Frage

Sperren und Freigeben für Fremdschlüssel in SQL Server unterstützt? Oder ist meine einzige Option drop und dann Wieder create die Einschränkungen?

War es hilfreich?

Lösung

Wenn Sie alle Einschränkungen in der Datenbank deaktivieren möchten nur diesen Code ausführen:

-- disable all constraints
EXEC sp_MSforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"

Sie auf Um wieder zu starten, führt (der Druck natürlich optional ist, und es ist nur die Tabellen,)

-- enable all constraints
exec sp_MSforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

Ich finde es nützlich, wenn Daten von einer Datenbank zur anderen bevölkern. Es ist viel besser als Ansatz fallen Einschränkungen. Wie Sie erwähnt kommt es praktisch, wenn alle Daten in der Datenbank löschen und neu zu besiedeln sie (sagen in Testumgebung).

Wenn Sie alle Daten löschen können Sie eine href finden <= "https://stackoverflow.com/questions/155246/how-do-you-truncate-all-tables-in-a-database-using- tsql # 156813" > diese Lösung hilfreich sein.

Auch ist es manchmal praktisch alle löst auch zu deaktivieren, können Sie die komplette Lösung finden Sie unter hier .

Andere Tipps

http://www.sqljunkies.com/ WebLog / roman / Archiv / 2005/01/30 / 7037.aspx

-- Disable all table constraints

ALTER TABLE MyTable NOCHECK CONSTRAINT ALL

-- Enable all table constraints

ALTER TABLE MyTable WITH CHECK CHECK CONSTRAINT ALL

-- Disable single constraint

ALTER TABLE MyTable NOCHECK CONSTRAINT MyConstraint

-- Enable single constraint

ALTER TABLE MyTable WITH CHECK CHECK CONSTRAINT MyConstraint

die Einschränkung Sie die Tabelle ALTER haben zu deaktivieren NOCHECK

ALTER TABLE [TABLE_NAME] NOCHECK CONSTRAINT [ALL|CONSTRAINT_NAME]

Damit Sie doppelt verwenden müssen Überprüfen

ALTER TABLE [TABLE_NAME] WITH CHECK CHECK CONSTRAINT [ALL|CONSTRAINT_NAME]
  • Achten Sie auf die Doppel CHECK CHECK , wenn ermöglicht wird.
  • ALL bedeutet für alle Einschränkungen in der Tabelle.

Nach der Fertigstellung, wenn Sie den Status überprüfen müssen, verwenden Sie dieses Skript die Einschränkung Status aufzulisten. Wird sehr hilfreich:

    SELECT (CASE 
        WHEN OBJECTPROPERTY(CONSTID, 'CNSTISDISABLED') = 0 THEN 'ENABLED'
        ELSE 'DISABLED'
        END) AS STATUS,
        OBJECT_NAME(CONSTID) AS CONSTRAINT_NAME,
        OBJECT_NAME(FKEYID) AS TABLE_NAME,
        COL_NAME(FKEYID, FKEY) AS COLUMN_NAME,
        OBJECT_NAME(RKEYID) AS REFERENCED_TABLE_NAME,
        COL_NAME(RKEYID, RKEY) AS REFERENCED_COLUMN_NAME
   FROM SYSFOREIGNKEYS
ORDER BY TABLE_NAME, CONSTRAINT_NAME,REFERENCED_TABLE_NAME, KEYNO 

Ihre beste Möglichkeit ist, Fremdschlüssel zu löschen und erstellen.

Ich habe keine Beispiele in diesem Beitrag finden, die für mich arbeiten würde „wie sie ist“, würde man nicht, wenn Fremdschlüssel unterschiedliche Schemata verweisen, würde der andere nicht, wenn Fremdschlüsselreferenzen mehr Spalten arbeiten. Dieses Skript berücksichtigt beide, mehrere Schemata und mehrere Spalten pro Fremdschlüssel.

Hier ist das Skript, das „ADD CONSTRAINT“ Aussagen, für mehrere Spalten erzeugt wird er sie durch Komma getrennt ( sicher sein, diese Ausgabe zu speichern, bevor DROP-Anweisungen ausführen ):

PRINT N'-- CREATE FOREIGN KEY CONSTRAINTS --';

SET NOCOUNT ON;
SELECT '
PRINT N''Creating '+ const.const_name +'...''
GO
ALTER TABLE ' + const.parent_obj + '
    ADD CONSTRAINT ' + const.const_name + ' FOREIGN KEY (
            ' + const.parent_col_csv + '
            ) REFERENCES ' + const.ref_obj + '(' + const.ref_col_csv + ')
