ALTER TRIGGER t1
ON dbo.Customers
FOR INSERT
AS
BEGIN TRANSACTION
/* variables */
DECLARE
@maxid bigint
SELECT @customerid = id FROM inserted
SET IDENTITY_INSERT dbo.new_table ON
DECLARE
@maxid bigint
SELECT @maxid = MAX(ID) FROM new_table
INSERT INTO new_table (ID, ParentID, Foo, Bar, Buzz)
SELECT ID+@maxid, ParentID+@maxid, Foo, Bar, Buzz FROM initial_table
SET IDENTITY_INSERT dbo.new_tableOFF
/* execute */
COMMIT TRANSACTION
GO
失败了:
SQL Server子查询返回的值超过1。这是不允许的 当子查询跟随=,!=,<,< =,>,> =或子查询是 用作表达式
如何解决?
我想做的是
id
和parentid
,每次增加@maxid
initial_table
new_table
日Thnx
NEW_TABLE
id (bigint)
parentid (bigint - linked to id)
foo | bar | buzz (others are nvarchar, not really important)
初始表
id (bigint)
parentid (bigint - linked to id)
foo | bar | buzz (others are nvarchar, not really important)
答案 0 :(得分:3)
你正在与我怀疑的一些错误作斗争。
1。 您正在插入违反new_table中唯一约束的值。 通过加入要插入的表来避免存在错误。调整连接条件以匹配表的约束:
insert into new_table (ID, ParentID, Foo, Bar, Buzz)
select ID+@maxid, ParentID+@maxid, Foo, Bar, Buzz
from initial_table i
left
join new_table N on
i.ID+@maxid = n.ID or
i.ParentID+@maxid = n.ParentId
where n.ID is null --make sure its not already there
2。 某处,子查询返回了您期望的多行。 子查询错误可以是插入dbo.Customer(触发t1)的代码,也可能是在new_table上定义的触发器中。我没有在发布的代码中看到任何会抛出子查询异常的内容。
触发器(也称为地雷)插入到已在其上定义触发器的表中是一种痛苦的处方。如果可能的话,尝试将一些逻辑从触发器重构为逻辑上遵循的代码。
答案 1 :(得分:2)
首先,您必须假设插入或删除的记录不止一条。您不应该在插入或删除的表中将值设置为SQL Server触发器中的标量变量。如果插入包含多个记录,迟早会出现问题。
接下来,您不应该考虑在触发器中设置标识插入。你在想什么?如果您有一个标识字段然后使用它,请不要尝试手动创建值。
接下来,子查询问题显然与另一个触发器相关联,您还假设一次只处理一条记录。我怀疑你需要检查数据库中的每个触发器并修复这个基本问题。
现在,当你运行这部分代码时:
INSERT INTO new_table (ID, ParentID, Foo, Bar, Buzz)
SELECT ID+@maxid, ParentID+@maxid, Foo, Bar, Buzz FROM initial_table
您正尝试在表格中插入所有记录,而不仅仅是插入的记录。因此,由于您在另一个表上的触发器是无法编写的,因此您遇到的错误实际上隐藏了当您尝试将具有相同PK的2000条记录插入新表时会出现的错误,或者更糟糕的是如果您没有PK,每次插入一条记录时都会很乐意插入它们。
答案 2 :(得分:1)
你有一个包含声明的触发器:
SELECT @customerid = id FROM inserted
inserted
表包含插入(或更新UPDATE
个触发器)的每一行的行。执行的语句插入了多行,触发了触发器,并且您的假设被曝光。
重新编码触发器以对行集进行操作,而不是单行。
答案 3 :(得分:-1)
在任何类型的select中使用子查询时,尝试调整查询,以便子查询只返回1个值而不是多个。
如果需要多个,则重构查询,使表成为主查询的一部分。
我举的SQL示例: 从table1中选择col1,(从table2中选择col2,其中table2.col3 = table1.col4); 如果col2返回多行,则查询失败,然后将其重新写入:
从table1,table2中选择col1,col2,其中table2.col3 = table1.col4;
我希望你明白这一点。
答案 4 :(得分:-3)
你不应该选择它,你应该设置它。
SET @maxid = MAX(ID) FROM another_table