Posts Tagged ‘Sql Server’

Convertendo dados

Posted in Vida Real on August 27th, 2008 by Silas Mendes – Be the first to comment

Já ouvi diversas pessoas perguntarem a diferença entre o CAST e CONVERT e as vezes coisas comuns passam despercebidas. A idéia é a mesma: as duas funções permitem converter um tipo de dado em outro, no entanto a função CAST é padrão ANSI, então teoricamente ela pode ser usada em qualquer SGBD. Já a função CONVERT é uma função T-SQL, ou seja, específica do Microsoft SQL Server. Além desta diferença, a função CONVERT tem um opcional que permite a conversão do dado e a possibilidade de formatar o resultado, é o que chamamos de estilo, e isso pode ser bem útil, principalmente quando você está trabalhando com datatypes datetime e money/float.

Então, por exemplo,  se você quiser converter uma data e deixá-la no formato dd/mm/aaaa, deve usar o CONVERT:

select CONVERT(varchar(60), current_timestamp, 103)

No exemplo acima estamos convertendo a data atual para VARCHAR e formatando a data como dd/mm/aaaa. A formatação neste caso está utilizando o estilo 103.

Uma tabela completa com os estilos disponíves pode ser acessada neste link: http://msdn.microsoft.com/en-us/library/ms187928.aspx

Bom trabalho :)

Pequenos detalhes: SET NOCOUNT ON

Posted in Vida Real on August 14th, 2008 by Silas Mendes – 1 Comment

Uma dica:

Ao executar uma procedure o SQL Server retorna para a aplicação o total de linhas afetadas.

Ex: (1 row(s) affected)

Para evitar esse tráfego (que custa no seu tempo de resposta) coloque no início de suas procedures a cláusula SET NOCOUNT ON.

Na maioria das vezes esse número é irrelevante,  mas imagine sua aplicação executando dezenas de procedures, que realizam centenas ou milhares de operações (INSERT, UPDATE, etc)  num dia.

Como dizem os mais velhos, de grão em grão a galinha enche o papo, na nossa realidade, de mili em milisegundos o seu banco também :)

Bom trabalho!

Inserindo registros via Bulk Insert

Posted in Erros $#$%!, Vida Real on July 25th, 2008 by Silas Mendes – 1 Comment

Realizar tarefas utilizando interfaces e nosso amigo (mickey) mouse pode ser muito confortável, no entanto, nem sempre elas estão disponíveis, ou em alguns cenários podem não ser a solução mais adequada.

Hoje pela manhã precisava importar dados para uma de nossas bases, a tarefa era urgentíssima, mas como sabemos, é justamente nessas horas que dá tudo errado! Meu Management Studio acordou mal humorado e quando cliquei na opção importar, ele disse sem pestanejar:

Unable to cast COM object of type ‘Microsoft.SqlServer.Dts.Runtime.Wrapper.PackageNeutralClass’ to interface type ‘Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSContainer90′ (…)

“Putz. Ok, hoje é sexta-feira, posso ir no Google e pesquisar sobre esse erro”. Enquanto pensava nisso meu gerente liga perguntando: “Já importou os dados?”…

Ok, vamos deixar o Google pra lá (por enquanto).

Existe uma forma muito prática de importar dados no SQL Server e foi a ela que recorri, o comando T-SQL é o BULK INSERT e é bem simples, veja o exemplo:

BULK INSERT tbTesteImport FROM ‘C:\arquivos_temp\tx_unid.txt’

WITH

(

FIRSTROW = 2,

FIELDTERMINATOR =‘;’

);

Neste caso o arquivo que eu precisava importar era o tx_unid.txt e ele foi gravado em C:\arquivos_temp do meu servidor SQL. Os dados desse arquivo foram importados para a tabela [tbTesteImport] e como ele tinha algumas particularidades tive que informar no BULK INSERT que ele deveria ignorar a primeira linha (era a linha de cabeçalho) e o caractere que separava um campo do outro era o ponto-e-vírgula (FIELDTERMINATOR =’;').

Pronto! Arquivo importado.

O BULK INSERT tem diversos parâmetros que você pode conferir aqui.

Em outra oportunidade irei comentar outras vantagens da utilização do BULK INSERT e também pretendo comentar sobre o BCP, mas agora vou ao Google ver se encontro o remédio pro mau humor do meu Management Studio :)

Até +

Novas certificações SQL Server

Posted in Bla bla bla on July 18th, 2008 by Silas Mendes – 1 Comment

Essa semana tá uma correria aqui mas pra não passar em branco posto abaixo um link com novidades sobre certificações Microsoft, em especial, para o SQL Server.

O post é do meu amigo Salvador Scardua e você pode conferir clicando aqui.

Um bom fim de semana a todos :)

MSDE – Restaurar backup > que 2 GB

Posted in Erros $#$%!, Vida Real on July 4th, 2008 by Silas Mendes – Be the first to comment

