Mostrando postagens com marcador SQLServer. Mostrar todas as postagens
Mostrando postagens com marcador SQLServer. Mostrar todas as postagens

sábado, 2 de abril de 2011

Acessar SQL Express Remotamente

Ao tentar conectar em uma instancia do SQL Server Express remotamente, eu estava recebendo a seguinte mensagem de erro: "error: 28 - O servidor não dá suporte ao protocolo solicitado".


Pesquisando na internet, encontrei a solução:



Enabling TCP/IP
First we must tell SQL Server Express to listen on TCP/IP, to do this
perform the following steps:

1. Launch the SQL Server Configuration Manager from the "Microsoft SQL
Server 2005 CTP" Program menu
2. Click on the "Protocols for SQLEXPRESS" node,
3. Right click on "TCP/IP" in the list of Protocols and choose, "Enable"

fonte: http://blogs.msdn.com/b/sqlexpress/archive/2005/05/05/415084.aspx


segunda-feira, 31 de março de 2008

Linked Server no SQL Server

Existe uma procedure no SQL Server chamada sp_addlinkedserver, que adiciona um link para uma base de dados externa, desde outros servidores do SQL Server, como Oracle e até mesmo Access, com OleDb.
Usei hoje, linkando com um outro servidor do SQL server. Executei o seguinte código.
SP_ADDLINKEDSERVER '192.168.1.2', 'SQL Server'

Depois disso, pude executar a seguinte query:

INSERT INTO
[192.168.1.2].VIRTO.DBO.CONFIG_ORIGENS
(EMPRESA, NOME, DESCRICAO)
SELECT EMPRESA
, NOME
, DESCRICAO
FROM CONFIG_ORIGENS

Para ver uma listagem dos servidores já linkados...
SELECT * FROM MASTER..SYSSERVERS

quarta-feira, 3 de outubro de 2007

Perfis de Horários

Há umas duas semanas eu me deparei com um problema interessante, no Virto (sistema que colaboro atualmente). Neste sistema há uma cadastro de horários de expediente do usuário. Há uma configuração de horário para cada usuário, e as tabelas no banco de dados segue a seguinte estrutura:



Os registros da tabela acima informam que o usuario '1' trabalha das 06:00h às 07:00, das 08:00h ás 09:00h e das 09:00h às 10:00h. Observe que neste caso o usuário não trabalha de 07:00h às 09:00h, mas trabalha de 08:00h às 10:00h de acordo com os registros 2 e 3. Isso é o que o sistema permite fazer.

Isso é horrível a efeito de normalização da base de dados, uma vez que uma empresa pode ter 200 funcionários que trabalhem nas mesmas 8 horas diárias, por exemplo, gerando portanto 1600 registros na base de dados. Foi aí que tiveram a brilhante idéia de criar perfis de horários, e atribuir o perfil de horário ao usuário.

Até aí nada de difícil. O desafio se apresentou quando foi necessário identificar quais eram os usuários que tinham os horarios iguais, para que pudesse ser criado apenas um perfil. Se assim não fosse, seria necessário criar um perfil para cada usuário

Existe algumas maneiras práticas pra realizar esta proeza:
1ª maneira: chamar o estagiário pra comparar um a um, sendo esta a maneira mais econômica.
2ª maneira: procurar no google pela ferramenta 'Super Ultra Plus Perfis Agrupator Utility', e torcer para que ele tenha a versão trial 30 dias se você pensa em economizar din-din.

Bem, segue minha solução:
1) Para cada registro de horário, elevar 2 à hora do dia. Assim, o registro referente ao período de 06:00h às 07:00h traria um registro 2 ^ 6 = 64.



2) Soma-se os valores do hora_id, agrupado por usuário.



Perceba que na imagem acima os usuários 901 e 244 têm as somas iguais. Isso significa que eles têm o mesmo perfil de horário. Se você for verificar com calma…


q

quinta-feira, 23 de agosto de 2007

Arredondamento de Datas