GO'
FROM (
    SELECT QUOTENAME(fk.NAME) AS [const_name]
        ,QUOTENAME(schParent.NAME) + '.' + QUOTENAME(OBJECT_name(fkc.parent_object_id)) AS [parent_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcP.parent_object_id, fcp.parent_column_id))
                FROM sys.foreign_key_columns AS fcP
                WHERE fcp.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [parent_col_csv]
        ,QUOTENAME(schRef.NAME) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) AS [ref_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcR.referenced_object_id, fcR.referenced_column_id))
                FROM sys.foreign_key_columns AS fcR
                WHERE fcR.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [ref_col_csv]
    FROM sys.foreign_key_columns AS fkc
    INNER JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.objects AS oParent ON oParent.object_id = fkc.parent_object_id
    INNER JOIN sys.schemas AS schParent ON schParent.schema_id = oParent.schema_id
    INNER JOIN sys.objects AS oRef ON oRef.object_id = fkc.referenced_object_id
    INNER JOIN sys.schemas AS schRef ON schRef.schema_id = oRef.schema_id
    GROUP BY fkc.parent_object_id
        ,fkc.referenced_object_id
        ,fk.NAME
        ,fk.object_id
        ,schParent.NAME
        ,schRef.NAME
    ) AS const
ORDER BY const.const_name

Hier ist das Skript, das "DROP CONSTRAINT" Anweisungen generiert:

PRINT N'-- DROP FOREIGN KEY CONSTRAINTS --';

SET NOCOUNT ON;

SELECT '
PRINT N''Dropping ' + fk.NAME + '...''
GO
ALTER TABLE [' + sch.NAME + '].[' + OBJECT_NAME(fk.parent_object_id) + ']' + ' DROP  CONSTRAINT ' + '[' + fk.NAME + ']
GO'
FROM sys.foreign_keys AS fk
INNER JOIN sys.schemas AS sch ON sch.schema_id = fk.schema_id
ORDER BY fk.NAME

Der SQL-92-Standard ermöglicht eine constaint als DEFERRABLE erklärt werden, so dass es (implizit oder explizit) im Rahmen einer Transaktion aufgeschoben werden kann. Leider ist SQL Server immer noch diese SQL-92-Funktionalität fehlt.

Für mich eine Einschränkung zu NOCHECK Ändern ähneln die Struktur der Datenbank on the fly zu ändern - fallen Einschränkungen sicher ist - und etwas zu vermeiden (zum Beispiel Benutzer-Rechte erfordern erhöht)

.
   --Drop and Recreate Foreign Key Constraints

SET NOCOUNT ON

DECLARE @table TABLE(
   RowId INT PRIMARY KEY IDENTITY(1, 1),
   ForeignKeyConstraintName NVARCHAR(200),
   ForeignKeyConstraintTableSchema NVARCHAR(200),
   ForeignKeyConstraintTableName NVARCHAR(200),
   ForeignKeyConstraintColumnName NVARCHAR(200),
   PrimaryKeyConstraintName NVARCHAR(200),
   PrimaryKeyConstraintTableSchema NVARCHAR(200),
   PrimaryKeyConstraintTableName NVARCHAR(200),
   PrimaryKeyConstraintColumnName NVARCHAR(200)    
)

INSERT INTO @table(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName)
SELECT 
   U.CONSTRAINT_NAME, 
   U.TABLE_SCHEMA, 
   U.TABLE_NAME, 
   U.COLUMN_NAME 
FROM 
   INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
      INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
         ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE
   C.CONSTRAINT_TYPE = 'FOREIGN KEY'

UPDATE @table SET
   PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME
FROM 
   @table T
      INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
         ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME

UPDATE @table SET
   PrimaryKeyConstraintTableSchema  = TABLE_SCHEMA,
   PrimaryKeyConstraintTableName  = TABLE_NAME
FROM @table T
   INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
      ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME

UPDATE @table SET
   PrimaryKeyConstraintColumnName = COLUMN_NAME
FROM @table T
   INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
      ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME

--SELECT * FROM @table

--DROP CONSTRAINT:
SELECT
   '
   ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] 
   DROP CONSTRAINT ' + ForeignKeyConstraintName + '

   GO'
FROM
   @table

--ADD CONSTRAINT:
SELECT
   '
   ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] 
   ADD CONSTRAINT ' + ForeignKeyConstraintName + ' FOREIGN KEY(' + ForeignKeyConstraintColumnName + ') REFERENCES [' + PrimaryKeyConstraintTableSchema + '].[' + PrimaryKeyConstraintTableName + '](' + PrimaryKeyConstraintColumnName + ')

   GO'
FROM
   @table

GO

ich mit Ihnen, Hamlin einverstanden. Wenn Sie Übertragung von Daten unter Verwendung von SSIS oder wenn mögen Daten replizieren, so scheint es durchaus notwendig, um vorübergehend Fremdschlüssel-Constraints zu deaktivieren oder löschen und dann wieder aktivieren oder neu erstellen. In diesen Fällen ist die referentielle Integrität nicht ein Problem, weil es bereits in der Quelldatenbank aufrechterhalten wird. Daher können Sie in dieser Angelegenheit sicher sein.

SET NOCOUNT ON

