Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server MS SQL更改所有约束_Sql Server_Foreign Keys_Constraints - Fatal编程技术网

Sql server MS SQL更改所有约束

Sql server MS SQL更改所有约束,sql-server,foreign-keys,constraints,Sql Server,Foreign Keys,Constraints,为了更改MS SQL中的约束,通常会删除旧约束并添加具有所需属性的新约束,如: alter table MY_TABLE drop constraint [MY_CONSTRAINT] go alter table MY_TABLE add constraint [MY_CONSTRAINT] foreign key (FK_TABLE_2) references TABLE_2 on delete set null --or w

为了更改MS SQL中的约束,通常会删除旧约束并添加具有所需属性的新约束,如:

alter table MY_TABLE drop constraint [MY_CONSTRAINT]
go

alter table MY_TABLE
    add constraint [MY_CONSTRAINT]
        foreign key (FK_TABLE_2) references TABLE_2
            on delete set null
        --or whatever property we want to change
go

但是,我想更改数据库中的所有约束。更具体地说,我希望所有外键约束都将delete规则
设置为null
。这样做可能吗?

我不知道有什么东西可以一次完成所有的工作,但这里有一个select语句可以让您获得一些时间:

SELECT 'ALTER TABLE [' + o1.name + '] DROP CONSTRAINT [' + fk.name + ']' AS DROP_STATEMENT
    ,   'ALTER TABLE [' + o1.name +'] ADD CONSTRAINT [' + fk.name + '] FOREIGN KEY ([' + c.name + ']) REFERENCES [' + o2.name + '] ON DELETE SET NULL' AS CREATE_STATEMENT
FROM sys.foreign_keys fk
    INNER JOIN sys.objects o1 ON fk.parent_object_id = o1.object_id
    INNER JOIN sys.objects o2 ON fk.referenced_object_id = o2.object_id
    INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.columns c ON c.object_id = o2.object_id AND c.column_id = fkc.referenced_column_id

正如评论中指出的,当fk引用两个或更多列时,这根本不起作用。然而,我不认为我可以很容易地适应这个查询,我不知道它对你的价值是什么;我不会的。请记住这一点。

我不知道有什么东西可以一次完成所有工作,但这里有一个select语句,它可能会让您赢得一些时间:

SELECT 'ALTER TABLE [' + o1.name + '] DROP CONSTRAINT [' + fk.name + ']' AS DROP_STATEMENT
    ,   'ALTER TABLE [' + o1.name +'] ADD CONSTRAINT [' + fk.name + '] FOREIGN KEY ([' + c.name + ']) REFERENCES [' + o2.name + '] ON DELETE SET NULL' AS CREATE_STATEMENT
FROM sys.foreign_keys fk
    INNER JOIN sys.objects o1 ON fk.parent_object_id = o1.object_id
    INNER JOIN sys.objects o2 ON fk.referenced_object_id = o2.object_id
    INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.columns c ON c.object_id = o2.object_id AND c.column_id = fkc.referenced_column_id

正如评论中指出的,当fk引用两个或更多列时,这根本不起作用。然而,我不认为我可以很容易地适应这个查询,我不知道它对你的价值是什么;我不会的。请记住这一点。

如果我想这样做,我会使用Powershell/SMO。大概是这样的:

import-module sqlps;

$scriptDrop = new-object microsoft.sqlserver.management.smo.scriptingoptions;
$scriptDrop.ScriptDrops = $true;
$s = new-object microsoft.sqlserver.management.smo.server '.';
$db = $s.Databases['yourDatabase'];
foreach ($table in $db.Tables) {
  foreach ($fk in $table.ForeignKeys) {
    $fk.DeleteAction = 'SetNull';
    $fk.Script($scriptDrop);
    $fk.Script();
  }
}

这将生成一个脚本,该脚本将删除并随后使用所需属性重新创建外键。

如果我想这样做,我会使用Powershell/SMO。大概是这样的:

import-module sqlps;

$scriptDrop = new-object microsoft.sqlserver.management.smo.scriptingoptions;
$scriptDrop.ScriptDrops = $true;
$s = new-object microsoft.sqlserver.management.smo.server '.';
$db = $s.Databases['yourDatabase'];
foreach ($table in $db.Tables) {
  foreach ($fk in $table.ForeignKeys) {
    $fk.DeleteAction = 'SetNull';
    $fk.Script($scriptDrop);
    $fk.Script();
  }
}

这将生成一个脚本,该脚本将删除并随后重新创建具有所需属性的外键。

这可能会让您感到震惊,但并非所有外键都只涉及一列。
JOIN
to
foreign\u key\u columns
可能会为单个FK返回多行,然后生成的输出将非常错误。这可能会让您感到震惊,但并非所有外键都只涉及一列。
JOIN
to
foreign\u key\u列
可能会为单个FK返回多行,然后生成的输出将非常错误。