Database
 sql >> Base de Dados >  >> RDS >> Database

Melhor ALTER do que DROP


Neste artigo, fornecerei uma construção para excluir um objeto antes de criá-lo.





Em nossa equipe, existem cerca de vinte desenvolvedores SQL Ninja. Todos eles descrevem essa construção de maneiras diferentes.

Nossa equipe é composta por cerca de vinte SQL Ninjas e todos eles usam a seguinte instrução de uma maneira diferente:
IF OBJECT_ID('dbo.Function', 'TF') NÃO É NULL DROP FUNCTION dbo.Function;GOCREATE FUNCTION dbo.Function ..

Ou:
IF EXISTS ( SELECT * FROM sys.objects WHERE name ='Procedure' AND type ='P') DROP PROCEDURE dbo.Procedure;GOCREATE PROCEDURE dbo.Procedure ..

Ou:
IF EXISTS ( SELECT 1 FROM sys.objects WHERE object_id =OBJECT_ID(N'dbo.Function') E digite IN (N'FN', N'IF', N'TF', N'FS', N' FT')) DROP FUNCTION dbo.Function;GOCREATE FUNCTION dbo.Function ..

No StackOverflow, os usuários gostaram desta versão:
IF EXISTS ( SELECT * FROM sysobjects WHERE id =object_id(N'function_name') AND xtype IN (N'FN', N'IF', N'TF')) DROP FUNCTION function_nameGO

As estrelas estão alinhadas e encontrei uma implementação apropriada em um dos sites SQL. No começo, fiquei chocado, mas depois as pessoas ajudaram a ver porque funciona bem.
IF OBJECT_ID('dbo.Function', 'TF') IS NULL EXEC('CREATE FUNCTION dbo.Function() RETURNS @t TABLE(i INT) BEGIN RETURN END');GOALTER FUNCTION dbo.Function .. 
O ponto é que, se você usar as instruções DROP e CREATE todas as vezes, excluirá as permissões do objeto. Além disso, o objeto pode estar na replicação e também será excluído assim que for recriado.

Então, eu gostei desta versão e decidi envolvê-la no dbo.antidrop procedimento.

O procedimento recebe apenas dois argumentos:nome do objeto e seu tipo. Para verificar o tipo de objeto, execute a seguinte instrução:
SELECT type FROM sys.objects WHERE name ='Name'

Aqui está como vai ficar:
EXEC dbo.antidrop('dbo.Name', 'FN');FUNÇÃO GOALTER dbo.Name ..

Por fim, o código do procedimento é o seguinte:
IF OBJECT_ID('dbo.antidrop', 'P') IS NULL EXEC('CREATE PROC dbo.antidrop AS');GOCREATE PROC dbo.antidrop @name SYSNAME, @type SYSNAMEASBEGIN DECLARE @if_tf NVARCHAR(512) =' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE FUNCTION ' + @name + '() RETURNS @t TABLE(i INT) BEGIN RETURN END''); VAI '; DECLARE @fn NVARCHAR(512) =' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE FUNCTION ' + @name + '(@ i INT) RETORNOS INT AS BEGIN RETURN @i + 1 END''); VAI '; DECLARE @p NVARCHAR(512) =' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE PROC ' + @name + 'AS' '); VAI '; DECLARE @v NVARCHAR(512) =' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE VIEW ' + @name + ' AS SELECT 1 ASi''); VAI '; IF @digite (N'IF', N'TF') BEGIN EXEC(@if_tf); END ELSE IF @type =N'FN' BEGIN EXEC(@fn); END ELSE IF @type =N'P' BEGIN EXEC(@p); END ELSE IF @type =N'V' BEGIN EXEC(@v); ENDENDGO

Obrigado pela sua atenção!