DECLARE @table TABLE(
   RowId INT PRIMARY KEY IDENTITY(1, 1),
   ForeignKeyConstraintName NVARCHAR(200),
   ForeignKeyConstraintTableSchema NVARCHAR(200),
   ForeignKeyConstraintTableName NVARCHAR(200),
   ForeignKeyConstraintColumnName NVARCHAR(200),
   PrimaryKeyConstraintName NVARCHAR(200),
   PrimaryKeyConstraintTableSchema NVARCHAR(200),
   PrimaryKeyConstraintTableName NVARCHAR(200),
   PrimaryKeyConstraintColumnName NVARCHAR(200),
   UpdateRule NVARCHAR(100),
   DeleteRule NVARCHAR(100)   
)

INSERT INTO @table(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName)
SELECT 
   U.CONSTRAINT_NAME, 
   U.TABLE_SCHEMA, 
   U.TABLE_NAME, 
   U.COLUMN_NAME
FROM 
   INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
      INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
         ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE
   C.CONSTRAINT_TYPE = 'FOREIGN KEY'

UPDATE @table SET
   T.PrimaryKeyConstraintName = R.UNIQUE_CONSTRAINT_NAME,
   T.UpdateRule = R.UPDATE_RULE,
   T.DeleteRule = R.DELETE_RULE
FROM 
   @table T
      INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
         ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME

UPDATE @table SET
   PrimaryKeyConstraintTableSchema  = TABLE_SCHEMA,
   PrimaryKeyConstraintTableName  = TABLE_NAME
FROM @table T
   INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
      ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME

UPDATE @table SET
   PrimaryKeyConstraintColumnName = COLUMN_NAME
FROM @table T
   INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
      ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME

--SELECT * FROM @table

SELECT '
BEGIN TRANSACTION
BEGIN TRY'

--DROP CONSTRAINT:
SELECT
   '
 ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] 
 DROP CONSTRAINT ' + ForeignKeyConstraintName + '
   '
FROM
   @table

SELECT '
END TRY

BEGIN CATCH
   ROLLBACK TRANSACTION
   RAISERROR(''Operation failed.'', 16, 1)
END CATCH

IF(@@TRANCOUNT != 0)
BEGIN
   COMMIT TRANSACTION
   RAISERROR(''Operation completed successfully.'', 10, 1)
END
'

--ADD CONSTRAINT:
SELECT '
BEGIN TRANSACTION
BEGIN TRY'

SELECT
   '
   ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + '] 
   ADD CONSTRAINT ' + ForeignKeyConstraintName + ' FOREIGN KEY(' + ForeignKeyConstraintColumnName + ') REFERENCES [' + PrimaryKeyConstraintTableSchema + '].[' + PrimaryKeyConstraintTableName + '](' + PrimaryKeyConstraintColumnName + ') ON UPDATE ' + UpdateRule + ' ON DELETE ' + DeleteRule + '
   '
FROM
   @table

SELECT '
END TRY

BEGIN CATCH
   ROLLBACK TRANSACTION
   RAISERROR(''Operation failed.'', 16, 1)
END CATCH

IF(@@TRANCOUNT != 0)
BEGIN
   COMMIT TRANSACTION
   RAISERROR(''Operation completed successfully.'', 10, 1)
END'

GO

Erster Beitrag:)

Für die OP, kristof-Lösung funktionieren wird, es sei denn, es gibt Probleme mit massiven Daten und Transaktionsprotokoll Ballon Probleme auf großen Löschungen. Auch selbst mit tlog Lagerung zu schonen, da Löschungen zum tlog schreibt, kann der Betrieb eine sehr lange Zeit für Tabellen mit Hunderten von Millionen von Zeilen.

Ich verwende eine Reihe von Cursor großen Kopien eines unserer großen Produktionsdatenbanken häufig zu kürzen und neu laden. Die Lösung entwickelt Konten für mehrere Schemas, mehrere Fremdschlüsselspalten, und am besten von allen für den Einsatz in SSIS sproc'd werden kann.

Es geht um die Schaffung von drei Importiertabellen (reale Tabellen) die DROP Hause, CREATE und CHECK-Skripte FK, Erstellen und Einfügen dieser Skripte in die Tabellen, und dann die Tabellen Schleifen über und Ausführen von ihnen. Das beigefügte Skript ist aus vier Teilen: 1.) Erstellung und Speicherung der Skripte in den drei Staging (real) Tabellen, 2.) die Ausführung der Drop-FK-Skripte über einen Cursor nacheinander, sp_MSforeachtable 3.) alle trunkieren Tabellen in der Datenbank anders als unsere drei Zwischenspeichertabellen und 4.) Durchführung der FK erstellen und FK-Skripte am Ende Ihres ETL SSIS-Paket überprüfen.

Führen Sie die Skripterstellung Abschnitt in einem Task SQL ausführen in SSIS. Führen Sie den „Drop FK Scripts ausführen“ -Teil in einer zweiten Task SQL ausführen. Legen Sie das Abschneiden Skript in einer dritten Task SQL ausführen, dann ausführen, was andere ETL-Prozesse, um die Erstellung und Überprüfung von Skripten in einer abschließenden Task SQL ausführen (oder zwei, wenn gewünscht) am Ende des Steuerflusses zu befestigen. Vor tun müssen

