STATEMENT ERROR(子查询返回的值超过1)

时间:2016-02-21 17:17:52

标签: sql sql-server tsql reporting-services

这是我的第一个问题。我刚从前任IT人那里接过了SQL报告,而且我正在努力解决下面的问题。它突然停止工作两天前,现在显示:

报告处理期间发生错误。 (rsProcessingAborted) 数据集' DataSet1'的查询执行失败。 (rsErrorExecutingCommand) 子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。声明已经终止。

它停在第49行:

and (select t.[status] from [ksimakeprod01].[imake].dbo.iSchWOScheduleLine t left join [ksimakeprod01].[imake].dbo.WORKORDER wa on t.WorkOrderKey=wa.WORKORDERKEY where wa.workorderno=wh.WorkOrderNo)<>7

我从错误中了解到我尝试更新包含多行数据的列...但是此查询之前有效...我该如何解决?

完整查询:

if object_id('tempdb..#CCR_TimelineTable') is not null
begin
drop table #CCR_TimelineTable
end


--Populate temp table with opening inventory.
select 'Balance'as'CCStatus'
,case ss.WhseID when 'SH3' then 'FD2' else ss.WhseID end as 'WhseID'
,ss.ItemID,ss.QtyOnHand,ss.UnitMeasID,cast(cast(getdate() as date)as datetime)'Date',cast(''as varchar(max)) as'WOnum',cast(0 as decimal(10,3)) as'QtyPerCS',cast(0 as float)as'TotalWOqtyReq'
into #CCR_TimelineTable
from vdvStockStatus ss
    left join timItem i on i.ItemKey=ss.ItemKey
where ss.CompanyID='KSO'
and right(left(i.ItemID,5),2) in('PK','PC')

--Populate table with incoming purchase orders.
insert into #CCR_TimelineTable
select 'Purchas'
,case pl.WhseID when 'SH3' then 'FD2' else pl.WhseID end as 'WhseID'
,pl.ItemID,pl.QtyOpenToRcv,pl.UnitMeasID
    ,case when datename(dw,pl.PromiseDate) in ('Friday','Thursday','Wednesday')
            then dateadd(day,5,pl.PromiseDate)
        else dateadd(day,3,pl.PromiseDate) end
,pl.TranID,0,0
from vdvPurchaseOrderLine pl
where pl.CompanyID='KSO' 
and right(left(pl.ItemID,5),2) in('PK','PC')
and pl.StatusAsText='Open'
and pl.QtyOpenToRcv>0
and pl.PromiseDate > cast(getdate() as date)


--Populate table with open work orders. With iMake scheduled start times.
insert into #CCR_TimelineTable
select 'WorkOr',w.WhseID,il.ItemID,-(ww.balancequantitytoproduce*wl.MatReqPc),wos.MaterialItemUOM,ww.woschstdate,ww.workorderno,wl.MatReqPc,(ww.balancequantitytoproduce*wl.MatReqPc)
from tmfWorkOrdDetl_HAI wl
    left join tmfWorkOrdHead_HAI wh on wh.WorkOrderKey=wl.WorkOrderKey
    left join timitem il on il.ItemKey=wl.MatItemKey
    left join timItem ih on ih.ItemKey=wl.ProduceItemKey
    left join timWarehouse w on w.WhseKey=wl.WhseKey
    left join vdvWorkOrderSteps wos on wos.WorkOrderNo=wh.WorkOrderNo and wos.ItemID=il.ItemID
    left join (select wh.WORKORDERNO,sch.WOSchStDate,wh.balancequantitytoproduce from [ksimakeprod01].[imake].dbo.iSchWOScheduleLine sch
                left join [ksimakeprod01].[imake].dbo.WORKORDER wh on sch.WorkOrderKey=wh.WORKORDERKEY)ww on ww.workorderno=wh.workorderno
where wl.CompanyID='KSO'
and right(left(il.ItemID,5),2) in('PK','PC')
and wh.Complete=0
and ww.WOSchStDate is not null
and (select t.[status] from [ksimakeprod01].[imake].dbo.iSchWOScheduleLine t left join [ksimakeprod01].[imake].dbo.WORKORDER wa on t.WorkOrderKey=wa.WORKORDERKEY where wa.workorderno=wh.WorkOrderNo)<>7

update #CCR_TimelineTable
set Date= cast(getdate()as date)
where CCStatus='WorkOr' and Date<cast(getdate()as date)

--select * from #CCR_TimelineTable


------------------------------------------------------------------------------
/*declare @days as int
declare @PK as varchar(max)
declare @FG as varchar(max)
declare @WO as varchar(max)
declare @cell as varchar(max)
declare @desc as varchar(max)
set @days = 30
set @PK = '%'
set @FG = '%'
set @WO = '%'
set @cell = 'EGW 3+4'
set @desc = 'sain'*/