(Essa é para os workaholics)

 

Chega sexta feira, você pega o backup da base de dados do serviço e leva pra casa pra adiantar o trabalho (ou correr atrás do prejuízo). Aí no sabadão, ao tentar restaurar o backup: ERRO.

Tenta o restore de novo e o mesmo erro. Sacanagem…

Então liga pra um amigo, pesquisa no Google e descobre: o MSDE tem uma limitação, não aceita bases de dados maiores que 2 GB!!

 

Ok, como (quase) tudo na vida, existe um “jeitinho” pra resolver isso, mas sinceramente não sugiro esse procedimento em nenhum ambiente de produção/homologação e etc. Repito: não sugiro esse procedimento em nenhum ambiente de produção/homologação e etc.

 

Para utilizar uma base > 2GB no MSDE você vai precisar dos arquivos MDF e LDF da sua base de dados original (a do seu trabalho). O procedimento é simples, mas tem contratempos, porque para copiar esses arquivos a base deve estar “desatachada” (ficou estranho mas não encontrei um termo mais apropriado) ou o serviço do SQL deve estar parado. Escolha uma das duas opções e copie os arquivos.

 

Na sua casa o procedimento vai ser o seguinte.

 

1 – No MSDE crie uma base de dados com o mesmo nome que ela tem em seu trabalho;

2 – Verifique onde os arquivos físicos da base foram criados;

3 – Pare o serviço do SQL Server;

4 – Pegue os arquivos MDF e LDF de seu serviço e cole (substitua!) os arquivos que o SQL acabou de criar para a sua nova base (é muito importante que os arquivos tenham o mesmo nome!);

5 – Inicie o serviço do SQL Server e …

 

Bom trabalho!

Executar DTS via código

Posted in Erros $#$%!, Vida Real on July 3rd, 2008 by Silas Mendes – 1 Comment

Uma dúvida muito comum:

Como executar um pacote DTS via código?

Muito simples… podemos a partir do DOS digitar o seguinte comando:

dtsrun /S nome_servidor /E /N nome_do_pacote

 

O pacote será executado.

Aí me perguntam: Ah, mas eu quero executar a partir do SQL Server!

Ok, existe a opção de utilizar a procedure xp_cmdshell para executar o mesmo comando. Ficaria mais ou menos assim:

EXEC master..xp_cmdshell ‘dtsrun /S nome_servidor /E /N nome_do_pacote’

Porém é bom deixar um alerta: Essa procedure só pode ser executada por sysadmins, e no SQL Server 2005 ela vem desabilitada, (se você quiser utilizá-la deverá realizar isso na SQL Server Surface Area). Isso tudo por razões de segurança, afinal ela tem o poder de executar comandos no sistema operacional… tire suas próprias conclusões sobre isso e pense se é viável habilitá-la em seu ambiente.

Pra finalizar, segue abaixo alguns parâmetros que podem ser interessantes na utilização do comando dtsrun:

  • Executar comando utilizando login do Windows:
    /E  (Conexão confiável)
  • Executar comando utilizando login do SQL:
    /U login /P senha
  • Se o pacote tiver uma senha:
    /M senha

Para ter acesso a uma relação completa digite apenas dtsrun no prompt do DOS e Enter ou acesse este link: http://msdn.microsoft.com/en-us/library/aa224467(SQL.80).aspx.

Até +

Macro no Excel, coisas da rotina

Posted in Vida Real on July 2nd, 2008 by Silas Mendes – 5 Comments

 

É inevitável na rotina de um DBA ter que utilizar-se de ferramentas que auxiliem seu trabalho.

Ontem recebi uma planilha no seguinte formato:

SETOR SubSetor Regra Subregra Código Descrição
1 01.1       Bla bla bla
    01.11     Bla bla la
      01.11-3   Bla bla bla
        0111-3/01 Bla bla bla
        0111-3/02 Bla bla bla
        0111-3/03 Bla bla bla
        0111-3/99 Bla bla bla

Eu deveria importar esta planilha numa tabela de nosso banco. Dentro da tabela ela ficaria mais ou menos assim:

SETOR SubSetor Regra Subregra Código Descrição
1 01.1 NULL NULL NULL Bla bla bla
1 01.1 01.11 NULL NULL Bla bla bla
1 01.1 01.11 01.11-3 NULL Bla bla bla
1 01.1 01.11 01.11-3 0111-3/01 Bla bla bla
1 01.1 01.11 01.11-3 0111-3/02 Bla bla bla
1 01.1 01.11 01.11-3 0111-3/03 Bla bla bla
1 01.1 01.11 01.11-3 0111-3/99 Bla bla bla

Ok… existe uma hierarquia que visualmente fica melhor representada na primeira tabela, no entanto, dentro do banco os dados deveriam estar como exposto na segunda tabela, isso iria influenciar na chave primária e etc.

Enfim, vamos lá!

