Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Nonaktifkan sementara semua batasan kunci asing

Untuk menonaktifkan batasan kunci asing:

DECLARE @sql NVARCHAR(MAX) = N'';

;WITH x AS 
(
  SELECT DISTINCT obj = 
      QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' 
    + QUOTENAME(OBJECT_NAME(parent_object_id)) 
  FROM sys.foreign_keys
)
SELECT @sql += N'ALTER TABLE ' + obj + ' NOCHECK CONSTRAINT ALL;
' FROM x;

EXEC sp_executesql @sql;

Untuk mengaktifkan kembali:

DECLARE @sql NVARCHAR(MAX) = N'';

;WITH x AS 
(
  SELECT DISTINCT obj = 
      QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' 
    + QUOTENAME(OBJECT_NAME(parent_object_id)) 
  FROM sys.foreign_keys
)
SELECT @sql += N'ALTER TABLE ' + obj + ' WITH CHECK CHECK CONSTRAINT ALL;
' FROM x;

EXEC sp_executesql @sql;

Namun, Anda tidak akan dapat memotong tabel, Anda harus menghapusnya dalam urutan yang benar. Jika Anda perlu memotong mereka, Anda harus menghilangkan batasan sepenuhnya, dan membuatnya kembali. Ini mudah dilakukan jika batasan kunci asing Anda semuanya sederhana, batasan kolom tunggal, tetapi pasti lebih kompleks jika ada banyak kolom yang terlibat.

Berikut adalah sesuatu yang dapat Anda coba. Untuk menjadikan ini bagian dari paket SSIS Anda, Anda memerlukan tempat untuk menyimpan definisi FK saat paket SSIS berjalan (Anda tidak akan dapat melakukan ini semua dalam satu skrip). Jadi di beberapa database utilitas, buat tabel:

CREATE TABLE dbo.PostCommand(cmd NVARCHAR(MAX));

Kemudian di database Anda, Anda dapat memiliki prosedur tersimpan yang melakukan ini:

DELETE other_database.dbo.PostCommand;

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id))
   + '.' + QUOTENAME(OBJECT_NAME(fk.parent_object_id)) 
   + ' ADD CONSTRAINT ' + fk.name + ' FOREIGN KEY (' 
   + STUFF((SELECT ',' + c.name
    FROM sys.columns AS c 
        INNER JOIN sys.foreign_key_columns AS fkc 
        ON fkc.parent_column_id = c.column_id
        AND fkc.parent_object_id = c.[object_id]
    WHERE fkc.constraint_object_id = fk.[object_id]
    ORDER BY fkc.constraint_column_id 
    FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '')
+ ') REFERENCES ' + 
QUOTENAME(OBJECT_SCHEMA_NAME(fk.referenced_object_id))
+ '.' + QUOTENAME(OBJECT_NAME(fk.referenced_object_id))
+ '(' + 
STUFF((SELECT ',' + c.name
    FROM sys.columns AS c 
        INNER JOIN sys.foreign_key_columns AS fkc 
        ON fkc.referenced_column_id = c.column_id
        AND fkc.referenced_object_id = c.[object_id]
    WHERE fkc.constraint_object_id = fk.[object_id]
    ORDER BY fkc.constraint_column_id 
    FOR XML PATH(''), TYPE).value('.', 'nvarchar(max)'), 1, 1, '') + ');
' FROM sys.foreign_keys AS fk
WHERE OBJECTPROPERTY(parent_object_id, 'IsMsShipped') = 0;

INSERT other_database.dbo.PostCommand(cmd) SELECT @sql;

IF @@ROWCOUNT = 1
BEGIN
  SET @sql = N'';

  SELECT @sql += N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(fk.parent_object_id))
    + '.' + QUOTENAME(OBJECT_NAME(fk.parent_object_id)) 
    + ' DROP CONSTRAINT ' + fk.name + ';
  ' FROM sys.foreign_keys AS fk;

  EXEC sp_executesql @sql;
END

Sekarang ketika paket SSIS Anda selesai, ia akan memanggil prosedur tersimpan yang berbeda, yaitu:

DECLARE @sql NVARCHAR(MAX);

SELECT @sql = cmd FROM other_database.dbo.PostCommand;

EXEC sp_executesql @sql;

Jika Anda melakukan semua ini hanya demi dapat memotong alih-alih menghapus, saya sarankan hanya mengambil hit dan menjalankan penghapusan. Mungkin menggunakan model pemulihan yang dicatat secara massal untuk meminimalkan dampak dari log. Secara umum saya tidak melihat bagaimana solusi ini akan jauh lebih cepat daripada hanya menggunakan penghapusan dalam urutan yang benar.

Pada tahun 2014 saya menerbitkan posting yang lebih rumit tentang ini di sini:

  • Lepaskan dan Buat Ulang Semua Batasan Kunci Asing di SQL Server


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tambahkan Akun Email Database ke Profil (SSMS)

  2. Cara melihat log transaksi di SQL Server 2008

  3. Peningkatan identitas melompat di database SQL Server

  4. Solusi Untuk Cara Membaca File Log Transaksi SQL Server Tanpa Gagal

  5. Cara Mengubah Kolom dari Null menjadi Tidak Null di Tabel SQL Server - Tutorial SQL Server / T-SQL Part 52