Olá pessoal,
Boa tarde!
Neste post vou demonstrar um novo recurso do Transact-SQL disponÃvel a partir do SQL Server 2016 SP1, que é o comando CREATE OR ALTER, que pode ser aplicado em procedures, functions, triggers e views.
Para quem trabalha ou já trabalhou com Oracle, sabe que isso é uma cópia do CREATE OR REPLACE, existente nesse SGBD há muitos e muitos anos e que desde o meu primeiro contato com o SQL Server (SQL 2005) eu sempre me perguntei porque a Microsoft não implementava isso, pois facilitava e muito o dia a dia dos DBA’s e desenvolvedores.
Até a criação desse recurso, para procedures, functions, triggers e views era possÃvel utilizar 3 comandos:
– CREATE
– ALTER
– DROP
Se o objeto em questão não existisse na base e você executasse o comando de ALTER, o SQL retornava uma mensagem de erro:
Se o objeto em questão existisse na base e você executasse o comando CREATE, o SQL também retornava uma mensagem de erro:
Então como que o DBA/Desenvolvedor fazia para evitar que essas mensagens de erro ocorressem durante a atualização de objetos ?
Se existe, apaga e depois cria
Uma forma de se garantir que a execução não retorne erro é verificando se o objeto existe na base e caso exista, faz a exclusão da view/procedure/function/trigger. Nesta solução, eu vejo dois grandes problemas:
- O código do DROP precisa ser explicitamente declarado com o tipo do objeto (DROP VIEW, DROP FUNCTION, DROP PROCEDURE ou DROP TRIGGER), fazendo com que o nosso código não seja tão genérico
- Ao apagar o objeto e recriá-lo logo em seguida, as permissões desse objeto são perdidas e os usuários que tinham acesso a esse objeto não terão mais. Para que isso não aconteça, você terá que salvar as permissões de cada objeto antes de apagá-lo e criá-lo novamente, o que pode gerar um trabalho muito grande dependendo da quantidade de objetos a serem alterados na base, além do risco e da responsabilidade de voltar todas as permissões, de todos os objetos. Para salvar as permissões, você pode utilizar o script que disponibilizei no post Verificando as permissões de um usuário no SQL Server.
Exemplo de uso:
1 2 3 4 5 |
IF (OBJECT_ID('dbo.vwDatabases') IS NOT NULL) DROP VIEW dbo.vwDatabases GO CREATE VIEW dbo.vwDatabases AS SELECT * FROM sys.databases |
Se não existe, cria e depois altera
Uma outra forma de garantir a criação/alteração de objetos sem erro, é com a solução que vou apresentar abaixo, onde eu verifico se o objeto existe e caso não exista, cria um objeto “vazio” e após isso, executa o comando ALTER com o código-fonte correto.
Essa solução é melhor que a anterior, pois ela não tem o problema da perda de permissão dos objetos, mas tem o mesmo problema do código não ser generalista, pois você precisará definir o tipo do objeto na instrução de criação do objeto “vazio” (CREATE VIEW, CREATE PROCEDURE, etc..)
Exemplo de uso:
1 2 3 4 5 6 7 8 9 10 11 12 |
IF (OBJECT_ID('dbo.stpTeste') IS NULL) EXEC('CREATE PROCEDURE dbo.stpTeste AS SELECT 1') GO ALTER PROCEDURE dbo.stpTeste AS BEGIN PRINT 'Código da SP alterado' SELECT 1 END |
CREATE OR ALTER
Recurso disponibilizado a partir do SQL Server 2016 SP1, agora é possÃvel utilizar a instrução CREATE OR ALTER ao criar Stored Procedures, Functions, Views e Triggers. Ao fazer isso, o próprio SQL Server irá verificar se o objeto existe e irá criá-lo, caso não exista com o código-fonte informado ou realizar uma alteração no código, caso o objeto já exista.
Exemplo de uso:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-- Garantindo que o objeto não existe IF (OBJECT_ID('dbo.stpTeste') IS NOT NULL) DROP PROCEDURE dbo.stpTeste GO -- Fazendo a criação/alteração da Stored Procedure CREATE OR ALTER PROCEDURE dbo.stpTeste AS BEGIN PRINT 'Código da SP alterado' SELECT 1 END |
Result:
Command(s) completed successfully.
É isso aÃ, pessoal.
Espero que tenham gostado desse post e até a próxima.
Show Dirceu como sempre, acompanho de perto o blog parabéns, me fez lembrar que eu usava tal recurso quando usava o Oracle em um certo projeto, fora que concordo plenamente como a Microsoft só foi implementar o recurso agora hahaha, mas são coisas da vida, valeu!
Obrigado pelo feedback, Ronaldo! Isso é que me motiva a continuar escrevendo.