Category Archives: Desenvolvimento

SQL201-On Handling Errors

Let’s get back into SQL 200 by learning to deal with errors. Churchill had a great quote that applies to development (database or not) “He who fails to plan is planning to fail.” No matter how well you think you’ve planned your code, it’s going tofail.

The question is, will it fail gracefully, or will it EPIC FAIL?

What information can you get on errors?

Whenever you run encounter an error within your T-SQL, you’ll be able to access the
following pieces of information

  • Error Number — every error message in SQL server has to have a unique number to
    idenitify it. Out of the box, they’re all defined. If you want to define custom
    errors, you’ll have to pick a number that’s not in use (a number greater than 50,000).
  • Error Message — The message should be something more meaningful than “An error has
    occurred.” But sometimes they are just that. Google will be your best friend until you
    get a good idea of what the error messages actually mean. Keep in mind how useless some
    error messages can be when you start defining your own errors. Give the user some
    useful information, that way you can solve the problem more quickly in the future.
  • Severity — how bad is it? These severities tell how bad the problem is, You’ll see
    values from 0 – 24. The higher the number, the more severe the error. Severities below
    10 are informational. Errors between 11 and 16 are errors I see most often. Mostly
    because these are the ones I use when raising errors within stored procedures and jobs.
    Severities over 16 require your adminstrator to correct them.
  • Procedure Name — If your error occurs within a stored procedure, function, or
    trigger, the error will tell you which parent object the error occured in. So if you
    have a stored procedure that calls a function, which in turn is called from an ad-hoc
    query, the error raised will tell you if the error was in the function, the stored
    procedure, or the ad-hoc query. Very useful when you’re trying to track down the
    problem!
  • Line Number — Once you know where the error is, for example let’s say the error
    raised says the error is in a stored procedure, the line number will tell you what line
    within that stored procedure errored. I’d like to give you a warning, the line number
    it gives isn’t always the exact line the error occured on, but it will help you figure
    out where to begin your search. I’ve found white space can throw off the line number,
    as well as IF..THEN statements can affect what line number is returned.
  • State — The state is where in the SQL code the error is generated. This points
    more to where SQL errored, and less where your T-SQL code errored. Unless you’re doing
    some pretty deep error handling, I doubt you’ll need this piece of information on your
    errors.

How do you get information on your errors programatically?

Now that you know what all information you can get on your errors, you need to know how
to get at that information. Well, you can use the following stored procedures to get at
the information:

  • ERROR_NUMBER() or @@ERROR
  • ERROR_MESSAGE()
  • ERROR_SEVERITY()
  • ERROR_PROCEDURE()
  • ERROR_LINE()
  • ERROR_STATE()

Whenever you want to grab the different pieces of information on the error that just
occured, use one of these stored procedures (or grab the value of @@ERROR). But there’s
a trick: you have in order to get data out of these stored procedures, you have to be
inside a TRY..CATCH
block. Check out my previous article, for more info on how to set up and use a
TRY..CATCH block.

…and finally


The last topic you’ll need to learn in order to deal with errors is how to raise your
own errors. I’ve covered this in a two articles, and I’m
going to do one more article on RAISERROR to share a larger picture of what all you can
do with your own errors.
But the moral of the story is you can define what an error is. That’s helpful when you
want to build in business logic into your stored procedures. Maybe you want to define a
positive integers only error message. Maybe you need to define what a valid account
number is. With RAISERROR you can build and handle those errors.

If you have any questions on errors, or SQL in general…let me know. I’m here to help!

Dettach and Attach Databases Script

Hello Guys,

I was looking for some simple and fast way to generate a list for dettach and attach databases, but the most of scripts on the internet uses cursor and as i really hate cursors, i decided to write my own scripts, because it is a good way to learn and improve your T-SQL Skills.

So, i will put the code for two scripts below and you could download these scripts here

Dettach Databases

