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

NOCHECK は外部キー参照を無効にしません

    外部キーを無効にするために、次の 2 つのスクリプトを使用しました。私はそれらを作成していません。インターウェブで見つけましたが、ここ数年は完璧に機能していました。残念ながら、それらのソースはもう見つかりません.

    references_sp.sql は、他のスクリプトを実行する前に作成する必要があるストアド プロシージャです。

    references_run.sql は、外部キーを無効化/有効化するためのスクリプトを生成するスクリプトです。

    ここで提供されているスクリプトを実行しても安全であることに注意してください。データベースを変更することはなく (一時テーブルを作成してから削除することは別として)、外部キーを削除して再作成する別のスクリプトを生成するだけです。

    そして今、スクリプト。

    references_sp.sql:

    USE [master]
    GO
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    /*********************************************************************************************
    Copyright SQLServerNation.com
    *  Author:  Tim Chapman
    ***********************************************************************************************/
    CREATE PROCEDURE [dbo].[sp_ShowForeignKeyObjects]
    AS
        SELECT 
            OBJECT_NAME(constid) AS ConstraintName,
            OBJECT_SCHEMA_NAME(fkeyid) + '.' + OBJECT_NAME(fkeyid) + '.' + COL_NAME(fkeyid, fkey) AS ForeignKeyObject,
            OBJECT_SCHEMA_NAME(rkeyid) + '.' + OBJECT_NAME(rkeyid) + '.' + COL_NAME(rkeyid, rkey) AS ReferenceKeyObject, 
            COL_NAME(fkeyid, fkey) AS ForeignKeyColumn,
            COL_NAME(rkeyid, rkey) AS ReferenceKeyColumn, 
            constid AS ConstraintID, 
            OBJECT_SCHEMA_NAME(fkeyid) + '.' + OBJECT_NAME(fkeyid) AS ForeignKeyTable,         
            fkeyid AS ForeignKeyID, 
            OBJECT_SCHEMA_NAME(rkeyid) + '.' + OBJECT_NAME(rkeyid) AS ReferenceKeyTable,
            rkeyid AS ReferenceKeyID,
            keyno AS KeySequenceNumber
        FROM 
            sysforeignkeys
        ORDER BY 
            OBJECT_NAME(rkeyid) ASC, COL_NAME(rkeyid, rkey)
    
    GO
    

    references_run.sql:

    IF OBJECT_ID('tempdb..#FK')>0
      DROP TABLE #FK
    
    IF OBJECT_ID('tempdb..#Const')>0
      DROP TABLE #Const
    
    CREATE TABLE #FK
    (
      ConstraintName VARCHAR(255),
      ForeignKeyObject VARCHAR(255),
      ReferenceObject VARCHAR(255),
      ForeignKeyColumn VARCHAR(255),
      ReferenceKeyColumn VARCHAR(255),
      ConstraintID INT, 
      ForeignKeyTable VARCHAR(255),
      ForeignKeyID INT, 
      ReferenceKeyTable VARCHAR(255),
      ReferenceKeyID INT, 
      KeySequenceNumber SMALLINT
    )
    
    CREATE TABLE #Const
    (
      ConstraintID INT, 
      FBuildField VARCHAR(2000) DEFAULT(''), 
      RBuildField VARCHAR(2000) DEFAULT(''), 
      CountField SMALLINT 
    )
    
    INSERT INTO #FK
    EXEC sp_Showforeignkeyobjects
    
    SET NOCOUNT ON
    DECLARE  tempcursor
    CURSOR
    READ_ONLY
    FOR 
    
      SELECT    
        f.ConstraintName ,
        f.ForeignKeyObject ,
        f.ReferenceObject ,
        f.ForeignKeyColumn ,
        f.ReferenceKeyColumn,
        f.ConstraintID , 
        f.ForeignKeyID , 
        f.ReferenceKeyID , 
        f.KeySequenceNumber, 
        f.ForeignKeyTable,
        f.ReferenceKeyTable 
      FROM #FK AS  f
        INNER JOIN 
        (
          SELECT ConstraintID, MAX(KeySequenceNumber) AS MaxSeq
          FROM #FK AS  k
          GROUP BY k.ConstraintID
        )b ON f.ConstraintID = b.ConstraintID AND f.KeySequenceNumber = b.MaxSeq
    
    DECLARE 
      @ConstraintName VARCHAR(255),
      @ForeignKeyObject VARCHAR(255),
      @ReferenceObject VARCHAR(255),
      @ForeignKeyColumn VARCHAR(255),
      @ReferenceKeyColumn VARCHAR(255),
      @ConstraintID INT, 
      @ForeignKeyID INT, 
      @ReferenceKeyID INT, 
      @KeySequenceNumber SMALLINT, 
      @ForeignKeyTable VARCHAR(255),
      @ReferenceKeyTable VARCHAR(255)
    
    OPEN tempcursor
    
      FETCH NEXT FROM tempCursor INTO 
      @ConstraintName ,
      @ForeignKeyObject ,
      @ReferenceObject ,
      @ForeignKeyColumn ,
      @ReferenceKeyColumn,
      @ConstraintID , 
      @ForeignKeyID , 
      @ReferenceKeyID, 
      @KeySequenceNumber,
      @ForeignKeyTable ,
      @ReferenceKeyTable 
    
    WHILE (@@fetch_status <> -1)
    BEGIN
    
      DECLARE  tempcursor2
      CURSOR
      READ_ONLY
      FOR 
    
        SELECT ConstraintID, ForeignKeyColumn, ReferenceKeyColumn, KeySequenceNumber 
        FROM #FK 
        WHERE ConstraintID = @ConstraintID
    
        ORDER BY ConstraintID, KeySequenceNumber ASC
    
      DECLARE @ConstraintID2 INT, @ForeignKeyColumn2 VARCHAR(255), @ReferenceKeyColumn2 VARCHAR(255), @KeySequenceNumber2 SMALLINT
      DECLARE @FKeyBuildField VARCHAR(1000), @RKeyBuildField VARCHAR(1000), @Cnt SMALLINT 
    
      OPEN tempcursor2
    
      SELECT @FKeyBuildField = '', @RKeyBuildField = '', @Cnt = 0
    
      FETCH NEXT FROM tempcursor2 INTO @ConstraintID2 , @ForeignKeyColumn2 , @ReferenceKeyColumn2 , @KeySequenceNumber2
      WHILE (@@fetch_status <> -1)
      BEGIN
        SET @Cnt = @Cnt + 1
        SELECT @FKeyBuildField = @FKeyBuildField  + ISNULL(@ForeignKeyColumn2,'')+ 
          CASE 
            WHEN @ForeignKeyColumn2 IS NULL THEN '' 
          ELSE  
            CASE WHEN @KeySequenceNumber = @KeySequenceNumber2 THEN '' ELSE ',' END
          END
    
        SELECT @RKeyBuildField = @RKeyBuildField  + ISNULL(@ReferenceKeyColumn2,'')+ 
          CASE 
            WHEN @ReferenceKeyColumn2 IS NULL THEN '' 
          ELSE  
            CASE WHEN @KeySequenceNumber = @KeySequenceNumber2 THEN '' ELSE ',' END
          END
    
        INSERT INTO #Const
        (   
          ConstraintID , 
          FBuildField , 
          RBuildField, 
          CountField  
        )
        VALUES
        (
          @ConstraintID, 
          @FKeyBuildField,
          @RKeyBuildField,
          @Cnt
        )
    
        FETCH NEXT FROM tempcursor2 INTO @ConstraintID2 , @ForeignKeyColumn2 , @ReferenceKeyColumn2 , @KeySequenceNumber2
      END
      CLOSE tempcursor2
      DEALLOCATE tempcursor2
    
      FETCH NEXT FROM tempCursor INTO 
      @ConstraintName ,
      @ForeignKeyObject ,
      @ReferenceObject ,
      @ForeignKeyColumn ,
      @ReferenceKeyColumn,
      @ConstraintID , 
      @ForeignKeyID , 
      @ReferenceKeyID , 
      @KeySequenceNumber ,
      @ForeignKeyTable ,
      @ReferenceKeyTable 
    END
    
    CLOSE tempcursor
    DEALLOCATE tempcursor
    
    SELECT 'ALTER TABLE ' + FKTable + ' DROP CONSTRAINT ' + OBJECT_NAME(a.ConstraintID) AS DropKeys,
    'ALTER TABLE ' + FKTable + ' WITH NOCHECK ADD CONSTRAINT ' + OBJECT_NAME(a.ConstraintID) + ' FOREIGN KEY(' + FBuildField + ') REFERENCES ' + RKTable + '(' + RBuildField+')' AS BuildKeys
    ,*
    FROM #Const a
    JOIN
    (
      SELECT ConstraintID, MAX(countfield) AS maxcount
      FROM #Const
      GROUP BY ConstraintID
    ) b ON a.ConstraintID = b.ConstraintID  AND a.countfield = b.maxcount
    JOIN
    (
    SELECT DISTINCT constraintid, '[' + OBJECT_SCHEMA_NAME(foreignkeyid) + '].[' + OBJECT_NAME(foreignkeyid) + ']' AS FKTable, '[' + OBJECT_SCHEMA_NAME(referencekeyid) + '].[' + OBJECT_NAME(referencekeyid) + ']' AS RKTable FROM #fk
    ) c ON a.constraintid = c.constraintid
    
    DROP TABLE #Const
    



    1. Postgresqlが関数で実行形式を使用しようとしましたが、合体で文字列形式を指定すると列が見つかりませんというエラーが発生しました

    2. Mariadb-延長された挿入実行時間のすべてのバッチが徐々に増加しています

    3. デフォルトとしてマークされた1つのレコードのみの制約

    4. MySQLの結果がPHPで空を返したかどうかを確認するにはどうすればよいですか?