SQL子查询返回了多个值

3

我的查询导致了以下错误:

消息512,级别16,状态1,过程Item_insupd,行17
子查询返回的值超过1个。当子查询跟随=,!=,<,<=,>,>=或子查询用作表达式时,不允许这种情况。

查询:

INSERT INTO [Total_Database].[dbo].[Item]
    (
        ItemID, 
        ItemNo,
        ItemDescription,
        Notes,
        StandardCost,
        SalesGLAccountID,
        ItemTypeID,
        Backorderable
    ) 
 (
    SELECT  [nr],
            [nr],
            [Latijn]+' '+[Subgroep]+' '+CAST([nr] as VARCHAR(255)),
            [NL]+' '+[Vorm]+' '+[Kenmerk]+' '+[Hoogte],[Inkoopprijs],
            (4),
            (case when [Productgroep]='PB' then 1 else 5 end),
            (1) 
    FROM    [ACCESDATA].[dbo].[Planten]
 );

我怀疑这是因为我的子查询中没有包含 WHERE,不幸的是我不知道如何构建正确的 WHERE 语句。


3
"INSERT..SELECT"语句中,SELECT前后不需要加括号。如果加上括号,则会变成子查询,在此处使用是不合适的。 - RBarryYoung
3
如果这是一个答案的话,那可能是一个不错的回答。 - GolezTrol
3
@Ben,这张表格上有触发器吗? - GolezTrol
1
@Ben:你能发一下你的存储过程(Procedure Item_insupd)吗?我怀疑你错误地标识了错误行... - a1ex07
1
没错,触发器很可能是问题所在。 - RBarryYoung
显示剩余6条评论
3个回答

4

我怀疑问题出现在这个字符串中(你的代码中的第26行):

IF NOT (EXISTS (SELECT G.GLAccountID FROM GLAccnt G INNER JOIN Inserted I ON G.GLAccountID = I.SalesGLAccountID))
OR ((SELECT I.COGSGLAccountID FROM Inserted I) IS NOT NULL) AND NOT (EXISTS (SELECT G.GLAccountID FROM GLAccnt G INNER JOIN Inserted I ON G.GLAccountID = I.COGSGLAccountID))

看起来 (SELECT I.COGSGLAccountID FROM Inserted I) 返回了多行,因此出现了错误。
你把 inserted 当作一个单行表来处理(例如,你从中获取参数,比如 SELECT @ItemNo = I.ItemNo, @ItemDescription = I.ItemDescription FROM Inserted I),但是 inserted 表可能有多行。所以在你的情况下,我认为你有三个选择:检查 inserted 中是否只有一行、重写触发器为基于集合的方式或使用游标。
这里有一个类似的例子:SQL Fiddle

禁用触发器完成了工作。谢谢。 - Ben

0

如果你真的只想插入一行,那么你只需要在末尾添加Where,然后跟上一个谓词(逻辑语句),该语句仅对查询所读取的表中的一行为真。

INSERT INTO [Total_Database].[dbo].[Item](ItemID,
    ItemNo,ItemDescription,Notes,StandardCost,SalesGLAccountID,
     ItemTypeID,Backorderable) 
SELECT  [nr],[nr],[Latijn]+' '+[Subgroep]+' '+CAST([nr] as VARCHAR(255)),
            [NL]+' '+[Vorm]+' '+[Kenmerk]+' '+[Hoogte],[Inkoopprijs],(4),
           (case when [Productgroep]='PB' then 1 else 5 end),(1) 
FROM  [ACCESDATA].[dbo].[Planten]
Where [SomeColumnName] = [some Value];  

... 但是当执行插入操作并使用选择生成要插入的行时,只需键入Select语句而不是Values()子句,并且不用加括号。 我认为因为你加了括号,查询处理器认为你想要一个单值。您是想插入一行数据还是整个数据集?


我喜欢一个完整的集合,我知道以下代码是有效的:WHERE [nr] = 'somenumber'; 但如果我删除WHERE并执行查询,无论是否使用括号,我都会得到相同的错误。 - Ben
@Ben,这与标准SQL不一致。使用返回多行的Select应该可以正常工作。请展示你正在使用的确切SQL语句(不包括Where子句),以便我们了解你遇到的错误……除非你的错误来自于此表上的某个触发器,该触发器试图使用此数据的子查询将数据插入到另一个表中? - Charles Bretana

-1
INSERT INTO [Total_Database].[dbo].[Item]
    (
        ItemID, 
        ItemNo,
        ItemDescription,
        Notes,
        StandardCost,
        SalesGLAccountID,
        ItemTypeID,
        Backorderable
    ) IN
 (
    SELECT  [nr],
            [nr],
            [Latijn]+' '+[Subgroep]+' '+CAST([nr] as VARCHAR(255)),
            [NL]+' '+[Vorm]+' '+[Kenmerk]+' '+[Hoogte],[Inkoopprijs],
            (4),
            (case when [Productgroep]='PB' then 1 else 5 end),
            (1) 
    FROM    [ACCESDATA].[dbo].[Planten]
 );

在 select 前加上 IN,即可选择多个值。 - chevhfghfghfgh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接