— If you put 1 the databases will be dettached
SET nocount ON
DECLARE @SQL NVARCHAR(MAX)
DECLARE @DatabaseName NVARCHAR(512)
DECLARE @ExecuteNow BIT
SET @ExecuteNow = 0
DECLARE @table TABLE
(
id INT ,
dbName NVARCHAR(512) ,
isVerified BIT
)
INSERT  INTO @table
SELECT  database_id ,
name ,
0 AS isVerified
FROM    sys.databases
WHERE   name NOT IN ( ‘master’, ‘tempdb’, ‘model’, ‘msdb’,
‘ReportServerTempDB’,
‘ReportServer’, ‘distribution’ )
ORDER BY database_id

WHILE ( SELECT  COUNT(*)
FROM    @table
WHERE   isVerified = 0
) > 0
BEGIN
SELECT TOP ( 1 )
@DatabaseName = dbName
FROM    @table
WHERE   isVerified = 0

IF @ExecuteNow = 1
BEGIN
SET @SQL = ‘exec sp_detach_db ”’ + @databaseName + ””
EXEC sp_executesql @sql
END

PRINT ‘exec sp_detach_db ”[‘ + @databaseName + ‘]”’

UPDATE  @table
SET     isVerified = 1
WHERE   @DatabaseName = dbName
END
SET nocount OFF

And now how to attach databases

SET nocount ON
DECLARE @SQL NVARCHAR(MAX)
DECLARE @DatabaseName NVARCHAR(512)

DECLARE @table TABLE
(
id INT ,
dbName NVARCHAR(512) ,
isVerified BIT
)
INSERT  INTO @table
SELECT  database_id ,
name ,
0 AS isVerified
FROM    sys.databases
WHERE   name NOT IN ( ‘master’, ‘tempdb’, ‘model’, ‘msdb’,
‘ReportServerTempDB’,
‘ReportServer’, ‘distribution’ )
ORDER BY database_id

WHILE ( SELECT  COUNT(*)
FROM    @table
WHERE   isVerified = 0
) > 0
BEGIN
SELECT TOP ( 1 )
@DatabaseName = dbName
FROM    @table
WHERE   isVerified = 0

SET @SQL = ( SELECT TOP ( 1 )
‘exec sp_attach_db ”’ + @DatabaseName + ”’ , ‘
+ ( SELECT  ”” + physical_name + ””
FROM    sys.master_files
WHERE   database_id = DB_ID(@DatabaseName)
AND RIGHT(physical_name, 3) = ‘mdf’
) + ‘ , ‘
+ ( SELECT  ”” + physical_name + ””
FROM    sys.master_files
WHERE   database_id = DB_ID(@DatabaseName)
AND RIGHT(physical_name, 3) = ‘ldf’
)
FROM   @table
)

PRINT @sql

UPDATE  @table
SET     isVerified = 1
WHERE   @DatabaseName = dbName

END
SET nocount OF

So, that’s a simple and good way to generate attach and dettach, it isn’t the best, but can help you.

Regards,
Marcos Freccia

Segundo Evento MCITP SC

Ola Pessoal, ontem saiu o cronograma de mais um evento da comunidade MCITP SC esta realizando. Dessa vez o evento será aqui em Blumenau, contando sempre é claro com boas palestras. Como é normal da nossa comunidade sempre realizamos dois eventos por semestre, um focado mais em Administração e Infraestrutura e o outro com o foco mais em Desenvolvimento. Nesse segundo evento será mais voltado então para Desenvolvimento e claro vamos contar com uma palestra de Infra para alegrar todos os povos.. Alegre

Mas qual a novidade desse evento?
A novidade é que dessa vez eu também estarei palestrando, e claro sempre focado em melhores praticas para desenvolvedores, assim como tentei no webcast que fiz. Aprendi muito com aquele webcast realizado e agora vamos falar sobre mais 5 lições sobre SQL Server para desenvolvedores.

Sem mais delongas, para acessar a pagina do evento clique aqui. Nesse proprio link terá também o link para a inscrição no Technet.

Aqui está a bio da minha palestra.

5 lições sobre SQL Server para desenvolvedores

Essa seção irá mostrar 5 passos que levarão o desenvolvedor autilizar as melhores praticas do SQL Server no ambiente de desenvolvimento. Se você acha que seu codigo é bom, espere até assistir essa seção e você verá que os mínimos detalhes fazem a diferença e acabe com a famosa frase “Mas no meu ambiente é rapido”.
Palestrante: Marcos Freccia

