在Sql Server 2019中,我得到了
msg 512子查询返回的值超过1。当子查询跟在=、!=、<lt;=>gt;=或者当子查询用作表达式时。
在几个地方,第一个在本节中。
IF (SELECT Job FROM [PRODUCTION].[dbo].[Job] WHERE Part_Number = @PN) is null
SELECT @Job='NOTHING'
ELSE
SELECT @Job = (SELECT Job FROM [PRODUCTION].[dbo].[Job] WHERE Status_Date = (SELECT
Max(Status_Date) FROM [PRODUCTION].[dbo].[Job] WHERE Part_Number = @PN AND Status =
'Closed'))
我可以自己运行查询,并且总是只得到一个结果。我已尝试使用TOP 1
进行查询,但仍然收到消息512。
您的代码中有两个相同的逻辑缺陷。您知道IF语句是一个问题,因为它已经被注意到了。因此可以通过替换来避免:
IF (SELECT Job FROM [PRODUCTION].[dbo].[Job] WHERE Part_Number = @PN) is null
SELECT @Job='NOTHING'
带有
if not exists (select * from dbo.Job where Part_Number = @PN)
set @Job = 'NOTHING';
注意更好的做法。删除了数据库名称,因为连接应该确定该名称。拆下方括号,因为不需要它们。使用SET指定标量值,而不是SELECT。语句终止符。等等
额外的错误出现在用于检索作业值的select语句中。去除额外的绒毛进行分配,你有:
SELECT Job FROM [PRODUCTION].[dbo].[Job]
WHERE Status_Date =
(SELECT Max(Status_Date)
FROM [PRODUCTION].[dbo].[Job]
WHERE Part_Number = @PN AND Status = 'Closed'
)
在这里,子查询确实会为您想要的零件号和状态选择一行。但是,您只选择一个日期,Status_date列中可能(而且显然(有许多行具有该特定日期。您没有将外部查询限制为适当的part_number,这可能会也可能不会解决您的问题(因为我不知道您的模式(。
因此,我建议您搜索我在评论中使用的术语,并使用row_number方法来访问";第一行";(实际上是按降序排列的最后一行(。
为了完整起见,您可以将您的任务更改为:
set @Job = (top 1 Job from dbo.Job
where Part_Number = @PN and Status = 'Closed' order by Status_Date desc);
这也可能";避免";问题,但我不能说没有你的模式知识。大概很多工作都可以有相同的零件号,所以我认为这里缺少了一些东西。
使用exists
尝试以下反向逻辑
if exists (select * from dbo.job where part_number = @PN)
select @job= (....)
else
select @Job='NOTHING'