我已经创建了一个要在其中插入数据的表。
对于数据插入,已经创建了一个查询,该查询将插入另一个表中的信息。
如果输出是单个值,它将在新表中更新。
但是,如果它是多个值,则会出现错误“子查询返回多个值”
如何使用表中的查询输入多个值?
Declare @BATCHNO as Nvarchar(10)
Declare @PRODNO as Nvarchar(10)
Declare @ISSUENO AS Nvarchar(10)
set @BATCHNO = (select T2.BatchNum from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14')
Set @PRODNO = (select T1.BaseRef from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14' )
Set @ISSUENO = (select T1.DocEntry AS 'ISSUE NUMBER' from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14')
Insert Into BATCHDETAIL (BATCHNO,PRODNO,ISSUENO) Values(@BATCHNO,@PRODNO,@ISSUENO)
[Microsoft] [用于SQL Server的ODBC驱动程序13] [SQL Server]子查询返回了多个值。当子查询遵循=,!=,<,<=,>,> =或将子查询用作表达式时,不允许这样做。在查询名称为“ FMS_BATCHNO_UPDATE”的字段“ U_EA_LICENCE”上执行FMS失败
答案 0 :(得分:2)
您需要修复子查询,以便它们返回要插入的确切单个值。
例如,如果您不太在意并可以插入满足这些条件的任何值,则只需在子查询中添加TOP 1,这样它们将仅返回可用的第一个值。
Declare @BATCHNO as Nvarchar(10)
Declare @PRODNO as Nvarchar(10)
Declare @ISSUENO AS Nvarchar(10)
set @BATCHNO = (select TOP 1 T2.BatchNum from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14')
Set @PRODNO = (select TOP 1 T1.BaseRef from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14' )
Set @ISSUENO = (select TOP 1 T1.DocEntry AS 'ISSUE NUMBER' from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14')
Insert Into BATCHDETAIL (BATCHNO,PRODNO,ISSUENO) Values(@BATCHNO,@PRODNO,@ISSUENO)
通过这种方式,您可以简化在单个查询中分配三个变量的脚本:
Declare @BATCHNO as Nvarchar(10)
Declare @PRODNO as Nvarchar(10)
Declare @ISSUENO AS Nvarchar(10)
select TOP 1 @BATCHNO = T2.BatchNum,
@PRODNO = T1.BaseRef,
@ISSUENO = T1.DocEntry
from OWOR T0
INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
where T0.DocEntry = '14'
Insert Into BATCHDETAIL (BATCHNO,PRODNO,ISSUENO) Values(@BATCHNO,@PRODNO,@ISSUENO)
最后,如果要插入满足条件的所有值,则可以使用select代替插入所有的值,而不用TOP 1取第一个值:
Insert Into BATCHDETAIL (BATCHNO,PRODNO,ISSUENO)
select T2.BatchNum, T1.BaseRef, T1.DocEntry
from OWOR T0
INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
where T0.DocEntry = '14'
答案 1 :(得分:2)
您似乎正在尝试根据现有数据插入多行。在这种情况下,您应该使用INSERT .. SELECT
而不是INSERT...VALUES
:
INSERT BatchDetail (BatchNo, ProdNo, IssueNo)
SELECT T2.BatchNum, T1.BaseRef, T1.DocEntry
FROM OWOR T0
INNER JOIN table_P T1
ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2
ON T1.DocEntry = T2.BaseEntry
AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14';
如果您只想基于多个记录插入一条记录,则可以使用TOP 1
,并提供ORDER BY
以确保获得可重复的结果:
INSERT BatchDetail (BatchNo, ProdNo, IssueNo)
SELECT TOP 1 T2.BatchNum, T1.BaseRef, T1.DocEntry
FROM OWOR T0
INNER JOIN table_P T1
ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2
ON T1.DocEntry = T2.BaseEntry
AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14'
ORDER BY t2.BatchNum, T1.BaseRef, T1.DocEntry;
最后,如果您确实确实想要3个标量变量,那么您仍然可以使用SELECT
和TOP 1
,只需使用SELECT
进行变量分配:
DECLARE @BATCHNO AS NVARCHAR(10)
@PRODNO AS NVARCHAR(10)
@ISSUENO AS NVARCHAR(10);
SELECT TOP 1
@BATCHNO = T2.BatchNum,
@PRODNO = T1.BaseRef,
@ISSUENO = T1.DocEntry
FROM OWOR T0
INNER JOIN table_P T1
ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2
ON T1.DocEntry = T2.BaseEntry
AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14'
ORDER BY t2.BatchNum, T1.BaseRef, T1.DocEntry;
ADENDUMEM
我非常建议您不要使用任何使用3个带有{{1}}并且没有排序依据的查询的方法。例如,如果您有一个表:
TOP 1
您可能希望它分配与单个记录对应的@ A,@ B和@C值(例如A B C
----------
1 3 2
2 1 3
3 2 1
或1, 3, 2
)
2, 1, 3
但是,您要执行3个不同的查询,并且根据表上的索引,您可以获得3个不同的查询计划和3个不同的记录用于每次分配。
这很容易证明:
SET @A = (SELECT TOP 1 A FROM #T);
SET @B = (SELECT TOP 1 B FROM #T);
SET @C = (SELECT TOP 1 C FROM #T);
对我来说,这返回:
-- CREATE TABLE AND FILL IT
IF OBJECT_ID(N'tempdb..#T', 'U') IS NOT NULL DROP TABLE #T;
CREATE TABLE #T (A INT NOT NULL PRIMARY KEY, B INT NOT NULL, C INT NOT NULL);
CREATE NONCLUSTERED INDEX IX_T_B ON #T (B);
CREATE NONCLUSTERED INDEX IX_T_C ON #T (C);
INSERT #T (A, B, C)
VALUES (1, 3, 2), (2, 1, 3), (3, 2, 1);
DECLARE @A INT, @B INT, @C INT;
SET @A = (SELECT TOP 1 A FROM #T);
SET @B = (SELECT TOP 1 B FROM #T);
SET @C = (SELECT TOP 1 C FROM #T);
SELECT A = @A, B = @B, C = @C;
与原始数据中的任何记录都不对应。这可能完全适合您的需求,但是绝对需要注意。
答案 2 :(得分:1)
使用它。
Declare @BATCHNO as Nvarchar(10)
Declare @PRODNO as Nvarchar(10)
Declare @ISSUENO AS Nvarchar(10)
set @BATCHNO = (select TOP 1 T2.BatchNum from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14')
Set @PRODNO = (select TOP 1 T1.BaseRef from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14' )
Set @ISSUENO = (select TOP 1 T1.DocEntry AS 'ISSUE NUMBER' from OWOR T0 INNER JOIN table_P T1 ON T0.DocEntry = T1.BaseEntry
INNER JOIN Table_I T2 ON T1.DocEntry = T2.BaseEntry AND T1.ObjType = T2.BaseType
WHERE T0.DocEntry = '14')
Insert Into BATCHDETAIL (BATCHNO,PRODNO,ISSUENO) Values(@BATCHNO,@PRODNO,@ISSUENO)