Mas faltou um detalhe… a tabela tinha algumas milhares de linhas. Como eu faria isso? CTRL C, CTRL V?? Quantas horas de um trabalho monótono copiando e colando, copiando e colando…

Bha!

Nessas horas eu adoro o Excel e suas macros. Para muitos pode parecer ridiculo mas me ajuda e talvez possa ajudar outras pessoas em situação parecida.

Ok… fiz um pequeno script que varria todas as linhas de uma determinada coluna da planilha, verificando se existiam células vazias. Se a célula está vazia, esta deve receber o conteúdo da célula anterior e assim por diante até o fim.

Muito simples e o trabalho todo, incluindo a importação no banco, não durou 1 hora. Então segue aí o script em VB, escrito dentro do próprio Excel:

Sub Copia_Celula_Anterior()

‘ Copia_Celula_Anterior() Macro
‘ Macro gravada em 1/7/2008 por silas.mendes

‘Declara váriavel de apoio do contador
Dim i As Integer

‘Inicializa váriavel com a primeira linha preenchida da planilha
‘ATENÇÃO: Esta informação sera copiada para outra(s) célula(s), caso
‘esteja(m) vazia(s).

i = 8

‘Varre todas a linhas da coluna até a linha 2371
Do While i < 2371
‘Verifica se a célula atual está vazia
If Range(“E” & i).Value = “” Then
‘Se a célula está vazia, seleciona a última célula
Range(“E” & i – 1).Select
‘Copia os dados da célula selecionada
Selection.Copy
‘Volta a selecionar a célula vazia (atual no loop)
Range(“E” & i).Select
‘Cola o conteúdo na célula vazia
ActiveSheet.Paste
End If
‘Incrementa contador do Loop
i = i + 1

Loop

End Sub

 

É, isso também faz parte da rotina de um DBA :))

Calculando a idade usando T-SQL

Posted in Traduzidos, Vida Real on July 1st, 2008 by Silas Mendes – Be the first to comment

O artigo abaixo foi escrito por Lynn Pettis para o site www.sqlservercentral.com. O texto original pode ser lido aqui.


Como calcular a idade de uma pessoa? Isto pode tornar-se um tema polêmico e com inúmeras soluções. Mas antes de criticar este tópico considere que ele pode ajudar a definir algumas regras a serem utilizadas na criação de um algoritmo que calcule a idade.

A parte mais difícil é saber o que fazer com os anos bissextos. Quando é que uma pessoa (objeto/documento) torna-se um ano mais velha? Neste pequeno artigo iremos definir que isto ocorre em 28 de fevereiro de anos não-bissextos.

Antes de mergulhar nos cálculos, vamos fazer alguns cálculos simples usando o SQL Server 2005.

Primeiro, vamos ver o que acontece quando adicionamos um ano às datas: 28/02/2008 e 29/02/2008:

declare @data1 datetime@data2 datetime

set @data1 = ’20080228′

set @data2 = ’20080229′

select dateadd(yy, 1, @data1), dateadd(yy, 1, @data2)

Resultado:

2009-02-28 00:00:00.000  2009-02-28 00:00:00.000

Observem que adicionar um ano para ambas as datas, resultam na mesma data. Vamos ver então o que acontece quando adicionamos 4 anos:

declare @data1 datetime,@data2 datetime

set @data1 = ’20080228′

set @data2 = ’20080229′

select dateadd(yy, 4, @data1), dateadd(yy, 4, @data2)

Resultado:

2012-02-28 00:00:00.000  2012-02-29 00:00:00.000

Veja que agora as datas são diferentes. Isto é o que esperávamos.

Agora vamos ver a função DATEDIFF e ver um pouco como ela trabalha:

declare @data datetime,@date2 datetime

set @data = ’20080229′

set @date2 = ’20090228′

select datediff(yy, @data, @date2)

Resultado:

1

Ok, mas qual o resultado da próxima consulta?

declare @data1 datetime,@data2 datetime

set @data1 = ’20081231′

set @data2 = ’20090101′

select datediff(yy, @data1, @data2)

Resultado:

1

Espere…Isso não está certo, não existe um ano de diferença entre essas datas, alguma coisa deve estar errada.

Como você pode ver a função DATEDIFF retornou o numero da diferença entre os anos e não o número real de anos entre as duas datas.

Nós podemos usar esta informação para criar um T-SQL simples:

declare @data_nascimento datetime@idade int@data_atual datetime

set @data_atual = ’2008-02-28′

set @data_nascimento = ’2007-03-01′

set @idade = datediff(yy,@data_nascimento,@data_atual) - case when @data_atual < dateadd(yy,datediff(yy,@data_nascimento,@data_atual), @data_nascimento) then 1 else 0 end

select @idade

Conclusão

Este é apenas um método para calcular a idade de uma pessoa. Existem outras inúmeras formas que podem ser usadas. Tudo o que posso sugerir é que você use o método que melhor lhe atenda em cada situação.