Die Speicherung der Skripte in realen Tabellen als sehr hilfreich erwiesen, wenn die Wiederanwendung des Fremdschlüssels nicht, wie Sie * aus sync_CreateFK auswählen, Kopieren / Einfügen in Ihre Abfrage-Fenster, führen sie einen nach dem anderen, und befestigen Sie die Daten wenn Sie Fragen zu finden diejenigen, die noch neu zu beantragen versagt / versagen.

Sie das Skript erneut nicht erneut ausführen, wenn es ohne sicherzustellen, nicht, dass Sie erneut bewerben alle der Fremdschlüssel / Kontrollen vor, so zu tun, oder Sie werden wahrscheinlich einige Schöpfung verlieren und fk Scripting als unsere Importiertabellen überprüfen werden gelöscht und vor der Erstellung der Skripte neu auszuführen.

----------------------------------------------------------------------------
1)
/*
Author:         Denmach
DateCreated:    2014-04-23
Purpose:        Generates SQL statements to DROP, ADD, and CHECK existing constraints for a 
                database.  Stores scripts in tables on target database for execution.  Executes
                those stored scripts via independent cursors. 
DateModified:
ModifiedBy
Comments:       This will eliminate deletes and the T-log ballooning associated with it.
*/

DECLARE @schema_name SYSNAME; 
DECLARE @table_name SYSNAME; 
DECLARE @constraint_name SYSNAME; 
DECLARE @constraint_object_id INT; 
DECLARE @referenced_object_name SYSNAME; 
DECLARE @is_disabled BIT; 
DECLARE @is_not_for_replication BIT; 
DECLARE @is_not_trusted BIT; 
DECLARE @delete_referential_action TINYINT; 
DECLARE @update_referential_action TINYINT; 
DECLARE @tsql NVARCHAR(4000); 
DECLARE @tsql2 NVARCHAR(4000); 
DECLARE @fkCol SYSNAME; 
DECLARE @pkCol SYSNAME; 
DECLARE @col1 BIT; 
DECLARE @action CHAR(6);  
DECLARE @referenced_schema_name SYSNAME;



--------------------------------Generate scripts to drop all foreign keys in a database --------------------------------

IF OBJECT_ID('dbo.sync_dropFK') IS NOT NULL
DROP TABLE sync_dropFK

CREATE TABLE sync_dropFK
    (
    ID INT IDENTITY (1,1) NOT NULL
    , Script NVARCHAR(4000)
    )

DECLARE FKcursor CURSOR FOR

    SELECT 
        OBJECT_SCHEMA_NAME(parent_object_id)
        , OBJECT_NAME(parent_object_id)
        , name
    FROM 
        sys.foreign_keys WITH (NOLOCK)
    ORDER BY 
        1,2;

OPEN FKcursor;

FETCH NEXT FROM FKcursor INTO 
    @schema_name
    , @table_name
    , @constraint_name

WHILE @@FETCH_STATUS = 0

BEGIN
        SET @tsql = 'ALTER TABLE '
                + QUOTENAME(@schema_name) 
                + '.' 
                + QUOTENAME(@table_name)
                + ' DROP CONSTRAINT ' 
                + QUOTENAME(@constraint_name) 
                + ';';
    --PRINT @tsql;
    INSERT sync_dropFK  (
                        Script
                        )
                        VALUES (
                                @tsql
                                )   

    FETCH NEXT FROM FKcursor INTO 
    @schema_name
    , @table_name
    , @constraint_name
    ;

END;

CLOSE FKcursor;

DEALLOCATE FKcursor;


---------------Generate scripts to create all existing foreign keys in a database --------------------------------
----------------------------------------------------------------------------------------------------------
IF OBJECT_ID('dbo.sync_createFK') IS NOT NULL
DROP TABLE sync_createFK

CREATE TABLE sync_createFK
    (
    ID INT IDENTITY (1,1) NOT NULL
    , Script NVARCHAR(4000)
    )

IF OBJECT_ID('dbo.sync_createCHECK') IS NOT NULL
DROP TABLE sync_createCHECK

CREATE TABLE sync_createCHECK
    (
    ID INT IDENTITY (1,1) NOT NULL
    , Script NVARCHAR(4000)
    )   

DECLARE FKcursor CURSOR FOR

     SELECT 
        OBJECT_SCHEMA_NAME(parent_object_id)
        , OBJECT_NAME(parent_object_id)
        , name
        , OBJECT_NAME(referenced_object_id)
        , OBJECT_ID
        , is_disabled
        , is_not_for_replication
        , is_not_trusted
        , delete_referential_action
        , update_referential_action
        , OBJECT_SCHEMA_NAME(referenced_object_id)

    FROM 
        sys.foreign_keys WITH (NOLOCK)

    ORDER BY 
        1,2;

OPEN FKcursor;

