Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.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
C# Visual Studio SQL数据库,执行批处理时出错(消息1785)_C#_Sql_Sql Server_Asp.net Mvc_Visual Studio - Fatal编程技术网

C# Visual Studio SQL数据库,执行批处理时出错(消息1785)

C# Visual Studio SQL数据库,执行批处理时出错(消息1785),c#,sql,sql-server,asp.net-mvc,visual-studio,C#,Sql,Sql Server,Asp.net Mvc,Visual Studio,我已在MS visual studio项目的基于服务的数据库(Microsoft SQL)中创建了下表: CREATE TABLE [dbo].[users] ( [phone_number] VARCHAR (50) NOT NULL, [name] VARCHAR (50) NOT NULL, [picture] VARCHAR (50) NOT NULL, [password] VARCHAR (50) NOT NULL, CONST

我已在MS visual studio项目的基于服务的数据库(Microsoft SQL)中创建了下表:

CREATE TABLE [dbo].[users] (
    [phone_number]   VARCHAR (50) NOT NULL,
    [name]     VARCHAR (50) NOT NULL,
    [picture]  VARCHAR (50) NOT NULL,
    [password] VARCHAR (50) NOT NULL, 
    CONSTRAINT [PK_users] PRIMARY KEY ([phone_number])
);
之后,当我尝试添加下表时,我得到了错误:

执行批处理时出错

创建更新脚本时不会出现警告,数据库中也没有数据。我尝试从头开始重新创建所有内容,但错误仍然存在。我可能做错了什么


编辑:如果我从任何一个外键约束中删除“删除级联”和“更新级联”,则错误消失,在任何其他组合中删除都没有帮助。这些约束有什么问题吗?

我在SSMS中执行代码时遇到了这个错误。我做了一个快速搜索,有很多关于这个主题的信息供你研究

Msg 1785,16级,状态0,第2行引入外键约束 表“位置”上的“FK_2”可能导致循环或多个级联路径。 指定在删除时不执行操作或在更新时不执行操作,或修改其他 外键约束。Msg 1750,16级,状态0,第2行无法访问 创建约束或索引。请参阅前面的错误

根据聊天记录编辑:

我认为,基于您删除该位置的愿望,最好您这样做。保持FK的完整性,并可能创建一个存储过程来删除用户

  • 开始交易
  • 从发送者=用户ID或接收者=用户ID(或电话号码,如果您坚持使用该PK)的位置删除
  • 从用户表中删除
  • 提交事务

  • 给出了MSDN上关于

    您收到此错误消息是因为在SQL Server中,表不能 在所有级联引用的列表中多次出现 由DELETE或UPDATE语句启动的操作。 例如,级联引用操作树必须只有 级联引用操作上特定表的一条路径 树

    以及他们声明的解决方法

    您可以通过几种方式强制引用完整性。声明的 引用完整性(DRI)是最基本的方法,但它也是 最不灵活的方式。如果你需要更多的灵活性,但你仍然想要一个 高度的完整性,您可以使用触发器

    我们可以选择以这种方式创建触发器来避免这个问题

    ALTER  TRIGGER [dbo].[CascadeDeleteNumber]
       ON  [dbo].[users]
       INSTEAD OF DELETE
    AS 
    BEGIN
        SET NOCOUNT ON;
    
        DELETE FROM location WHERE Sender = (select phone_number from deleted)
        DELETE FROM location WHERE Reciever = (select phone_number from deleted)
        DELETE FROM users WHERE phone_number = (select phone_number from deleted)
    
    END
    
    DELETE触发器是一个而不是,因为AFTER触发器从未被引用完整性检查阻止执行。取而代之允许我们先删除位置表中的记录,然后删除用户表中的记录,从而保留引用完整性

    对于更新,我们可以使用另一个触发器,但这更棘手。
    我没有找到在不破坏引用完整性的情况下正确更新电话号码的方法,因此我设法临时更改电话号码,删除引用完整性,更新所需记录,然后恢复引用完整性

    ALTER TRIGGER [dbo].[CascadeUpdateNumber]
       ON  [dbo].[users]
       INSTEAD OF UPDATE
    AS 
    BEGIN
        SET NOCOUNT ON;
        DECLARE @old_num nvarchar(50)
        DECLARE @new_num nvarchar(50)
        DECLARE @new_name varchar(50)
        DECLARE @new_img varchar(50)
        DECLARE @new_pwd varchar(50)
        SELECT @old_num = phone_number FROM deleted
        SELECT @new_num = phone_number, @new_name = name, @new_img = picture,
               @new_pwd = password FROM inserted
    
    
    ALTER TABLE [dbo].[location] DROP CONSTRAINT [FK_1]
    ALTER TABLE [dbo].[location] DROP CONSTRAINT [FK_2]
    
        UPDATE location SET sender = @new_num WHERE sender = @old_num
        UPDATE location SET reciever = @new_num WHERE reciever = @old_num
        UPDATE users SET phone_number = @new_num, name = @new_name, 
                     picture=@new_img, password=@new_pwd 
                     WHERE phone_number = @old_num
    
    ALTER TABLE [dbo].[location]  WITH CHECK 
           ADD  CONSTRAINT [FK_3] FOREIGN KEY([sender])
                REFERENCES [dbo].[users] ([phone_number])
    
    ALTER TABLE [dbo].[location]  WITH CHECK 
           ADD  CONSTRAINT [FK_4] FOREIGN KEY([reciever])
                REFERENCES [dbo].[users] ([phone_number])
    
    END
    

    老实说,从表上并发更新的角度来看,我不知道这种方法是否安全

    数字是非常糟糕的列名…所以发送方和接收方对于数字列都是FK?你是说名字吗?@jarlh:对不起,这个号码是用来存储电话号码的。@Steve:不,我的意思和我现在使用的完全一样,意思是一个电话号码可以是发送者,另一个可以是接收者,他们的发送关系或记录保存在位置表中。我感谢你的关注,你能详细说明一下在哪种情况下它会导致循环吗?我没有读太多,但在我看来,因为两个外键都指向同一个表中的同一个字段,所以可能会有冲突。例如,如果删除用户,位置记录将被删除。如果指定两次,将尝试两次删除相同的记录。通常,FK指向主键,并且只引用一次。我不清楚你设计的意图,链接到电话号码。我明白你的意思,那么,维护从phone_number_1发送到phone_number_2的消息的最佳模式是什么,以便在父表中删除或更新这两个消息时自动更新或删除它们。就我个人而言,我不会让发件人和收件人字段填充电话号码。它们只是与用户表上的ID相关的整数。您只需要对其中一个外键进行约束,删除用户将删除位置。即使我使用int id并将其用作FK而不是电话号码,则不需要更新cascade,但仍然需要删除cascade。如果我在其中一个外键上使用on delete cascade,比如sender,那么如果从用户表中删除了接收方,那又怎么样?啊哈!我将这个问题解释为反向级联(位置上的触发器级联到用户)。那会有点混乱;)@Steve:如果我使用trigger,那么我必须删除外键约束,就像添加trigger之后一样,当我尝试删除或更新父表中的主键时,它会显示错误。我不想删除外键约束,因为它会导致数据不一致。如何通过触发器确保数据一致性?我明白了,需要将触发器更改为而不是。更新部分很棘手,我不确定这在非常高的并发性场景中是否安全,但它也适用于引用。更新
    ALTER TRIGGER [dbo].[CascadeUpdateNumber]
       ON  [dbo].[users]
       INSTEAD OF UPDATE
    AS 
    BEGIN
        SET NOCOUNT ON;
        DECLARE @old_num nvarchar(50)
        DECLARE @new_num nvarchar(50)
        DECLARE @new_name varchar(50)
        DECLARE @new_img varchar(50)
        DECLARE @new_pwd varchar(50)
        SELECT @old_num = phone_number FROM deleted
        SELECT @new_num = phone_number, @new_name = name, @new_img = picture,
               @new_pwd = password FROM inserted
    
    
    ALTER TABLE [dbo].[location] DROP CONSTRAINT [FK_1]
    ALTER TABLE [dbo].[location] DROP CONSTRAINT [FK_2]
    
        UPDATE location SET sender = @new_num WHERE sender = @old_num
        UPDATE location SET reciever = @new_num WHERE reciever = @old_num
        UPDATE users SET phone_number = @new_num, name = @new_name, 
                     picture=@new_img, password=@new_pwd 
                     WHERE phone_number = @old_num
    
    ALTER TABLE [dbo].[location]  WITH CHECK 
           ADD  CONSTRAINT [FK_3] FOREIGN KEY([sender])
                REFERENCES [dbo].[users] ([phone_number])
    
    ALTER TABLE [dbo].[location]  WITH CHECK 
           ADD  CONSTRAINT [FK_4] FOREIGN KEY([reciever])
                REFERENCES [dbo].[users] ([phone_number])
    
    END