Além dessa, teremos também outras otimas palestras que vocês podem conferir acessando o site da comunidade e claro nao deixem de participar.

A comunidade MCITP SC agradece a compreensão de todos.

Marcos Freccia
MCTS SQL Server 2008 Implementation and Maintenance
MCTS SQL Server 2008 Database Development
@SqlFreccia

Performance com Filestream

Ontem pela manhã o Edvaldo Castro (Blog|Twitter) precisava de uma solução para colocar no SQL Server pequenos arquivos como arquivos txt, doc, pdf, xls e assim por diante. Mas qual a melhor solução?

Depende !! Alegre

A Microsoft tem um whitepaper onde explica que arquivos até 1mb o melhor é guardar dentro do SQL Server, após isso a recomendação é filestream.

Pra quem não conhece filestream é uma funcionalidade de que veio no SQL Server 2008 para facilitar o armazenamento de arquivos binarios muitas vezes grandes, fora do SQL Server e por cima de tudo fornecendo o maximo de desempenho. Então vamos aprender como utilizar filestream e ver se ele realmente me traz beneficios?

O primeiro passo então é criamos nossa base de dados. Muita atenção aqui, pois é na criacão da base que você define qual filegroup será o responsavel por armazenar os dados do filestream.

Read the rest of this entry

Video – Parameter Sniffing

Pessoal,

Conforme prometido segue o video dando continuidade ao meu webcast. Hoje o video sera sobre Parameter Sniffing.

Detalhe pessoal que quando eu tentava mostrar as propriedades da consulta a mesma nao aparecia no video, então peguei os prints dos mesmos e estou colocando aqui para vocês. Colocarei na ordem que os mesmos forem demonstrados no video.

Read the rest of this entry

SQL 201-Ranking Functions

It’s been a while since I’ve covered a SQL 201 topic!  I want to jump back into it with ranking functions.  These are functions that let you represent orders in your data.  When you were in school I’m sure you had to take standardized tests.  When you did you were given a percentile score.  This score represented how you performed compared to all students in your sample.  This sample group was everyone in your grade level.  So if you were taking the end of course exams for 11th grade, you were compared with every other student in the 11th grade.

Percentile is just one of the four ranking functions you have available in SQL 2008 R2.  I’m going to go over how and when you would use these in the real world.  Let’s start with the easy stuff.

Read the rest of this entry

Dica do Dia: Lista de Servidores SQL Server

Pessoal,

Apenas uma dica do dia: Ontem precisava acessar uma instancia do SQL Server, porem eu nao tinha o management studio instalado, bom qual recurso a ser usado? Acertou quem disse sqlcmd. Como eu não sabia o nome da instancia um comando do sqlcmd me ajudou muito o sqlcmd /L ou -L. Esse comando te retorna  uma lista dos servidores de SQL Server que ele encontrar na rede, a partir dai é só correr pro abraço. Abaixo segue uma imagem de como é retornado a lista para o usuario

Obs: Com powershell também existe uma solução bem legal, porem como eu nao sou expert nao consegui fazer. 😦

Até mais,
Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia

Precedência de tipo de dados

Ola Pessoal,

No ultimo post eu falei sobre como Problemas com conversão implicita pode acabar com seu índice. Ainda no final do post falei que ainda temos mais problemas com a conversão implícita, então esse é o nosso assunto de hoje.

A grande questão aqui é a  precedência do tipo de dados, a precedência também é um serio fator na conversão implícita de dados, mas como?

A precedência de dados diz que certos tipos de dados tem uma certa “vantagem” sobre outros tipos de dados em comparações, conversões, etc.. até ai tudo bem, mas como a precedência pode também ser um empecilho na conversão implícita dos dados e assim acabar com seu índice. Vamos aos testes.

Utilizaremos aqui os mesmos scripts do post anterior.

create table #temp ( id int not null, cdVendedor varchar(100))

go

alter table #temp add constraint PK primary key (id)

go

insert into #temp (id,cdVendedor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

go

create nonclustered index ix_teste on #temp(cdVendedor)

go

select cdVendedor from #temp

where cdVendedor = 1

Analisando temos o seguinte plano de execução.

