sql >> データベース >  >> RDS >> Database

DROPよりも優れたALTER

    この記事では、オブジェクトを作成する前にオブジェクトを削除するための構造を提供します。

    私たちのチームには、約20人のSQLNinja開発者がいます。それらはすべて、この構造をさまざまな方法で説明しています。

    私たちのチームは約20人のSQL忍者で構成されており、全員が次のステートメントを異なる方法で使用しています。

    IF OBJECT_ID('dbo.Function', 'TF') IS NOT NULL
    	DROP FUNCTION dbo.Function;
    GO
    CREATE FUNCTION dbo.Function ..

    または:

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

    または:

    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 ..

    StackOverflowでは、ユーザーはこのバージョンを気に入りました:

    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

    星が整列していて、SQLサイトの1つで適切な実装を見つけました。最初はショックを受けましたが、その後、人々はそれがうまく機能する理由を理解するのに役立ちました。

    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 ..

    重要なのは、毎回DROPステートメントとCREATEステートメントを使用する場合は、オブジェクトのアクセス許可を削除するということです。さらに、オブジェクトはレプリケーションに含まれている可能性があり、再作成されると削除されます。

    それで、私はこのバージョンが好きで、それを dbo.antidropにまとめることに決めました。 手順。

    このプロシージャは、オブジェクト名とそのタイプの2つの引数のみを取ります。オブジェクトタイプを確認するには、次のステートメントを実行します。

    SELECT type 
    FROM sys.objects 
    WHERE name = 'Name'

    外観は次のとおりです。

    EXEC dbo.antidrop('dbo.Name', 'FN');
    GO
    ALTER FUNCTION dbo.Name ..

    最後に、手順のコードは次のとおりです。

    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

    ご清聴ありがとうございました!


    1. SQL ServerでのASIN()の例

    2. WHMCSデータベースをMariaDBガレラクラスターに移行する方法

    3. PostgreSQLの「エラー:各UNIONクエリには同じ数の列が必要」を修正

    4. PostgreSQLとMySQL:どちらが最適ですか?