Utilize as tabelas de sistema do SQL Server para turbinar seu trabalho
As tabelas de sistema contém informações sobre a estrutura do seu banco de dados. Estas estruturas permitem a criação de dinâmicas de código que facilitam o dia-a-dia do programador SQL. Todas estão disponíveis a partir do SQL 2000 (com excessão da tabela SYS.OBJECTS, disponível a partir da versão 2005). Vamos conhecer as tabelas.
SYSOBJECTS
Esta tabela armazena todos os objetos do banco de dados, tais como tables, procedures, triggers, views, functions, foreign keys, constraints, entre outros. Resumindo, todos os objetos de usuário estão nesta tabela. As principais colunas da tabela são:
- Name: nome do objeto no banco de dados
- crdate: data de criação do objeto
- type: tipo do objeto.
Alguns exemplos de aplicação:
- --
- select name, crdate, type
- from sysobjects
- where name like 'spcFAE%'
- order by crdate desc
- --
Retorna o nome, data de criação e tipo dos objetos que o nome comece com “spcFAE”, ordenando por data de criação descescente.
- --
- select name, crdate, type
- from sysobjects
- where crdate > '2010-05-01'
- order by crdate desc
- --
Retorna todos os objetos criados no banco de dados a partir de 01 de maio de 2010.
- --
- select name
- from sysobjects
- where type in ('P','TR','FN')
- order by crdate desc
- --
Estas pesquisas na tabela SYSOBJECTS são muito úteis, por exemplo, para buscar todos os procedimentos criados a partir de uma determinada data, ou relacionar rotinas por nome, etc. Existe ainda (somente a partir da versão 2005 do SQL), a tabela SYS.OBJECTS, que funciona como uma extensão da tabela SYSOBJECTS (relaciona pela coluna ID), porém possui uma coluna que é muito útil para desenvolvedores, a coluna MODIFY_DATE. Esta coluna armazena a data da última alteração de um objeto.
Os tipos conhecidos mais comuns de objetos na tabela (coluna type) são:
- U - TABLE (tabela)
- F - FOREIGN KEY (chaves estrangeiras)
- C - CHECK CONSTRAINT
- D - DEFAULT
- P - STORED PROCEDURE
- V - VIEW
- TR – TRIGGER
- TF - TABLE FUNCTION
- FN - USER DEFINED FUNCTION
- S - SYSTEM TABLE
- K - PRIMARY KEY (chave primária)
A tabela sysobjects também pode ser utilizada em conjunto com outras tabelas de sistema, para outros tipos de pesquisa no banco de dados. Vamos conhecer agora a tabela SYSCOLUMNS.
SYSCOLUMNS
Esta tabela armazena armazena as colunas de tabelas, parametros de entrada de procedimentos, e assim por diante. Toda vez que é criada uma nova tabela ou procedimento no sistema, o SQL grava nesta tabela informações preciosas, que podemos utilizar a qualquer momento. As colunas que mais vamos utilizar neste exemplo são:
ID | é a identificação do objeto a quem pertence estas colunas [ syscolumns.id = sysobjects.id ] |
xtype | determina o tipo de coluna (inteiro, decimal, char, varchar, bit, etc). O tipo é um código, encontrado em systypes [ syscolumns.xtype = systypes.xtype ] |
length | tamanho do campo (no caso char, varchar terá o tamanho específico). |
xprec & xscale | especifico para tipos decimais, informando a quantidade total de dígitos com decimais (xprec), e a quantidade de decimais (xscale) |
allownulls | valor bit (0/1) que informa se a coluna aceita valores nulos ou não. |
collation | Especifica o COLLATION da coluna (para tipos texto). Isto é necessário para solucionar problemas de conflitos de bancos de dados de diferentes idiomas. |
A partir desta tabela, é possível ler qualquer estrutura do banco de dados. Qual a utilidade disso? Como uma pequena demonstração do que podemos fazer com a tabela SYSCOLUMNS, vamos criar um procedimento de apoio (?). Bom, um procedimento de apoio é um código feito para gerar código. É isto mesmo!
Vamos exemplificar.
Temos uma tabela chamada NotaItemLote (tabela onde são gravados os números de lote dos itens de uma nota fiscal). Você está criando uma rotina que irá inserir dados nesta tabela (gerando uma nota fiscal). Conhecendo a dinâmica de bancos de dados, quando construo uma query de insert, eu sempre especifico o nome dos campos da tabela que estou inserindo dados:
- --
- insert into tabela (coluna1, coluna2, coluna3) select 1, 2, 3
- --
Isto garante que no caso de uma eventual atualização no sistema, se forem adicionadas colunas novas nesta tabela que aceitem nulo, minha rotina ficará estável e não dará erros. Se você não especifica o nome das colunas no insert, ao alterar a estrutura da tabela, todas as rotinas que geram insert sem especificar o nome darão erro. Isto é padronização básica da básica.
Pois bem, como vamos gerar um insert então? Muito simples! Altere o nome da tabela para uma que exista no seu banco de dados, e veja o resultado do select abaixo (utilizando syscolumns)
- --
- select syscolumns.name + ', '
- from syscolumns, sysobjects
- where syscolumns.id = sysobjects.id
- and sysobjects.name = 'NotaItemLote'
- order by syscolumns.colorder
- --
A query irá retornar o nome das colunas da tabela, em sequência, e ainda colocando uma virgula ao nome do lado, para facilitar. Aí basta copiar, colar e montar a sua query de insert
- --
- insert into NotaItemLote (cd_empresa, nr_serie, nr_nota, cd_item
- , nr_lote, dt_validade, qt_lote, sinal) ...
- --
Então vamos melhorar mais ainda, e facilitar a utilização deste procedimento, pois não teria sentido digitar uma query como essa toda vez que quisesse pegar as colunas de uma tabela. Então vamos criar um procedimento chamado sp_gerainsert. Segue o código dele abaixo:
- --
- create proc sp_gerainsert
- @objname as sysname
- as
- select name + ', '
- from syscolumns
- where id = object_id(@objname)
- order by colorder
- --
*A função object_id retorna o ID do objeto passado como parâmetro (o mesmo ID da tabela sysobjects).
Após compilar o procedimento, vá até o menu TOOLS (ferramentas), OPTIONS (opções). Selecione KEYBOARD, e insira a função que criamos no atalho CTRL+5 (pode vincular em qualquer atalho que desejar):
Agora, toda vez que for criar uma query de insert em uma tabela, basta selecionar o nome da tabela na janela de query, e pressionar CTRL+5 (ou o atalho que tenha especificado):
SYSCOMMENTS
A tabela syscomments é onde ficam armazenados todos os textos de procedimentos, triggers, funções, etc. Quando você executa um CREATE PROCEDURE, por exemplo, é nesta tabela que fica armazenado todo o código da procedure que compilou.
Vamos então para a parte prática. Digamos que você esteja fazendo uma atualização no seu banco de dados. Uma tabela de uso frequente recebeu uma nova coluna, e esta coluna não aceita valores nulos. Isto significa que você precisa revisar todos os procedimentos que inserem dados nesta tabela, correto? Para entender a forma como vamos procurar isso na tabela syscomments, vamos primeiro analisar uma query de insert:
- --
- insert into NotaItemLote (cd_empresa, nr_serie, nr_nota, nr_lote
- , dt_validade, qt_lote, sinal)
- select 1, 'NFF', 1525, 'A0001', '2010-12-31', 10.0 , 'E'
- --
- --
- select name
- from sysobjects
- where id in (select name
- from syscomments
- where text like '%into notaitemlote%')
- --
O resultado da query é o nome de todos os procedimentos que contenham este texto “into notaitemlote”. Quem está acostumado com atualizações em bancos de dados que contém procedimentos, conhece bem esta rotina.
Estas dicas, aplicadas no dia-a-dia, garantem muito mais produtividade ao programador, pois não precisa ficar digitando nome de colunas, localiza os objetos alterados no sistema, etc. É muito mais controle sobre os objetos para o programador. E pode ter certeza, utilizar estes indicadores (como data de criação, data de alteração da rotina, etc) garantem muito mais precisão do que documentação manual.
Ajudou e muito no meu aprendizado! Não sabia destas funcionalidades do SQL SERVER.
ResponderExcluir