Como vimos nessa consulta estamos realizando uma conversão de um tipo de dado texto (varchar) para um tipo de dado inteiro (int), se analisar o tipo de dados varchar que foi declarado na criação da tabela, o mesmo não tem precedência sobre o tipo de dados int, logo o SQL Server não consegue realizar um índex seek na consulta.

Agora vamos mudar nosso tipo de dado do campo cdVendedor.

drop table #temp

go

create table #temp ( id int not null, cdVendedor int)

go

alter table #temp add constraint PK_2 primary key (id)

go

insert into #temp (id,cdVendedor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

create nonclustered index ix_teste on #temp(cdVendedor)

select * from #temp where cdVendedor = 3

Executando a consulta a seguir temos o seguinte plano de execução.

Agora execute a seguinte consulta.

select * from #temp2

where cdVendedor = ‘3’

Abaixo plano de execução.

Agora vimos que como o tipo de dados inteiro (int) tem precedência sobre o tipo de dados texto (varchar) não importa como realizamos nossa consulta, se for com aspas ‘’ ou sem aspas sempre teremos um índex seek.

Caso alguém se interessar em realizar esse mesmo teste com outros tipos de dados me avise depois, mas provável que esse comportamento só ocorra com esses dois tipos de dados no caso de inteiro para texto e vice-versa.

Então pessoal por hoje era isso, espero que seja de utilidade para alguém isso, pois é muito importante realizar uma boa modelagem de dados para não ter problemas mais tarde.

Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia

Problemas com Conversão Implicita

Pessoal,

A dica de hoje é bem simples: CUIDADO COM CONVERSAO IMPLICITA há algum tempo atrás precisei criar alguns índices e tudo ocorreu normalmente, porem ao realizar testes desses índices vi que eles não realizavam um índex seek na minha tabela, mas sim um índex scan L. Isso tudo ocorreu por conta de uma conversão implícita estar acontecendo na minha consulta. Então vamos a uma demonstração de como a conversão pode deixar seu índice ineficaz na consulta.

create table #temp ( id int not null, cdVendedor varchar(100))

go

alter table #temp add constraint PK primary key (id)

go

insert into #temp (id,cdVendedor)

values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6)

go

create nonclustered index ix_teste on #temp(cdVendedor)

go

select cdVendedor from #temp

where cdVendedor = 1

Executando a consulta acima temos o seguinte plano de execução.

Como viram nada adiantou eu criar meu índice, mas será que foi um erro do SQL Server ou meu? Bom eu diria que é um erro nosso ao realizar a declaração dos dados, pois como vocês podem ver o campo cdVendedor é do tipo varchar e antes de realizar a consulta o query optimizer teve que realizar a conversão desse campo para encontrar a melhor forma possível de realizar a consulta. Analisando as informações da consulta temos:

Viram o convert_implicit? Então ele foi o responsável por fazer o SQL Server percorrer toda a arvore do índice para procurar o valor que satisfizesse a consulta, porem foi erro nosso declarar o valor na clausula where de forma errada, o correto então seria declarar a consulta da seguinte maneira.

select cdVendedor from #temp

where cdVendedor = ‘1’

Assim temos o seguinte plano de execução.

E como podem ver não temos mais a conversão do tipo de dado antes da consulta ser executada.

Então pessoal por hoje era isso, espero que vocês tenham aprendido alguma coisa por aqui. Ainda temos mais um empecilho com a conversão implícita de dados, mas isso é assim para isso é um assunto que deixo para um próximo post.

Marcos Freccia
MCTS SQL Server 2008
@SQLFreccia

Diferença entre ISNULL x Coalesce

Bom Dia Pessoal,
Há algumas semanas atrás em um fórum que participo houve a duvida de uma pessoa que queria substituir valores nulos por qualquer outro valor, instrui ele a utilizar a função coalesce ou a isnull. Bom até ai tudo bem temos duas funções conhecidas: ISNULL (Implementação Microsoft) e Coalesce (Padrão ANSI).
Assim que respondi essa questão uma duvida me apareceu: Qual a diferença entre ISNULL e Coalesce? Primeiramente fui ao twitter e perguntei para o @sqlservian ele logo me respondeu e me mandou alguns links, vou compartilhar e espero que fique bem entendida a diferença.
Read the rest of this entry