FETCH NEXT FROM FKcursor INTO 
    @schema_name
    , @table_name
    , @constraint_name
    , @referenced_object_name
    , @constraint_object_id
    , @is_disabled
    , @is_not_for_replication
    , @is_not_trusted
    , @delete_referential_action
    , @update_referential_action
    , @referenced_schema_name;

WHILE @@FETCH_STATUS = 0

BEGIN

        BEGIN
            SET @tsql = 'ALTER TABLE '
                        + QUOTENAME(@schema_name) 
                        + '.' 
                        + QUOTENAME(@table_name)
                        +   CASE 
                                @is_not_trusted
                                WHEN 0 THEN ' WITH CHECK '
                                ELSE ' WITH NOCHECK '
                            END
                        + ' ADD CONSTRAINT ' 
                        + QUOTENAME(@constraint_name)
                        + ' FOREIGN KEY (';

        SET @tsql2 = '';

        DECLARE ColumnCursor CURSOR FOR 

            SELECT 
                COL_NAME(fk.parent_object_id
                , fkc.parent_column_id)
                , COL_NAME(fk.referenced_object_id
                , fkc.referenced_column_id)

            FROM 
                sys.foreign_keys fk WITH (NOLOCK)
                INNER JOIN sys.foreign_key_columns fkc WITH (NOLOCK) ON fk.[object_id] = fkc.constraint_object_id

            WHERE 
                fkc.constraint_object_id = @constraint_object_id

            ORDER BY 
                fkc.constraint_column_id;

        OPEN ColumnCursor;

        SET @col1 = 1;

        FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;

        WHILE @@FETCH_STATUS = 0

        BEGIN
            IF (@col1 = 1)
                SET @col1 = 0;
            ELSE
            BEGIN
                SET @tsql = @tsql + ',';
                SET @tsql2 = @tsql2 + ',';
            END;

            SET @tsql = @tsql + QUOTENAME(@fkCol);
            SET @tsql2 = @tsql2 + QUOTENAME(@pkCol);
            --PRINT '@tsql = ' + @tsql 
            --PRINT '@tsql2 = ' + @tsql2
            FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
            --PRINT 'FK Column ' + @fkCol
            --PRINT 'PK Column ' + @pkCol 
        END;

        CLOSE ColumnCursor;
        DEALLOCATE ColumnCursor;

        SET @tsql = @tsql + ' ) REFERENCES ' 
                    + QUOTENAME(@referenced_schema_name) 
                    + '.' 
                    + QUOTENAME(@referenced_object_name)
                    + ' (' 
                    + @tsql2 + ')';

        SET @tsql = @tsql
                    + ' ON UPDATE ' 
                    + 
                        CASE @update_referential_action
                            WHEN 0 THEN 'NO ACTION '
                            WHEN 1 THEN 'CASCADE '
                            WHEN 2 THEN 'SET NULL '
                                ELSE 'SET DEFAULT '
                        END

                    + ' ON DELETE ' 
                    + 
                        CASE @delete_referential_action
                            WHEN 0 THEN 'NO ACTION '
                            WHEN 1 THEN 'CASCADE '
                            WHEN 2 THEN 'SET NULL '
                                ELSE 'SET DEFAULT '
                        END

                    + 
                    CASE @is_not_for_replication
                        WHEN 1 THEN ' NOT FOR REPLICATION '
                            ELSE ''
                    END
                    + ';';

        END;

    --  PRINT @tsql
        INSERT sync_createFK    
                        (
                        Script
                        )
                        VALUES (
                                @tsql
                                )

-------------------Generate CHECK CONSTRAINT scripts for a database ------------------------------
----------------------------------------------------------------------------------------------------------

        BEGIN

        SET @tsql = 'ALTER TABLE '
                    + QUOTENAME(@schema_name) 
                    + '.' 
                    + QUOTENAME(@table_name)
                    + 
                        CASE @is_disabled
                            WHEN 0 THEN ' CHECK '
                                ELSE ' NOCHECK '
                        END
                    + 'CONSTRAINT ' 
                    + QUOTENAME(@constraint_name)
                    + ';';
        --PRINT @tsql;
        INSERT sync_createCHECK 
                        (
                        Script
                        )
                        VALUES (
                                @tsql
                                )   
        END;

    FETCH NEXT FROM FKcursor INTO 
    @schema_name
    , @table_name
    , @constraint_name
    , @referenced_object_name
    , @constraint_object_id
    , @is_disabled
    , @is_not_for_replication
    , @is_not_trusted
    , @delete_referential_action
    , @update_referential_action
    , @referenced_schema_name;

END;

CLOSE FKcursor;

DEALLOCATE FKcursor;

--SELECT * FROM sync_DropFK
--SELECT * FROM sync_CreateFK
--SELECT * FROM sync_CreateCHECK
---------------------------------------------------------------------------
2.)
-----------------------------------------------------------------------------------------------------------------
----------------------------execute Drop FK Scripts --------------------------------------------------

DECLARE @scriptD NVARCHAR(4000)

DECLARE DropFKCursor CURSOR FOR
    SELECT Script 
    FROM sync_dropFK WITH (NOLOCK)

