Fabiano Neves's profileFabiano Neves Amorim - S...PhotosBlogListsMore ![]() | Help |
|
|
October 27 Table Variables e TransactionsHoje um amigo perguntou sobre o conceito de transações no SQL Server,
Ele queria fazer o seguinte, chamar um processo para fazer alguns cálculos, depois gravar o resultado disso em uma tabela, e depois efetuar um rollback, pois o processo seria de simulação.
A dúvida era que quando ele efetuava um rollback o SQL fazia um rollback de tudo, inclusive no insert que ele havia feito para pegar o resultado da simulação. Ou seja, ele queria guardar o valor da simulação em uma tabela para exibir na tela.
Mesmo não concordando muito com a lógica aplicada, sugeri para ele usar uma variável de tabela para guardar o resultado, já que ela não faz parte do escopo de uma transação portanto não afetada pelo rollback.
Por ex:
BEGIN TRAN
DECLARE @TMP TABLE (LETRA CHAR(2))
INSERT INTO @TMP(LETRA) VALUES('EU')
ROLLBACK TRAN
SELECT LETRA + ' ' + 'CONTINUO AQUI!' FROM @TMP
Uma outra solução seria usar SavePoints, mas também não acho que seria legal, maasss fica a dica sobre as variáveis do tipo table. October 21 Scalar Functions e Analysis Services - Named CalculationScalar functions são bastante utilizadas em banco de dados, mas elas são verdadeiras killers de CPU...
Estou trabalhando na manutenção de um projeto ETL para BI e me deparei com um desses casos onde vale a pena escrever...
Tenho uma consulta que retorna aproximadamente 800 mil linhas o que é bastante comum quando estamos falando de bases DW, mas o interessante aqui é que o select que retorna os dados para criação da minha dimensão usa uma function para gerar o Ano, Mês e Dia a partir de uma Data existente na tabela. Depois de converter a data para Ano usando a function YEAR do SQL eu pego o valor de Ano e jogo em uma outra tabela na coluna Ano, e depois uso ela na dimensão de tempo no meu cubo Analysis Services.
Bom vou resumir para ver se da pra ficar mais fácil de entender, eu tenho uma Data e preciso do Ano, Mês e Dia desta data em colunas separadas para poder efetuar os filtros por um determinado período no Cubo.
Ai é que ta, na verdade eu nem precisava fazer a conversão no SQL para jogar no AS, mas eu posso simplesmente criar uma Named Calculation na tabela do DataSource View no AS, antes de mostrar isso, vamos ver porque Scalar Functions são bad.
Vamos criar uma base para os testes,
use tempdb SET NOCOUNT ON IF OBJECT_ID('TabTeste') IS NOT NULL DROP TABLE TabTeste GO CREATE TABLE TabTeste (ID Int Identity(1,1), Nome VarChar(200) DEFAULT NEWID(), Data DateTime DEFAULT GETDATE()) GO -- Vamos inserir um registro para simular o problema INSERT INTO TabTeste(Nome, Data) VALUES('Teste', '20050101') GO -- Massa aleatoria de dados. INSERT INTO TabTeste DEFAULT VALUES GO 1000000
Agora vamos criar uma Scalar Function para usar nos testes.
IF OBJECT_ID('fn_PreencheComZeros') IS NOT NULL DROP FUNCTION dbo.fn_PreencheComZeros GO
CREATE FUNCTION dbo.fn_PreencheComZeros(@Coluna VarChar(250), @Qtde_Zeros Int) RETURNS Varchar(200) AS BEGIN DECLARE @Result VarChar(200) SET @Result = RIGHT(REPLICATE('0', @Qtde_Zeros) + @Coluna, @Qtde_Zeros)
RETURN @Result; END GO
Agora um exemplo simples de um select para retornar os dados que eu preciso.
-- Retorna os dados com da tabela criando 3 colunas, Ano, Mes e Dia. SELECT YEAR(Data) AS Ano, MONTH(Data) AS Mes, DAY(Data) AS Dia, * FROM TabTeste -- Rodou em 31 segundos e usou 1109 ms de CPU
/* Exemplo do resultado Ano Mes Dia ID Nome Data 2005 1 1 1 Teste 2005-01-01 00:00:00.000 2008 10 21 2 E09D7055-CC12-40FC-8D3E-F7A28521D601 2008-10-21 11:35:46.087*/
Repare que na data de 01/01/2005 o Mês veio como "1" e não "01" a mesma coisa acontece com o dia, eu sei que existem outras formas de fazer retornar o "01" mas vamos dizer que eu me depare com uma solução que usa a função para formatar os valores para retornar conforme o desejado. É bem comum usar funções deste tipo para fazer diversas formatações desde concatenações até cálculos super complexos.
-- Com a simples função de Preencher com Zero o SQL ficaria assim: SELECT dbo.fn_PreencheComZeros(YEAR(Data),4) AS Ano, dbo.fn_PreencheComZeros(MONTH(Data),2) AS Mes, dbo.fn_PreencheComZeros(DAY(Data),2) AS Dia, * FROM TabTeste -- Rodou em 35 segundos e usou 22438 ms de CPU
/* Exemplo do resultado Ano Mes Dia ID Nome Data 2005 01 01 1 Teste 2005-01-01 00:00:00.000 2008 10 21 2 E09D7055-CC12-40FC-8D3E-F7A28521D601 2008-10-21 11:35:46.087*/
Agora imagine que uma mente Brilhante resolva sofisticar a função e usa-lá para diversas formatações deixando o código dentro dela um pouco maior...
-- Conforme mais código na function pior fica a coisa... SELECT DBO.fn_PreencheComZerosSuper(YEAR(Data),4,0) AS Ano, DBO.fn_PreencheComZerosSuper(MONTH(Data),2,0) AS Mes, DBO.fn_PreencheComZerosSuper(DAY(Data),2,0) AS Dia, * FROM TabTeste -- Rodou em 1:15 e usou 73515 ms de CPU, ou seja o dobro do tempo inicial.
Mas o que fazer neste caso? Bom a resposta é, evite usar Functions de qualquer tipo que seja em colunas, caso enha que fazer alguma formatação tente formatar o código direto na coluna por ex:
-- Exemplo de uma solução SELECT RIGHT('0000' + Convert(VarChar(4),YEAR(Data)),4) AS Ano, RIGHT('00' + Convert(VarChar(2), MONTH(Data)),2) AS Mes, RIGHT('00' + Convert(VarChar(2), DAY(Data)),2) AS Dia, * FROM TabTeste -- Rodou em 33 segundos e usou 1984 ms de CPU
Named Calculation são colunas calculadas que você pode criar no seu DataSource View sem que você tenha que alterar a estrutura de suas tabelas, ou seja, não precisa gastar tempo para popular e espaço para armazenar os dados sendo que você pode criar uma Named Calculation que irá retornar o valor que você deseja.
No meu exemplo acima, optei por ao invés de ter que calcular e gravar os dados de Ano, Mês e Dia em uma tabela e depois ler estes valores, achei melhor criar 3 novas Named Calculation direto no AS, segue um print das telas para ficar mais claro.
Depois de clicar no OK a coluna ficará disponível como todas as outras mas com um ícone(
That’s all folks... October 20 Microsoft SQL Server 2008 Internals
A Amazon publicou um link para pré-venda do novo livro da Delaney(co-Autores Paul Randal, Kimberly Trip, Conor…) que está no forno e com previsão de entrega para Fevereiro de 2008. http://www.amazon.com/dp/0735626243/ Estou aguardando ansiosamente… October 16 Recomendação de SitePois é galera, estou afim de ganhar um CD do Rodrigo Faria que é professor de inglês e também é o mais novo colaborador do site English Experts.
Sou assinante dos feeds do site e recomendo para todos que desejam ter contato diário com a língua inglesa e que desejam aprender, o site conta com várias publicações e comentários de professores de inglês.
Diariamente eu passo pela minha pasta “English Experts” para ler os posts e tentar aprender cada vez mais sobre inglês afim de tentar não cometer mais gafes como a que publiquei estes dias :-) ...
Recomendo a assinatura do site, a assinatura pode ser feita pelo link, http://feeds.feedburner.com/EnglishExperts.
Fica ai a dica de um site com ótimo conteúdo e excelentes professores.
Abraço. October 13 Dissecting SQL Server Execution PlansFiz uma recomendação de um livro na thread abaixo no Forum do MSDN,
http://forums.microsoft.com/MSDN-BR/ShowPost.aspx?PostID=3983673&SiteID=21
Quero aproveitar para deixar o link aqui tbm para quem se interessar.
“Dissecting SQL Server Execution Plans” do Grant Fritchey. October 09 Da série mico do AnoEstava eu conversando com o Conor Cunningham quando escrevi a seguinte pérola,
I’m fine, and, in my testes I have one doubt about why QP …. e continua…
Só tem um detalhe galera… rs... como podem reparar acima, ao invés de escrever TESTS, eu escrevi TESTES, e testes nada mais é que, segundo palavras do próprio Conor, - Testes is a part of the male anatomy… ou melhor dizendo, testículo... hauhuauhahu
Puts... essa foi f... mas blz... agora já aprendi :-) |
|
|