In questo articolo, fornirò una costruzione per eliminare un oggetto prima di crearlo.
Nel nostro team ci sono una ventina di sviluppatori SQL Ninja. Tutti descrivono questa costruzione in modi diversi.
Il nostro team è composto da una ventina di SQL Ninja e tutti usano la seguente affermazione in un modo diverso:
IF OBJECT_ID('dbo.Function', 'TF') IS NOT NULL DROP FUNCTION dbo.Function; GO CREATE FUNCTION dbo.Function ..
Oppure:
IF EXISTS ( SELECT * FROM sys.objects WHERE name = 'Procedure' AND type = 'P' ) DROP PROCEDURE dbo.Procedure; GO CREATE PROCEDURE dbo.Procedure ..
Oppure:
IF EXISTS ( SELECT 1 FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.Function') AND type IN (N'FN', N'IF', N'TF', N'FS', N'FT') ) DROP FUNCTION dbo.Function; GO CREATE FUNCTION dbo.Function ..
Su StackOverflow, agli utenti è piaciuta questa versione:
IF EXISTS ( SELECT * FROM sysobjects WHERE id = object_id(N'function_name') AND xtype IN (N'FN', N'IF', N'TF') ) DROP FUNCTION function_name GO
Le stelle sono allineate e ho trovato un'implementazione appropriata in uno dei siti SQL. All'inizio sono rimasto scioccato, ma poi le persone hanno aiutato a capire perché funziona bene.
IF OBJECT_ID('dbo.Function', 'TF') IS NULL EXEC('CREATE FUNCTION dbo.Function() RETURNS @t TABLE(i INT) BEGIN RETURN END'); GO ALTER FUNCTION dbo.Function ..
Il punto è che se si utilizzano le istruzioni DROP e CREATE ogni volta, si eliminano le autorizzazioni dell'oggetto. Inoltre, l'oggetto può essere nella replica e verrà eliminato anche una volta ricreato.
Quindi, questa versione mi è piaciuta e ho deciso di racchiuderla in dbo.antidrop procedura.
La procedura accetta solo due argomenti:il nome dell'oggetto e il suo tipo. Per verificare il tipo di oggetto, eseguire la seguente istruzione:
SELECT type FROM sys.objects WHERE name = 'Name'
Ecco come apparirà:
EXEC dbo.antidrop('dbo.Name', 'FN'); GO ALTER FUNCTION dbo.Name ..
Infine, il codice della procedura è il seguente:
IF OBJECT_ID('dbo.antidrop', 'P') IS NULL EXEC('CREATE PROC dbo.antidrop AS'); GO CREATE PROC dbo.antidrop @name SYSNAME, @type SYSNAME AS BEGIN DECLARE @if_tf NVARCHAR(512) = ' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE FUNCTION ' + @name + '() RETURNS @t TABLE(i INT) BEGIN RETURN END''); GO '; DECLARE @fn NVARCHAR(512) = ' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE FUNCTION ' + @name + '(@i INT) RETURNS INT AS BEGIN RETURN @i + 1 END''); GO '; DECLARE @p NVARCHAR(512) = ' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE PROC ' + @name + 'AS''); GO '; DECLARE @v NVARCHAR(512) = ' IF OBJECT_ID(''' + @name + ''', ''' + @type + ''') IS NULL EXEC(''CREATE VIEW ' + @name + ' AS SELECT 1 AS i''); GO '; IF @type in (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); END END GO
Grazie per l'attenzione!