OPEN DropFKCursor

FETCH NEXT FROM DropFKCursor
INTO @scriptD

WHILE @@FETCH_STATUS = 0
BEGIN
--PRINT @scriptD
EXEC (@scriptD)
FETCH NEXT FROM DropFKCursor
INTO @scriptD
END
CLOSE DropFKCursor
DEALLOCATE DropFKCursor
--------------------------------------------------------------------------------
3.) 

------------------------------------------------------------------------------------------------------------------
----------------------------Truncate all tables in the database other than our staging tables --------------------
------------------------------------------------------------------------------------------------------------------


EXEC sp_MSforeachtable 'IF OBJECT_ID(''?'') NOT IN 
(
ISNULL(OBJECT_ID(''dbo.sync_createCHECK''),0),
ISNULL(OBJECT_ID(''dbo.sync_createFK''),0),
ISNULL(OBJECT_ID(''dbo.sync_dropFK''),0)
)
BEGIN TRY
 TRUNCATE TABLE ?
END TRY
BEGIN CATCH
 PRINT ''Truncation failed on''+ ? +''
END CATCH;' 
GO
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------
----------------------------execute Create FK Scripts and CHECK CONSTRAINT Scripts---------------
----------------------------tack me at the end of the ETL in a SQL task-------------------------
-------------------------------------------------------------------------------------------------
DECLARE @scriptC NVARCHAR(4000)

DECLARE CreateFKCursor CURSOR FOR
    SELECT Script 
    FROM sync_createFK WITH (NOLOCK)

OPEN CreateFKCursor

FETCH NEXT FROM CreateFKCursor
INTO @scriptC

WHILE @@FETCH_STATUS = 0
BEGIN
--PRINT @scriptC
EXEC (@scriptC)
FETCH NEXT FROM CreateFKCursor
INTO @scriptC
END
CLOSE CreateFKCursor
DEALLOCATE CreateFKCursor
-------------------------------------------------------------------------------------------------
DECLARE @scriptCh NVARCHAR(4000)

DECLARE CreateCHECKCursor CURSOR FOR
    SELECT Script 
    FROM sync_createCHECK WITH (NOLOCK)

OPEN CreateCHECKCursor

FETCH NEXT FROM CreateCHECKCursor
INTO @scriptCh

WHILE @@FETCH_STATUS = 0
BEGIN
--PRINT @scriptCh
EXEC (@scriptCh)
FETCH NEXT FROM CreateCHECKCursor
INTO @scriptCh
END
CLOSE CreateCHECKCursor
DEALLOCATE CreateCHECKCursor

WITH CHECK CHECK ist mit ziemlicher Sicherheit erforderlich!

Dieser Punkt wurde in einige der Antworten und Kommentare angehoben, aber ich glaube, dass es wichtig genug ist, um es wieder zu rufen.

Re-Enabling eine Einschränkung mit dem folgenden Befehl (kein WITH CHECK) wird einige schwerwiegende Nachteile .

ALTER TABLE MyTable CHECK CONSTRAINT MyConstraint;
  

WITH CHECK | MIT NOCHECK

     

Gibt an, ob die Daten in der Tabelle ist oder validiert nicht gegen   ein neu hinzugefügte oder Constraint wieder aktiviert FOREIGN KEY oder Scheck. Wenn nicht   angegeben, WITH CHECK für neue Einschränkungen angenommen wird, und mit NOCHECK   wieder aktiviert Einschränkungen angenommen für wird.

     

Wenn Sie nicht möchten, dass neue CHECK oder FOREIGN KEY-Einschränkungen überprüfen   gegen bestehende Daten, die Verwendung mit NOCHECK. Wir empfehlen nicht tun   dies, außer in seltenen Fällen. Die neue Einschränkung wird ausgewertet   alle späteren Datenaktualisierungen. Jegliche Constraint-Verletzungen, die unterdrückt werden   Durch die Zusammenarbeit mit NOCHECK, wenn die Einschränkung hinzugefügt wird, kann zukünftiges Updates verursachen   zum Scheitern verurteilt, wenn sie Zeilen mit Daten aktualisieren, die nicht mit dem nicht entsprechen   Zwang.

     

Der Abfrageoptimierer berücksichtigt nicht Einschränkungen, die definiert sind,   MIT NOCHECK. Solche Beschränkungen ignoriert werden, bis sie wieder aktiviert werden   mithilfe von ALTER TABLE Tabelle MIT CHECK CHECK CONSTRAINT ALL.

Hinweis: MIT NOCHECK ist die Standardeinstellung für die erneute Aktivierung Einschränkungen. Ich muss mich fragen, warum ...

  1. Keine vorhandenen Daten in der Tabelle werden während der Ausführung dieses Befehls ausgewertet werden - erfolgreicher Abschluss ist keine Garantie, dass die Daten in der Tabelle gültig sind nach der Einschränkung
  2. .
  3. Während der nächsten Aktualisierung der ungültigen Datensätze, wird die Constraint ausgewertet und wird scheitern - was zu Fehlern, die dem eigentlichen Update nicht verwandt sein kann, die gemacht wird,
  4. .
  5. Anwendungslogik, die auf der Einschränkung beruht, dass die Daten, um sicherzustellen, gültig ist fehlschlagen.
  6. Der Abfrageoptimierer wird nicht Gebrauch jeglicher Einschränkung machen, die auf diese Weise aktiviert ist.

