作为一名新手,我创造了一些没有明确名称的外键。
然后我创建了SQL生成的疯狂名称,如FK__Machines__IdArt__760D22A7
。猜猜它们将在不同的服务器上生成不同的名称。
有没有什么好的函数可以删除未命名的FK约束作为参数传递表和相关字段?
答案 0 :(得分:14)
要在列上删除单个未命名的默认约束,请使用以下代码:
DECLARE @ConstraintName VARCHAR(256)
SET @ConstraintName = (
SELECT obj.name
FROM sys.columns col
LEFT OUTER JOIN sys.objects obj
ON obj.object_id = col.default_object_id
AND obj.type = 'F'
WHERE col.object_id = OBJECT_ID('TableName')
AND obj.name IS NOT NULL
AND col.name = 'ColunmName'
)
IF(@ConstraintName IS NOT NULL)
BEGIN
EXEC ('ALTER TABLE [TableName] DROP CONSTRAINT ['+@ConstraintName+']')
END
如果您想为默认列执行此操作,这可能比原始问题更常见,我相信很多人会从Google搜索中找到这个,然后只需更改一行:
obj.type = 'F'
到
obj.type = 'D'
答案 1 :(得分:5)
没有内置的过程来完成此任务,但您可以使用information_schema视图中的信息构建自己的过程。
基于表格的示例
Create Proc dropFK(@TableName sysname)
as
Begin
Declare @FK sysname
Declare @SQL nvarchar(4000)
Declare crsFK cursor for
select tu.Constraint_Name from
information_schema.constraint_table_usage TU
LEFT JOIN SYSOBJECTS SO
ON TU.Constraint_NAME = SO.NAME
where xtype = 'F'
and Table_Name = @TableName
open crsFK
fetch next from crsFK into @FK
While (@@Fetch_Status = 0)
Begin
Set @SQL = 'Alter table ' + @TableName + ' Drop Constraint ' + @FK
Print 'Dropping ' + @FK
exec sp_executesql @SQL
fetch next from crsFK into @FK
End
Close crsFK
Deallocate crsFK
End
答案 2 :(得分:1)
这将允许您根据表名+列名
删除特定的外键约束在尝试了其他答案之后,我只是在系统表中捅了一下,直到找到了可能看起来的东西。
你想要的是Constraint_Column_Usage,根据文档Returns one row for each column in the current database that has a constraint defined on the column.
我已将它加入sys.objects以获取外键。
在一个程序中(这可以借鉴其他答案。欢呼的家伙!):
Create Proc yourSchema.dropFK(@SchemaName NVarChar(128), @TableName NVarChar(128), @ColumnName NVarChar(128))
as
Begin
DECLARE @ConstraintName nvarchar(128)
SET @ConstraintName = (
select c.Constraint_Name
from Information_Schema.Constraint_Column_usage c
left join sys.objects o
on o.name = c.Constraint_Name
where c.TABLE_SCHEMA = @SchemaName and
c.Table_name = @TableName and
c.Column_Name = @ColumnName and
o.type = 'F'
)
exec ('alter table [' + @SchemaName + '].[' + @TableName + '] drop constraint [' + @ConstraintName + ']')
End
答案 3 :(得分:0)
尽管如果您想删除实际的DEFAULT约束而不是FKey约束(这也是将ME带到这里的原因),Gunner的答案可以使人们走上正确的道路,但它存在问题。
我认为这可以解决所有问题。 (T-SQL)
CREATE PROC #DropDefaultConstraint @SchemaName sysname, @TableName sysname, @ColumnName sysname
AS
BEGIN
DECLARE @ConstraintName sysname;
SELECT @SchemaName = QUOTENAME(@SchemaName)
, @TableName = QUOTENAME(@TableName);
SELECT @ConstraintName = QUOTENAME(o.name)
FROM sys.columns c
JOIN sys.objects o
ON o.object_id = c.default_object_id
WHERE c.object_id = OBJECT_ID(@SchemaName+'.'+@TableName)
AND c.name = @ColumnName;
IF @ConstraintName IS NOT NULL
EXEC ('ALTER TABLE ' + @SchemaName + '.' + @TableName + ' DROP CONSTRAINT ' + @ConstraintName + '');
END
答案 4 :(得分:0)
这些都不适合我,所以我不得不想出这个来在12和14的mssql服务器版本上工作。
首先,检查RDBMS给FK赋予的名称,该名称具有相同的前缀和主体,但仅在后缀哈希上有所不同。
第二,选择这些约束的名称。
第三次exec alter命令将其删除。
最后,您可以删除被这些对象阻止的列或表
BEGIN TRANSACTION;
DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = name
FROM sys.objects
WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT'
AND name LIKE 'FK__table_col_shortcut1___%'
EXEC('ALTER TABLE table1 DROP CONSTRAINT ' + @ConstraintName)
SELECT @ConstraintName = name
FROM sys.objects
WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT'
AND name LIKE 'FK__table_col_shortcut2___%'
EXEC('ALTER TABLE table2 DROP CONSTRAINT ' + @ConstraintName)
SELECT @ConstraintName = name
FROM sys.objects
WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT'
AND name LIKE 'FK__table_col_shortcut3___%'
EXEC('ALTER TABLE table3 DROP CONSTRAINT ' + @ConstraintName)
DROP TABLE table_referenced;
COMMIT TRANSACTION;
经验教训,从现在开始,我将始终明确创建约束!
答案 5 :(得分:0)
这将生成一个脚本来重命名默认约束以使用模式 DF__table_name__column_name
SELECT 'EXEC sp_rename ''dbo.' + dc.name + ''', ''DF__' + t.name + '__' + c.name + '''' AS the_script,
t.name AS table_name,
c.name AS column_name,
dc.name AS old_constraint_name
FROM
sys.default_constraints dc
INNER JOIN sys.tables t
ON dc.parent_object_id = t.object_id
INNER JOIN sys.columns c
ON dc.parent_column_id = c.column_id
AND t.object_id = c.object_id
WHERE
dc.name <> 'DF__' + t.name + '__' + c.name