【问题标题】:Drop foreign key without knowing the name of the constraint?在不知道约束名称的情况下删除外键?
【发布时间】:2023-03-10 03:12:01
【问题描述】:

我使用以下命令创建了一张表:

create table Table1(
    Id int Not Null 
        Foreign key 
        references Table2(Id)  
        on delete cascade 
        on update cascade,
    UserName nvarchar(150),
    TimeInSeconds int Not Null 

    primary key(Id,TimeInSeconds)
);

但现在我想删除外键。 由于我没有给出约束名称,所以我不能使用:

Alter table <tablename>
drop foreign key <foreign key name>

有什么办法吗?

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    你可以在INFORMATION_SCHEMA.TABLE_CONSTRAINTS找到约束的名字

    select CONSTRAINT_NAME
    from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    where TABLE_NAME = 'Table1'
    

    【讨论】:

    • +1。快速绘制。我打算:select * from syscontraints where xtype = 'F' and name like '%table1%'
    • 除非您在脚本中执行此操作以发布到应该具有相同架构的多个数据库,因此约束的名称在数据库的每个实例上可能不同?在这种情况下,这将不起作用。
    • @Peter,理想情况下你会命名约束,但如果你不这样做,你仍然可以在脚本运行时获取名称。没发现问题。
    • 彼得的问题我们有答案了吗?我正在尝试做这样的事情:ALTER TABLE ef_jobpremium DROP CONSTRAINT 。希望我很清楚,我试图在一次执行中做到这一点。
    • 这给出了所有的约束名称。如何获取特定字段的约束名称?
    【解决方案2】:

    类似于 Ed 的答案,但您可以使用它来根据表和列名选择键名。

    这样你可以在脚本中运行它,或者作为子查询来删除约束。

    SELECT CONSTRAINT_NAME
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    WHERE TABLE_NAME =  'post'
    AND COLUMN_NAME =  'userID'
    

    【讨论】:

    • 里面有 2 个。我必须得到这个position_in_unique_constraint IS NOT NULL
    【解决方案3】:

    因为我遇到了一些问题,所以扩展了答案。另外,我声明了 2 个外键,所以我添加了一个可选键来保留,如果它为 null,它将被忽略:

    declare @name varchar(255),
         @table varchar(255) = 'mytable',
         @column varchar(255) = 'mykeycolumn',
         @validkey varchar(255) =  'mykeyIwanttokeep'
    
    SELECT @name = CONSTRAINT_NAME
    FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
    WHERE TABLE_NAME = @table
        AND COLUMN_NAME =  @column
        AND (CONSTRAINT_NAME != @validkey or @validkey is null)
    
    declare @sql varchar(1023) = 'alter table ' + @table + ' drop ' + @name 
    
    exec (@sql)
    

    【讨论】:

    • AND COLUMN_NAME = @column
    • 加一个用于完整地回答问题。其他人都错过了实际下降的部分,SQL Server 不允许参数化。
    【解决方案4】:

    SQL Server 选项:

    DECLARE @foreignkey varchar(100)
    DECLARE @tablename varchar(100)
    DECLARE @command nvarchar(1000)
    
    DECLARE db_cursor CURSOR FOR
    SELECT fk.name, t.name
    FROM sys.foreign_keys fk
    JOIN sys.tables t ON t.object_id = fk.parent_object_id
    WHERE t.name IN (
        'table_1_name_here',
        'table_2_name_here'
    )
    
    OPEN db_cursor
    FETCH NEXT FROM db_cursor INTO @foreignkey, @tablename
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SELECT @command = 'ALTER TABLE ' + @tablename + ' DROP CONSTRAINT ' + @foreignkey
        EXECUTE(@command)
        FETCH NEXT FROM db_cursor INTO @foreignkey, @tablename
    END
    CLOSE db_cursor
    DEALLOCATE db_cursor
    

    SQL 将您关心的表的所有约束选择到游标中,并一一删除。您只需要知道要从中删除它们的表的名称。

    【讨论】:

      【解决方案5】:

      要删除外键,请使用以下命令:

      1. SHOW CREATE TABLE table_name;
      2. ALTER TABLE table_name DROP FOREIGN KEY table_name_ibfk_3; (“table_name_ibfk_3”是为未命名约束分配的约束外键名称)。它因人而异。
      3. ALTER TABLE table_name DROP column_name.

      【讨论】:

      • 它通常以 table_name_ibfk_1 开头,然后是 table_name_ibfk_2,依此类推
      【解决方案6】:

      如果您只查看企业管理器/管理工作室中的表格,您将能够看到密钥列表并将其从那里删除。

      【讨论】:

        【解决方案7】:

        没关系,下面是 Postgres 语法。如果问题的标题中有sql server会更好,因为我没有注意到标签

        您还可以使用cascade 删除并重新添加父表上的主键。这将删除引用该表的所有外键,而您无需知道外键名称。

        ALTER TABLE parent_table
        DROP CONSTRAINT 'pk_id' CASCADE
        
        -- add back pk
        ALTER TABLE parent_table
        ADD CONSTRAINT 'pk_id' PRIMARY KEY (id)
        

        警告:您需要先检查所有依赖项,如果还有其他表,则需要重新添加它们的外键。这确实允许您在添加外键时正确命名它们。由于阻塞事务,这种方法在高事务系统中也可能不可行。

        【讨论】:

          【解决方案8】:

          你可以说:

          > show create table tablename;

          您将看到如何创建表...列、类型...等。你可以看到你的约束名称。

          【讨论】:

          • SHOW CREATE TABLE tablename; 是 MySQL 特定的命令。这个问题是关于 Microsoft SQL Sever,完全不同的产品。
          猜你喜欢
          • 1970-01-01
          • 2011-04-26
          • 2012-02-18
          • 1970-01-01
          • 2010-11-28
          • 2015-03-22
          • 1970-01-01
          • 2021-01-05
          • 2013-08-06
          相关资源
          最近更新 更多