Die sys.foreign_keys Systemansicht bietet einige Einblicke in das Thema . Beachten Sie, dass es sowohl eine is_disabled und eine is_not_trusted Spalte hat. is_disabled zeigt an, ob zukünftige Datenmanipulationsoperationen werden gegen die Einschränkung validiert werden. is_not_trusted zeigt an, ob alle Daten aktuell in der Tabelle gegen die Einschränkung validiert wurde.

ALTER TABLE MyTable WITH CHECK CHECK CONSTRAINT MyConstraint;

Sind Ihre Zwänge zu trauen? Finden Sie heraus, ...

SELECT * FROM sys.foreign_keys WHERE is_not_trusted = 1;

Hier finden Sie die Einschränkung

SELECT * 
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('TABLE_NAME')

Führen Sie den von diesen SQL generierte SQL

SELECT 
    'ALTER TABLE ' +  OBJECT_SCHEMA_NAME(parent_object_id) +
    '.[' + OBJECT_NAME(parent_object_id) + 
    '] DROP CONSTRAINT ' + name
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('TABLE_NAME')

Safeway.

. Hinweis: Hinzugefügt Lösung für Droping der Einschränkung, so dass Tabelle ohne Einschränkung Fehler gelöscht oder geändert werden

Klicken Sie rechts in die Tabelle Design und gehen Sie zu Beziehungen und den Fremdschlüssel auf dem linken Bereich auswählen und im rechten Bereich, setzen Sie Fremdschlüssel Erzwingen auf ‚Ja‘ (ermöglichen Fremdschlüssel-Constraints) oder ‚Nein '(zu deaktivieren). eingeben Bild Beschreibung hier

Antwort der Aufschrift '905' sieht gut aus, funktioniert aber nicht.

Im Anschluss für mich gearbeitet. Jeder Primärschlüssel, eindeutige Schlüssel oder Standardeinschränkungen NICHT deaktiviert. wenn ‚sp_helpconstraint '' zeigt 'n / a' in status_enabled In der Tat - bedeutet, dass es nicht wird aktiviert / deaktiviert

.

- Skript zu generieren, um zu SPERREN

select 'ALTER TABLE ' + object_name(id) + ' NOCHECK CONSTRAINT [' + object_name(constid) + ']'
from sys.sysconstraints 
where status & 0x4813 = 0x813 order by object_name(id)

- Skript zu generieren, um ENABLE

select 'ALTER TABLE ' + object_name(id) + ' CHECK CONSTRAINT [' + object_name(constid) + ']'
from sys.sysconstraints 
where status & 0x4813 = 0x813 order by object_name(id)

Sie sollten Sie vorübergehend deaktivieren andere Einschränkungen tatsächlich in der Lage sein, Fremdschlüssel-Constraints auf die gleiche Weise zu deaktivieren:

Alter table MyTable nocheck constraint FK_ForeignKeyConstraintName

So stellen Sie sicher, dass Sie das Deaktivieren der Beschränkung auf die erste Tabelle in der Constraint-Name aufgeführt. wenn meine Fremdschlüssel FK_LocationsEmployeesLocationIdEmployeeId Zum Beispiel wäre, würde ich möchte folgend verwenden:

Alter table Locations nocheck constraint FK_LocationsEmployeesLocationIdEmployeeId

obwohl diese Beschränkung zu verletzen wird einen Fehler erzeugen, die nicht unbedingt die Tabelle als Quelle des Konflikts angeben.

Ein Skript sie knechten: Dies kombiniert gestutzt und löschen Befehle mit sp_MSforeachtable so dass Sie vermeiden können, fallen und Einschränkungen neu zu erstellen - nur die Tabellen angeben, die nicht abgeschnittene gelöscht werden müssen, um und für meine Zwecke habe ich ein zusätzliches Schema enthalten Filter für eine gute Maßnahme (getestet in 2008r2)

declare @schema nvarchar(max) = 'and Schema_Id=Schema_id(''Value'')'
declare @deletiontables nvarchar(max) = '(''TableA'',''TableB'')'
declare @truncateclause nvarchar(max) = @schema + ' and o.Name not in ' +  + @deletiontables;
declare @deleteclause nvarchar(max) = @schema + ' and o.Name in ' + @deletiontables;        

exec sp_MSforeachtable 'alter table ? nocheck constraint all', @whereand=@schema
exec sp_MSforeachtable 'truncate table ?', @whereand=@truncateclause
exec sp_MSforeachtable 'delete from ?', @whereand=@deleteclause
exec sp_MSforeachtable 'alter table ? with check check constraint all', @whereand=@schema

