我有一个存储过程来处理每月的工作。存储过程将循环遍历所有可用作业,并在将其插入表格之前进行一些计算。大多数工作都没问题,但对于某些工作,会出现错误
子查询返回的值超过1。这是不允许的 子查询跟随=,!=,<,< =,>,> =或当子查询用作 表达。
以下是发生错误的部分:
IF EXISTS( SELECT *
FROM aastocks aastk
WHERE aastk.estno = @lcEstno
and 0 in (aastk.cartonratio1,
aastk.cartonratio2,
aastk.cartonratio3,
aastk.cartonratio4,
aastk.cartonratio5)
) EXECUTE ru_est_stocksum @lcEstNo
@lcEstNo在前面的代码中定义。
SET @lcEstno = (SELECT MAX(estno) FROM dbo.v_est_joblist WHERE ljob = @tcLjob)
MAX()应该只返回1个值,我不明白为什么会出现多值错误。
事实证明,错误的行号与存储过程中的行号不同。所以问题实际上存在于下面的代码中(在我注释掉下面的部分并且没有错误之后)。但我无法找出哪个子查询返回的值超过1。有什么想法吗?
INSERT INTO @JCDTotals
SELECT @tcLjob, coalesce(cast( ap.deptno as char(4)),'????') as deptno,
CASE WHEN coalesce(v_depuse_qty.DepUse, 1) = 1 THEN
CASE WHEN @tcCostBase = 'D' THEN CASE WHEN ap.procgroup = 'I' THEN aaprocqt.dmcstmat1 + aaprocqt.dmcstmat2 + aaprocqt.dmcstmat3 END
WHEN @tcCostBase = 'A' THEN CASE WHEN ap.procgroup = 'I' THEN aaprocqt.costmats1 + aaprocqt.costmats2 + aaprocqt.costmats3 END
ELSE ' 0 '
END
ELSE 0 END AS ecostmats,
CASE WHEN coalesce(v_depuse_qty.DepUse, 1) = 1 THEN CASE WHEN @tcCostBase = 'D' THEN (1 / (1 + (ap.burden/100))) ELSE 1 END
* aaprocqt.costlab
ELSE 0
END AS ecostlab,
CASE WHEN coalesce(v_depuse_qty.DepUse, 1) = 1 THEN aaprocqt.proctime
ELSE 0
END AS eprochours,
0.0 AS bcostmats,
0.0 AS bcostlab,
0 AS bprochours,
0.0 AS acostmats,
0.0 AS acostlab,
0 AS aprochours,
0.0 AS chgcost,
0 AS dirlab,
0.0 AS aacost,
0.0 AS pecost,
0.0 AS otcost,
0 AS sell
FROM (
SELECT aaproces.idnumber,
aaproces.estno,
aaproces.procgroup,
aaproces.partno,
aaproces.[lineno],
aaproces.counter,
ssproces.burden,
case WHEN aaproces.procgroup = 'I' then ssinvent.deptno
else ssproces.deptno end as deptno,
case WHEN aaproces.procgroup = 'I' then ssinvent.matno
else STR(ssproces.procno,6) end as procno,
case WHEN aaproces.procgroup = 'I' then ssinvent.material
else ssproces.process end as process
FROM dbo.aaproces
LEFT JOIN dbo.SSINVENT ON ssinvent.matno = aaproces.matno
AND ssinvent.invtype IN ('G', 'I', 'F', 'S')
LEFT JOIN dbo.SSPROCES ON ssproces.procno = aaproces.procno
WHERE ((aaproces.procgroup = 'I' and ssinvent.deptno is not null)
OR (aaproces.procgroup <> 'I' and ssproces.deptno is not null))
AND ((aaproces.procgroup = 'I' and ssinvent.matno is not null)
OR (aaproces.procgroup <> 'I' and ssproces.procno is not null))
) ap
INNER join dbo.v_est_joblist
on v_est_joblist.estno = ap.estno
LEFT OUTER JOIN dbo.aaprocqt
on aaprocqt.estno = ap.estno
and ap.[lineno] = aaprocqt.[lineno]and aaprocqt.procgroup = ap.procgroup
and ap.partno = aaprocqt.partno and ap.counter = aaprocqt.counter and aaprocqt.qty = v_est_joblist.alt
LEFT OUTER JOIN dbo.v_depuse_qty
ON v_est_joblist.estno = v_depuse_qty.estno
AND v_depuse_qty.deptno = ap.deptno
AND V_DEPUSE_QTY.LJOB = V_EST_JOBLIST.LJOB
AND V_DEPUSE_QTY.ALT = V_EST_JOBLIST.ALT
WHERE v_est_joblist.ljob = @tcLjob
-- AND ssdept.divno like @lcDivNo
--------------------------------------------------------------------------- PROCESS MATERIAL1,MATERIAL2,MATERIAL3 (ESTIMATED)
UNION ALL
SELECT @tcLjob, coalesce(ssinvent.deptno,'????') as deptno,
CASE WHEN coalesce((SELECT v_depuse_qty.DepUse FROM dbo.v_depuse_qty WHERE v_est_joblist.estno = v_depuse_qty.estno
AND ssinvent.deptno = v_depuse_qty.deptno
AND V_DEPUSE_QTY.LJOB = V_EST_JOBLIST.LJOB
AND V_DEPUSE_QTY.ALT = V_EST_JOBLIST.ALT), 1) = 1 THEN CASE WHEN sq.CopyNum = 1 THEN CASE WHEN @tcCostBase = 'D' THEN aaprocqt.dmcstmat1 ELSE aaprocqt.costmats1 END
WHEN sq.CopyNum = 2 THEN CASE WHEN @tcCostBase = 'D' THEN aaprocqt.dmcstmat2 ELSE aaprocqt.costmats2 END
WHEN sq.CopyNum = 3 THEN CASE WHEN @tcCostBase = 'D' THEN aaprocqt.dmcstmat3 ELSE aaprocqt.costmats3 END
END
ELSE 0
END AS ecostmats,
0 AS ecostlab,
0 AS eprochours,
0 AS bcostmats,
0 AS bcostlab,
0 AS bprochours,
0.0 AS acostmats,
0.0 AS acostlab,
0 AS aprochours,
0.0 AS chgcost,
0 AS dirlab,
0.0 AS aacost,
0.0 AS pecost,
0.0 AS otcost,
0 AS sell
FROM dbo.aaproces JOIN dbo.v_est_joblist on v_est_joblist.estno = aaproces.estno
CROSS JOIN @NumCopies sq
LEFT JOIN dbo.ssproces on aaproces.procno = ssproces.procno
LEFT JOIN dbo.ssinvent on ssinvent.matno = ( case when sq.CopyNum = 1 then CASE WHEN aaproces.manmatno = '' THEN ssproces.matno1 ELSE aaproces.manmatno END
when sq.CopyNum = 2 then CASE WHEN aaproces.manmatno2 = '' THEN ssproces.matno2 ELSE aaproces.manmatno2 END
when sq.CopyNum = 3 then CASE WHEN aaproces.manmatno3 = '' THEN ssproces.matno3 ELSE aaproces.manmatno3 END
end)
JOIN dbo.aaprocqt on aaprocqt.estno = aaproces.estno and aaprocqt.procgroup = aaproces.procgroup
and aaproces.partno = aaprocqt.partno and aaproces.[lineno] = aaprocqt.[lineno]
and aaproces.counter = aaprocqt.counter and aaprocqt.qty = v_est_joblist.alt
WHERE aaproces.procgroup <> 'I'
--and sq.CopyNum < 4
and case when sq.CopyNum = 1 then (manmatno + matno1 )
when sq.CopyNum = 2 then (aaproces.manmatno2 + ssproces.matno2 )
when sq.CopyNum = 3 then (manmatno3 + matno3 )
end <> ''
AND v_est_joblist.ljob = @tcLjob
--------------------------------------------------------------------------- STOCKS (ESTIMATED)
UNION ALL
SELECT @tcLjob, coalesce(case when aastocks.houvend = 'H' then ssinvent.deptno
else case when aapthead.parttype = 'S' then @opt_stockccs
else @opt_stockccr end end,'????')
as deptno,
CASE WHEN coalesce((SELECT v_depuse_qty.DepUse FROM dbo.v_depuse_qty WHERE v_est_joblist.estno = v_depuse_qty.estno
AND v_depuse_qty.deptno = ssdept.deptno
AND V_DEPUSE_QTY.LJOB = V_EST_JOBLIST.LJOB
AND V_DEPUSE_QTY.ALT = V_EST_JOBLIST.ALT), 1) = 1 THEN CASE WHEN @tcCostBase = 'D' THEN
CASE WHEN aastocks.houvend = 'V' THEN (1 / (1 + (ssdept.burden/100)))
ELSE (1 / (1 + (ssinvent.burden/100))) END
ELSE 1 END *
case when v_est_joblist.alt = 1 then aastocks.stkcost1 * aastocks.cartonratio1
when v_est_joblist.alt = 2 then aastocks.stkcost2 * aastocks.cartonratio2
when v_est_joblist.alt = 3 then aastocks.stkcost3 * aastocks.cartonratio3
when v_est_joblist.alt = 4 then aastocks.stkcost4 * aastocks.cartonratio4
when v_est_joblist.alt = 5 then aastocks.stkcost5 * aastocks.cartonratio5
END
ELSE 0
END AS ecostmats,
0 as ecostlab,
0 as eprochours,
0 AS bcostmats,
0 AS bcostlab,
0 AS bprochours,
0.0 AS acostmats,
0.0 AS acostlab,
0 AS aprochours,
0.0 AS chgcost,
0 AS dirlab,
0.0 AS aacost,
0.0 AS pecost,
0.0 AS otcost,
0 AS sell
FROM dbo.aapthead
INNER JOIN dbo.aastocks on aapthead.estno = aastocks.estno and aapthead.partno = aastocks.partno
INNER JOIN dbo.v_est_joblist on v_est_joblist.estno = aapthead.estno
LEFT OUTER JOIN dbo.ssinvent on aastocks.matno = ssinvent.matno
AND ssinvent.invtype IN ('R', 'S')
LEFT OUTER JOIN dbo.ssdept ON ssdept.deptno = (CASE WHEN aastocks.houvend = 'H' THEN ssinvent.deptno
ELSE CASE WHEN aapthead.parttype = 'S' THEN @opt_stockccs
ELSE @opt_stockccr
END
END)
WHERE v_est_joblist.ljob = @tcLjob
AND 1 = [dbo].[DivisionCheck] (ssdept.divno,@tcDivNo)
答案 0 :(得分:0)
在显示的三个代码示例中,我看不到任何会生成该子查询错误消息的内容。
exists()
子查询旨在处理多个返回的行select max()
子查询格式正确因此,它必须是别的东西。我的猜测 - 这是一个猜测 - 在第三个bock中,表v_est_joblist
和/或v_depuse_qty
实际上是视图(我自己使用类似v_Blah
约定的东西),其中一个出了问题。如果是这样,您需要测试这些视图,看看它们在加入主查询时返回的内容是什么。
答案 1 :(得分:-2)
您的“in”表达式似乎提供了多行值。因此,虽然“exists”可以接受多行作为输入,但是(aastk.cartonratio1,...)中的“0”不能。