Essa semana eu peguei um probleminha interessante: a partir de uma tabela que tinha um campo [HoraInicial] e outro [HoraFinal], eu precisava exportar para uma segunda tabela, porém arredondada a cada 30 minutos, ou seja, em [HoraInicial], caso a hora seja 08:15h, arredondar para 08:00h; Caso seja 08:45, arredondar para 08:30h. Já em [HoraFinal], caso a hora seja 18:15h, arredondar para 18:30h; Caso seja 18:45, arredondar para 19:00h. Outra observação importante é que o campo no banco é do tipo Varchar, com os valores no formato '00:00'.

Considerando somente a [HoraFinal] eu poderia ter feito o seguinte usando a maneira tradicional:
- Pego os dois últimos caracteres e os dois primeiros e assumo como Minutos e Horas respectivamente;
- Se Minutos < 30 Então eu zero os minutos e +1 à hora; Senão eu assumo minutos = 30.
- Converto para SMALLDATETIME

O script somente para este campo seria semelhante ao SELECT abaixo:
DECLARE @HORA AS VARCHAR(5)
BEGIN
SET @HORA = '08:17'
SELECT CAST(
CASE WHEN CAST(RIGHT(@HORA, 2) AS INT) < 30 THEN
'1900-01-01 ' + LEFT(@HORA, 2) + ':30'
ELSE
'1900-01-01 ' + CAST(
CAST(LEFT(@HORA, 2) AS INT) + 1
AS VARCHAR(5)) + ':00'
END
AS SMALLDATETIME)
END

Conclusão: Funciona!!! O Problema seria se ao invés de 30 minutos nós tivessemos que fazer a cada 10 minutos, por exemplo. A quantidade de CASE WHEN cresceria absurdamente, poluindo meu código, pois eu precisaria verificar quando a Hora fosse < 10, 20, 30... Preferi fazer algo um pouquinho mais inteligente.

Os tipos de dados SMALLDATETIME e DATETIME representam valores númericos (FLOAT) onde a parte inteira representa os dias (partindo de '1900-01-01 00:00:00') e a parte fracionária as horas. Assim, '1900-01-02' representa o inteiro 1, e '12:00:00' representa a metade de um dia, ou seja, '.5'. Ao multiplicar uma fração por 24 é possível recuperar um float representando a qtde de horas ( '08:30' = 8,5 ). Ao multiplicar por 2 é possível fazer com que a parte inteira represente um período de 30 minutos (1/2 hora) ao invés de 60. Se ao invés de 2 fosse por 4, isso faria o inteiro representar um perído de 15 minutos (1/4 hora). O script ficaria semelhante à :
DECLARE @HORA AS VARCHAR(5)
BEGIN
SET @HORA = '08:17'
SELECT CAST( CEILING( CAST(
CAST('1900-01-01 ' + @HORA AS SMALLDATETIME)
AS FLOAT) * 24 * 2 ) / 2 / 24 AS SMALLDATETIME) HORA_FINAL
END

CEILING() é uma função que retorna o inteiro mais próximo acima de um determinado número. Por exemplo, CEILING(15.3) retorna 16. Para a [HoraIncial], é possível usar a função FLOOR(). FLOOR(15.7) retorna 15.

quarta-feira, 22 de agosto de 2007

Dependência de Objetos no SQL Server

Utilize a seguinte query para poder verificar quais objetos referenciam à um determinado objeto no SQL Server:
DECLARE @TABLE_NAME VARCHAR(255)
BEGIN
SET @TABLE_NAME = 'TBL_XPTO'

SELECT FOBJ.NAME OBJETO, FK.*
FROM SYSFOREIGNKEYS FK,
SYSOBJECTS FOBJ, -- OBJS QUE CONTÉM O CAMPO FK
SYSOBJECTS ROBJ -- OBJ QUE CONTÉM O CAMPO PK
WHERE FK.RKEYID = ROBJ.ID
AND FK.FKEYID = FOBJ.ID
AND ROBJ.NAME = @TABLE_NAME
END

Altere o valor da variável @TABLE_NAME.