Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.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 当发生集成引用时,是否可以忽略插入,但插入其他记录?_Sql Server_Tsql_Insert_Ado.net - Fatal编程技术网

Sql server 当发生集成引用时,是否可以忽略插入,但插入其他记录?

Sql server 当发生集成引用时,是否可以忽略插入,但插入其他记录?,sql-server,tsql,insert,ado.net,Sql Server,Tsql,Insert,Ado.net,我在两个表之间有一个N:N关系,所以我有一个链接表来连接它们。此链接表的主键是两个表的两个主键的组合。这是最基本的 我想关联许多记录,因此在我的应用程序中,我使用循环创建如下命令: begin transaction insert into MyMiddleTable(ID1, ID2) VALUES(1, 2); insert into MyMiddleTable(ID1, ID2) VALUES(1, 3); ... commit; 但是如果我想关联的一个记录被事务中间的其他进程删除,那么

我在两个表之间有一个N:N关系,所以我有一个链接表来连接它们。此链接表的主键是两个表的两个主键的组合。这是最基本的

我想关联许多记录,因此在我的应用程序中,我使用循环创建如下命令:

begin transaction
insert into MyMiddleTable(ID1, ID2) VALUES(1, 2);
insert into MyMiddleTable(ID1, ID2) VALUES(1, 3);
...
commit;

但是如果我想关联的一个记录被事务中间的其他进程删除,那么我会得到一个引用完整性的错误,这是可以的,但是它不会创建任何其他可以创建的其他关系,因为存在其他记录。 因此,我的问题是,如果有某种方式可以告诉SQL Server,这种引用完整性发生在一对寄存器上,请忽略,然后继续下一个,并创建所有可以创建的关系。因为如果一条记录因为被删除而不存在,我不会创建这个关系,而是创建我想要的其他记录

前例,当我试图删除在进程中间删除的关系时,SQLServer通知此事件,但继续并删除其余的关系。的确,在我的代码中,如果delete不在事务中,但我尝试在没有事务的情况下进行插入,问题仍然存在

我知道另一种解决方案是用一个提示表阻塞两个主表,但我希望避免为创建此关系而阻塞两个表


谢谢。

您不能在事务中包装整个内容:

开始交易

承诺


您明确地告诉SQL,如果其中任何一个出现故障,它就会失败。当您说问题不在事务中时仍然存在时,您是从哪个程序执行此SQL的?如果您在SSMS中,您可能需要用GO或其他东西来分隔每条语句,否则您可能会得到仍然包含所有语句的隐式事务。

这里需要做的是删除该循环过程,并使用基于集合的方法将记录作为一个事务的一部分提交到链接表。这里没有足够的信息来提供具体的逻辑,但这里有一个例子

请注意,DISTINCT用于防止重复插入,而LEFT JOIN用于从插入集中删除现有值

IF OBJECT_ID('LeftTable') IS NOT NULL DROP TABLE LeftTable
IF OBJECT_ID('RightTable') IS NOT NULL DROP TABLE RightTable
IF OBJECT_ID('BridgeTable') IS NOT NULL DROP TABLE BridgeTable
CREATE TABLE LeftTable (LeftID INT IDENTITY NOT NULL, LeftValue UNIQUEIDENTIFIER);
CREATE TABLE RightTable (RightID INT IDENTITY NOT NULL, RightValue UNIQUEIDENTIFIER);
CREATE TABLE BridgeTable (LeftID INT NOT NULL, RightID INT NOT NULL);

ALTER TABLE BridgeTable ADD CONSTRAINT [PK_BridgeTable_LeftIDRightID] PRIMARY KEY CLUSTERED ([LeftID], [RightID]);

WHILE (SELECT COUNT(*) FROM LeftTable) < 100
INSERT INTO LeftTable (LeftValue) SELECT NEWID()

WHILE (SELECT COUNT(*) FROM RightTable) < 100
INSERT INTO RightTable (RightValue) SELECT NEWID()

--Replace with actual matching logic
;WITH cteJoinSet AS (
    SELECT DISTINCT L.LeftID, R.RightID
    FROM LeftTable L
    CROSS JOIN RightTable R
)

INSERT INTO BridgeTable (LeftID, RightID)
SELECT J.LeftID, J.RightID
FROM cteJoinSet J
LEFT JOIN BridgeTable B ON B.LeftID = J.LeftID
    AND B.RightID = J.RightID
WHERE B.LeftID IS NULL
IF OBJECT_ID('LeftTable') IS NOT NULL DROP TABLE LeftTable
IF OBJECT_ID('RightTable') IS NOT NULL DROP TABLE RightTable
IF OBJECT_ID('BridgeTable') IS NOT NULL DROP TABLE BridgeTable
CREATE TABLE LeftTable (LeftID INT IDENTITY NOT NULL, LeftValue UNIQUEIDENTIFIER);
CREATE TABLE RightTable (RightID INT IDENTITY NOT NULL, RightValue UNIQUEIDENTIFIER);
CREATE TABLE BridgeTable (LeftID INT NOT NULL, RightID INT NOT NULL);

ALTER TABLE BridgeTable ADD CONSTRAINT [PK_BridgeTable_LeftIDRightID] PRIMARY KEY CLUSTERED ([LeftID], [RightID]);

WHILE (SELECT COUNT(*) FROM LeftTable) < 100
INSERT INTO LeftTable (LeftValue) SELECT NEWID()

WHILE (SELECT COUNT(*) FROM RightTable) < 100
INSERT INTO RightTable (RightValue) SELECT NEWID()

--Replace with actual matching logic
;WITH cteJoinSet AS (
    SELECT DISTINCT L.LeftID, R.RightID
    FROM LeftTable L
    CROSS JOIN RightTable R
)

INSERT INTO BridgeTable (LeftID, RightID)
SELECT J.LeftID, J.RightID
FROM cteJoinSet J
LEFT JOIN BridgeTable B ON B.LeftID = J.LeftID
    AND B.RightID = J.RightID
WHERE B.LeftID IS NULL