SQL Server:如何知道是否有任何行引用要删除的行

如何解决SQL Server:如何知道是否有任何行引用要删除的行

|| 如果有任何行引用要通过FK删除的行,则无法删除该行。 在执行DELETE语句之前是否可以知道是否有任何行在引用要删除的行?     

解决方法

        此脚本将显示所有具有引用您要删除的行的行的表:
declare @RowId int = 1
declare @TableName sysname = \'ParentTable\'

declare @Command varchar(max) 

select @Command = isnull(@Command + \' union all \',\'\') + \'select \'\'\' + object_name(parent_object_id) + 
    \'\'\' where exists(select * from \' + object_name(parent_object_id) + \' where \' + col.name+ \' = \' + cast(@RowId as varchar) + \')\' 
from sys.foreign_key_columns fkc
    join sys.columns col on
        fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
where object_name(referenced_object_id) = @TableName

execute (@Command)
假定外键不是复合键。     ,        选项1(检测): 您执行ѭ1来确定是否有任何记录在引用要删除的记录-并根据需要手动删除那些引用了该记录的记录。尽管我建议不要使用触发器,但是也可以使用触发器来实现,因为它们会给人(和您自己)带来惊喜。 选项2(自动化): 您可以查看级联删除,如果配置正确,则会导致所有引用要删除的记录的记录也被删除。 何时使用级联删除(摘自Joel Coehoorn撰写的文本) 当关系的语义可以包含“是”描述时,级联删除可能很有意义。示例:网络订单,网络订单行项目 如果要保留历史记录或在仅设置已删除位列的情况下使用软删除,则不应使用级联删除 如果您错误地设置了外键,级联会给您带来麻烦。 在完全了解层叠之前,使用层叠是不明智的。但是,它是一个有用的功能,因此值得花一些时间来理解。 这是关于stackoverflow上级联删除的精彩讨论。     ,        没有人提到它,但是为了记录,我使用了很多程序
sp_helpconstraint \'dbo.mytable\'
为了找到与dbo.mytable相关的所有约束,哪些表引用dbo.mytable。 我觉得它非常有用和方便。     ,        我改进了Alex Aza的解决方案。 我使用softdelete,因此有必要在条件“ where”中添加列“ delete”。 另外,我在TSQL中创建了一个函数,该函数可以发现表何时表示NHibernate中继承的对象,而PK是父表中的FK。 跟随:
declare @RowId int = 4
declare @TableName sysname = \'TABLE\'

declare @Command varchar(max) 

select @Command = isnull(@Command + \' union all \',\'\') + \'select \'\'\' + object_name(parent_object_id) + 
    \'\'\' where exists(select * from \' + object_name(parent_object_id) + 
    CASE
        WHEN EXISTS(select object_name(object_id) from sys.columns col where name = \'deleted\' and object_id = parent_object_id) 
            THEN \' where \' + col.name+ \' = \' + cast(@RowId as varchar) +\' and deleted = 0 \'
        when dbo.ParentIdFromTable(object_name(parent_object_id)) <> \'\'
            then \' inner join \' + dbo.ParentIdFromTable(object_name(parent_object_id)) + \' on id = \' + dbo.PrimaryKey(object_name(parent_object_id))
                +\' where \' + col.name+ \' = \' + cast(@RowId as varchar) +\' and deleted = 0 \'
        else 
            \' where \' + col.name+ \' = \' + cast(@RowId as varchar) 
      END
    + \')\' 
from sys.foreign_key_columns fkc
    join sys.columns col on
        fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
where object_name(referenced_object_id) = @TableName

PRINT @Command
execute (@Command)
功能:
CREATE FUNCTION dbo.ParentIdFromTable(@Table varchar(255))
RETURNS varchar(255) 
AS 
BEGIN
    declare @tableParent varchar(255) = \'\'

    if exists(select pk.TABLE_NAME,pk.COLUMN_NAME,col.name,object_name(referenced_object_id) Referenced,object_name(parent_object_id) as Parent
        from sys.columns col
            inner join sys.foreign_key_columns fkc on
                fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
            inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk on
                pk.TABLE_NAME = object_name(object_id) and pk.COLUMN_NAME = col.name
        WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name),\'IsPrimaryKey\') = 1
        AND table_name = @table)
    begin

        while exists(select *
            from sys.columns col
            inner join sys.foreign_key_columns fkc on
                fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
            inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk on
                pk.TABLE_NAME = object_name(object_id) and pk.COLUMN_NAME = col.name
            WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name),\'IsPrimaryKey\') = 1 AND table_name = @table)
        begin
            -- Descobrir o parent,column
            select  @tableParent = object_name(referenced_object_id)
            from sys.columns col
            inner join sys.foreign_key_columns fkc on
                fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
            inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk on
                pk.TABLE_NAME = object_name(object_id) and pk.COLUMN_NAME = col.name
            WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name),\'IsPrimaryKey\') = 1
            AND table_name = @table

            --print @tableParent
            set @table = @tableParent
        end
    end

    return @tableParent;
END;
GO


CREATE FUNCTION dbo.PrimaryKey(@Table varchar(255))
RETURNS varchar(255) 
AS 
BEGIN
    declare @columnName varchar(255) = \'\'
    -- Descobrir o parent,column
    select @columnName = COLUMN_NAME
    from INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
    WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name),\'IsPrimaryKey\') = 1
    AND table_name = @Table

    return @columnName
end;
    

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?