Sie können vorübergehend Einschränkungen für Ihre Tabellen deaktivieren, tun die Arbeit, dann sie wieder aufzubauen.

Hier ist eine einfache Möglichkeit, es zu tun ...

Deaktivieren

alle Indizes, einschließlich der Primärschlüssel, die alle Fremdschlüssel deaktivieren, dann wieder aktivieren nur die Primärschlüssel, so dass Sie mit ihnen arbeiten ...

DECLARE @sql AS NVARCHAR(max)=''
select @sql = @sql +
    'ALTER INDEX ALL ON [' + t.[name] + '] DISABLE;'+CHAR(13)
from  
    sys.tables t
where type='u'

select @sql = @sql +
    'ALTER INDEX ' + i.[name] + ' ON [' + t.[name] + '] REBUILD;'+CHAR(13)
from  
    sys.key_constraints i
join
    sys.tables t on i.parent_object_id=t.object_id
where
    i.type='PK'


exec dbo.sp_executesql @sql;
go

[Tun Sie etwas, wie Ladevorgang]

Dann wieder aktivieren und wieder aufzubauen, die Indizes ...

DECLARE @sql AS NVARCHAR(max)=''
select @sql = @sql +
    'ALTER INDEX ALL ON [' + t.[name] + '] REBUILD;'+CHAR(13)
from  
    sys.tables t
where type='u'

exec dbo.sp_executesql @sql;
go

Ich habe eine nützlichere Version, wenn Sie interessiert sind. Ich hob ein Stück Code von hier aus einer Website, wo der Link nicht mehr aktiv ist. Ich modifyied es für eine Reihe von Tabellen in der gespeicherten Prozedur ermöglichen, und es füllt den Tropfen, gestutzt, fügen Sie Anweisungen vor allen von ihnen ausgeführt wird. Dies gibt Ihnen zu entscheiden, steuern, welche Tabellen müssen Kürzen.

/****** Object:  UserDefinedTableType [util].[typ_objects_for_managing]    Script Date: 03/04/2016 16:42:55 ******/
CREATE TYPE [util].[typ_objects_for_managing] AS TABLE(
    [schema] [sysname] NOT NULL,
    [object] [sysname] NOT NULL
)
GO

create procedure [util].[truncate_table_with_constraints]
@objects_for_managing util.typ_objects_for_managing readonly

--@schema sysname
--,@table sysname

as 
--select
--    @table = 'TABLE',
--    @schema = 'SCHEMA'

declare @exec_table as table (ordinal int identity (1,1), statement nvarchar(4000), primary key (ordinal));

--print '/*Drop Foreign Key Statements for ['+@schema+'].['+@table+']*/'

insert into @exec_table (statement)
select
          'ALTER TABLE ['+SCHEMA_NAME(o.schema_id)+'].['+ o.name+'] DROP CONSTRAINT ['+fk.name+']'
from sys.foreign_keys fk
inner join sys.objects o
          on fk.parent_object_id = o.object_id
where 
exists ( 
select * from @objects_for_managing chk 
where 
chk.[schema] = SCHEMA_NAME(o.schema_id)  
and 
chk.[object] = o.name
) 
;
          --o.name = @table and
          --SCHEMA_NAME(o.schema_id)  = @schema

insert into @exec_table (statement) 
select
'TRUNCATE TABLE ' + src.[schema] + '.' + src.[object] 
from @objects_for_managing src
; 

--print '/*Create Foreign Key Statements for ['+@schema+'].['+@table+']*/'
insert into @exec_table (statement)
select 'ALTER TABLE ['+SCHEMA_NAME(o.schema_id)+'].['+o.name+'] ADD CONSTRAINT ['+fk.name+'] FOREIGN KEY (['+c.name+']) 
REFERENCES ['+SCHEMA_NAME(refob.schema_id)+'].['+refob.name+'](['+refcol.name+'])'
from sys.foreign_key_columns fkc
inner join sys.foreign_keys fk
          on fkc.constraint_object_id = fk.object_id
inner join sys.objects o
          on fk.parent_object_id = o.object_id
inner join sys.columns c
          on      fkc.parent_column_id = c.column_id and
                   o.object_id = c.object_id
inner join sys.objects refob
          on fkc.referenced_object_id = refob.object_id
inner join sys.columns refcol
          on fkc.referenced_column_id = refcol.column_id and
                   fkc.referenced_object_id = refcol.object_id
where 
exists ( 
select * from @objects_for_managing chk 
where 
chk.[schema] = SCHEMA_NAME(o.schema_id)  
and 
chk.[object] = o.name
) 
;

          --o.name = @table and
          --SCHEMA_NAME(o.schema_id)  = @schema



declare @looper int , @total_records int, @sql_exec nvarchar(4000)

select @looper = 1, @total_records = count(*) from @exec_table; 

while @looper <= @total_records 
begin

select @sql_exec = (select statement from @exec_table where ordinal =@looper)
exec sp_executesql @sql_exec 
print @sql_exec 
set @looper = @looper + 1
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top