select w.WhseID,il.ItemID,id.ShortDesc as'PKDesc',wo.RoutingId,rd.ShortDesc as'FGDesc',wo.WorkOrderNo,ww.CellName,ww.WOSchStDate
    ,(select sum(tl.QtyOnHand) from #CCR_TimelineTable tl where tl.ItemID=il.ItemID and tl.WhseID=w.WhseID and ww.WOSchStDate>=tl.Date)'RunningBalance'
    ,(select top 1 tl.UnitMeasID from #CCR_TimelineTable tl where tl.ItemID=il.ItemID group by tl.UnitMeasID order by count(tl.UnitMeasID) desc)'UoM'
    ,inv.FD2,inv.FD2QC,inv.EG2,inv.EG2QC,inv.SH3,inv.SH3QC,inv.AL3
    ,(select distinct cc.QtyPerCS from #CCR_TimelineTable cc where cc.WOnum=wo.WorkOrderNo and cc.ItemID=il.ItemID)as'QtyReqPerCS'
    ,(select distinct cc.TotalWOqtyReq from #CCR_TimelineTable cc where cc.WOnum=wo.WorkOrderNo and cc.ItemID=il.ItemID)as'TotalQtyReqWO'
from tmfWorkOrdDetl_HAI wl
        left join tmfWorkOrdHead_HAI wh on wh.WorkOrderKey=wl.WorkOrderKey
        left join timitem il on il.ItemKey=wl.MatItemKey
        left join timItemDescription id on id.ItemKey=il.ItemKey
        left join vdvWorkOrder wo on wo.WorkOrderKey=wh.WorkOrderKey
        left join timWarehouse w on w.WhseKey=wl.WhseKey
        left join timItem ri on ri.ItemID=wo.RoutingId and ri.CompanyID='KSO'
        left join timItemDescription rd on rd.ItemKey=ri.ItemKey
        left join (select wh.WORKORDERNO,sch.WOSchStDate,wh.CURRENTSTATUS,mc.CellName from [ksimakeprod01].[imake].dbo.iSchWOScheduleLine sch
                left join [ksimakeprod01].[imake].dbo.WORKORDER wh on sch.WorkOrderKey=wh.WORKORDERKEY
                left join [ksimakeprod01].[imake].dbo.ManufacturingCell mc on mc.CellKey=wh.MANUFACTURINGCELL)ww on ww.workorderno=wo.workorderno
        left join (select i.ItemID
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='FD2' and vs.ItemID=i.ItemID),0)as'FD2'
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='FD2QC' and vs.ItemID=i.ItemID),0)as'FD2QC'
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='EG2' and vs.ItemID=i.ItemID),0)as'EG2'
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='EG2QC' and vs.ItemID=i.ItemID),0)as'EG2QC'
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='SH3' and vs.ItemID=i.ItemID),0)as'SH3'
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='SH3QC' and vs.ItemID=i.ItemID),0)as'SH3QC'
        ,isnull((select vs.QtyOnHand from vdvStockStatus vs where vs.WhseID='AL3' and vs.ItemID=i.ItemID),0)as'AL3'
        from timItem i
        where i.CompanyID='KSO'
        and right(left(i.ItemID,5),2) in('PK','PC'))inv on inv.ItemID=il.ItemID
where wl.CompanyID='KSO'
and right(left(il.ItemID,5),2) in('PK','PC')
and wh.Complete=0
and (select sum(tl.QtyOnHand) from #CCR_TimelineTable tl where tl.ItemID=il.ItemID and tl.WhseID=w.WhseID and ww.WOSchStDate>=tl.Date)<0
and ww.currentstatus<>'Completed'
and il.ItemID like '%'+ @PK +'%'
and wo.RoutingId like '%'+ @FG +'%'
and wo.WorkOrderNo like '%'+ @WO +'%'
and id.shortdesc like '%'+ @desc +'%'
and ww.cellname in(@cell)
and ww.WOSchStDate < dateadd(day,@days,getdate())

order by ww.WOSchStDate

2 个答案:

答案 0 :(得分:1)

  

和(从[ksimakeprod01]中选择t。[status]。[imake] .dbo.iSchWOScheduleLine t left join [ksimakeprod01]。[imake] .dbo.WORKORDER wa on t.WorkOrderKey = wa.WORKORDERKEY where wa.workorderno = wh.WorkOrderNo)LT;大于7

问题是查询现在返回多行。如果您自己运行查询,那将是显而易见的。解决此问题的最简单方法是确保使用TOP子句只返回1行,如下所示。

and (select TOP 1 t.[status] from [ksimakeprod01].[imake].dbo.iSchWOScheduleLine t left join [ksimakeprod01].[imake].dbo.WORKORDER wa on t.WorkOrderKey=wa.WORKORDERKEY where wa.workorderno=wh.WorkOrderNo)<>7

您应该知道这是一个“错误”修复,因为它可能导致整个查询返回错误的数据。可以这样考虑...你正在检查状态列是否为7.但是,由于查询返回多行,一个状态值可能是7而另一个可能是7以外的其他值。因为你是现在使用顶部子句,顶行可以是7,或者顶行可以是另一个值。

我不想这么说,但修复此查询的最佳方法是完全重写。这是确保您的查询做得正确的唯一方法。

答案 1 :(得分:0)

如果完成:

(select 
    t.[status] 
from 
    [ksimakeprod01].[imake].dbo.iSchWOScheduleLine t 
left join 
    [ksimakeprod01].[imake].dbo.WORKORDER wa 
on 
    t.WorkOrderKey=wa.WORKORDERKEY 
where 
    wa.workorderno=wh.WorkOrderNo)<>7

然后问题是此子查询返回多个记录,因此您无法将其与单个值进行比较。您可以强制它使用TOP 1返回一个值,但这取决于该上下文是否合适。如果你使用它,你基本上会忽略该查询中的所有其他值,并选择第一个出现的值可能没有意义!

(select 
    TOP 1 t.[status] 
from 
    [ksimakeprod01].[imake].dbo.iSchWOScheduleLine t 
left join 
    [ksimakeprod01].[imake].dbo.WORKORDER wa 
on 
    t.WorkOrderKey=wa.WORKORDERKEY 
where 
    wa.workorderno=wh.WorkOrderNo)<>7