我正在尝试运行一个存储过程,但它会因使用过多内存而超时。运行它的服务器只有 1.5GB 的内存可以使用。这是原始查询:
CREATE PROCEDURE [dbo].[rpt_Registrations_Std]
@Action nvarchar(50) = '', -- Action is field name for now
@DATE_OPRT_FROM datetime = null,
@DATE_OPRT_TO datetime = null,
@DATE_EFFECTIVE_FROM datetime = null,
@DATE_EFFECTIVE_TO datetime = null,
@DATE_MODIFIED_FROM datetime = null,
@DATE_MODIFIED_TO datetime = null,
@ASSET_NO nvarchar(4000) = '',
@ASSET_NO_FROM nvarchar(20) = '',
@ASSET_NO_TO nvarchar(20) = '',
@HOLDER_CD nvarchar(4000) = '',
@HOLDER_CD_FROM nvarchar(10) = '',
@HOLDER_CD_TO nvarchar(10) = '',
@SITE_CD nvarchar(4000) = '',
@SITE_CD_FROM nvarchar(10) = '',
@SITE_CD_TO nvarchar(10) = '',
@ASSETCODE nvarchar(4000) = '',
@ASSETCODE_FROM nvarchar(10) = null,
@ASSETCODE_TO nvarchar(10) = null,
@FUND_CD nvarchar(4000) = '',
@FUND_CD_FROM nvarchar(10) = '',
@FUND_CD_TO nvarchar(10) = '',
@PO_NO nvarchar(4000) = '',
@PO_NO_FROM nvarchar(15) = '',
@PO_NO_TO nvarchar(15) = '',
@STATUS nvarchar(4000) = '',
@STATUS_FROM int = null,
@STATUS_TO int = null,
@UNITPRICE_FROM money = null,
@UNITPRICE_TO money = null,
@CAPITALIZED bit = Null
AS
BEGIN
select cast(data as nvarchar) ASSET_NO INTO #asset_nos from dbo.split(@ASSET_NO,',')
where data is not null
select cast(data as nvarchar) HOLDER_CD INTO #holders from dbo.split(@HOLDER_CD,',')
where data is not null
select cast(data as nvarchar) SITE_CD INTO #site from dbo.split(@SITE_CD,',')
where data is not null
select cast(data as nvarchar) ASSETCODE INTO #assetcode from dbo.split(@ASSETCODE,',')
where data is not null
select cast(data as nvarchar) FUND_CD INTO #fundcode from dbo.split(@FUND_CD,',')
where data is not null
select cast(data as nvarchar) PO_NO INTO #pono from dbo.split(@PO_NO,',')
where data is not null
select cast(data as int) [STATUS] INTO #status from dbo.split(@STATUS,',')
where data is not null
DECLARE @FIELD nvarchar(20)
SET @FIELD = @Action
--- FIELD Def for report From here
SELECT
a.ASSET_NO
,a.DATE_RECEIVED as DATE_OPRT
,a.DATE_EFFECTIVE_REGISTERED as DATE_EFFECTIVE
,a.DATE_REGISTERED as DATE_MODIFIED
,a.USER_ID_REGIST as USER_ID_MODIFY
,a.DESC_1
,a.DESC_2
,a.DESC_AX
,a.DESC_1
+ CASE WHEN IsNull(a.DESC_2, '') = '' THEN '' ELSE ' ' + a.DESC_2 END
+ CASE WHEN IsNull(a.DESC_AX, '') = '' THEN '' ELSE ' ' + a.DESC_AX END
as ASSET_DESC
,a.MANUFACTURER
,a.MODEL
,a.SERIAL_NO
,a.WEIGHT
,a.ASSETCODE
,a.SITE_CD
,a.ROOM_CD
,a.BUILDING_CD
,a.HOLDER_CD
,a.HOLDER_DESC
,a.STATUS
,Left(a.STATUS_DESC, 10) as STATUS_DESC
,ac.CODE_DESCRIPTION
,a.RM_DESC_1 AS ROOM_DESC
,a.SITE_NAME_1 AS SITE_NAME
,a.BUILDING_NAME
,a.DATE_RECEIVED
,fin.DATE_INSERVICE
,fin.ORIG_COST
,fin.QTY
,fin.PM_FUND_CD as FUND_CD
,fin.CAPITALIZED
,fnd.FUND_DESC
,a.PM_PO_NO as PO_NO
-- Initial values
,u.ORIG_COST AS INIT_COST
,ui.ASSETCODE AS INIT_ASSETCODE
,uR.SITE_CD AS INIT_SITE_CD
,u.ROOM_CD AS INIT_ROOM_CD
,uR.BUILDING_CD AS INIT_BUILDING_CD
,uR.RM_DESC_1 AS INIT_ROOM_DESC
,uR.BUILDING_NAME AS INIT_BUILDING_NAME
,uR.SITE_NAME_1 AS INIT_SITE_NAME
,u.HOLDER_CD AS INIT_HOLDER_CD
,uH.ORG_DESC AS INIT_HOLDER_DESC
,uac.CODE_DESCRIPTION AS INIT_CODE_DESCRIPTION
FROM vAsset as a
LEFT JOIN vAsset_Rgst_Info as u ON a.ASSET_ID = u.ASSET_ID
LEFT JOIN tAssetCode as ac ON a.ASSETCODE = ac.ASSETCODE
LEFT JOIN tAssetFin as fin ON a.ASSET_NO = fin.ASSET_NO
LEFT JOIN tFunding as fnd ON fin.PM_FUND_CD = fnd.FUND_CD
LEFT JOIN tItemCatalog as ui ON u.ITEM_CD = ui.ITEM_CD
LEFT jOIN tAssetCode as uac ON ui.ASSETCODE = uac.ASSETCODE
LEFT JOIN vRoom as uR ON u.ROOM_CD = uR.ROOM_CD
LEFT JOIN tOrganization as uH ON u.HOLDER_CD = uH.ORG_CD
WHERE
( @DATE_OPRT_FROM is null OR a.DATE_RECEIVED >= @DATE_OPRT_FROM )
AND ( @DATE_OPRT_TO is null OR a.DATE_RECEIVED <= @DATE_OPRT_TO )
AND ( @DATE_EFFECTIVE_FROM is null OR a.DATE_EFFECTIVE_REGISTERED >= @DATE_EFFECTIVE_FROM )
AND ( @DATE_EFFECTIVE_TO is null OR a.DATE_EFFECTIVE_REGISTERED <= @DATE_EFFECTIVE_TO )
AND ( @DATE_MODIFIED_FROM is null OR a.DATE_REGISTERED >= @DATE_MODIFIED_FROM )
AND ( @DATE_MODIFIED_TO is null OR a.DATE_REGISTERED <= @DATE_MODIFIED_TO )
AND ( @ASSET_NO = '' OR u.ASSET_NO in ( SELECT ASSET_NO from #asset_nos ))
AND ( @ASSET_NO_FROM = '' OR u.ASSET_NO >= @ASSET_NO_FROM )
AND ( @ASSET_NO_TO = '' OR u.ASSET_NO <= @ASSET_NO_TO )
AND ( @HOLDER_CD = '' OR a.HOLDER_CD in ( SELECT HOLDER_CD from #holders ))
AND ( @HOLDER_CD_FROM = '' OR a.HOLDER_CD >= @HOLDER_CD_FROM )
AND ( @HOLDER_CD_TO = '' OR a.HOLDER_CD <= @HOLDER_CD_TO )
AND ( @SITE_CD = '' OR a.SITE_CD in ( SELECT SITE_CD from #site ))
AND ( @SITE_CD_FROM = '' OR a.SITE_CD >= @SITE_CD_FROM )
AND ( @SITE_CD_TO = '' OR a.SITE_CD <= @SITE_CD_TO )
AND ( @ASSETCODE = '' OR a.ASSETCODE in ( SELECT ASSETCODE from #assetcode ))
AND ( @ASSETCODE_FROM is null OR a.ASSETCODE >= @ASSETCODE_FROM )
AND ( @ASSETCODE_TO is null OR a.ASSETCODE <= @ASSETCODE_TO )
AND ( @FUND_CD = '' OR PM_FUND_CD in ( SELECT FUND_CD from #fundcode ))
AND ( @FUND_CD_FROM = '' OR fin.PM_FUND_CD >= @FUND_CD_FROM )
AND ( @FUND_CD_TO = '' OR fin.PM_FUND_CD <= @FUND_CD_TO )
AND ( @PO_NO = '' OR a.PM_PO_NO in ( SELECT PO_NO from #pono ))
AND ( @PO_NO_FROM = '' OR a.PM_PO_NO >= @PO_NO_FROM )
AND ( @PO_NO_TO = '' OR a.PM_PO_NO <= @PO_NO_TO )
AND ( @STATUS = '' OR a.STATUS in ( SELECT [STATUS] from #status ))
AND ( @STATUS_FROM is null OR a.STATUS >= @STATUS_FROM )
AND ( @STATUS_TO is null OR a.STATUS <= @STATUS_TO )
AND ( @UNITPRICE_FROM is null OR fin.UNIT_COST >= @UNITPRICE_FROM )
AND ( @UNITPRICE_TO is null OR fin.UNIT_COST <= @UNITPRICE_TO )
AND ( @CAPITALIZED is null OR fin.CAPITALIZED = @CAPITALIZED )
END -- proc
我添加了一些子查询来加速它,但它仍然超时:
ALTER PROCEDURE [dbo].[rpt_Registrations_Std]
@Action nvarchar(50) = '', -- Action is field name for now
@DATE_OPRT_FROM datetime = null,
@DATE_OPRT_TO datetime = null,
@DATE_EFFECTIVE_FROM datetime = null,
@DATE_EFFECTIVE_TO datetime = null,
@DATE_MODIFIED_FROM datetime = null,
@DATE_MODIFIED_TO datetime = null,
@ASSET_NO nvarchar(4000) = '',
@ASSET_NO_FROM nvarchar(20) = '',
@ASSET_NO_TO nvarchar(20) = '',
@HOLDER_CD nvarchar(4000) = '',
@HOLDER_CD_FROM nvarchar(10) = '',
@HOLDER_CD_TO nvarchar(10) = '',
@SITE_CD nvarchar(4000) = '',
@SITE_CD_FROM nvarchar(10) = '',
@SITE_CD_TO nvarchar(10) = '',
@ASSETCODE nvarchar(4000) = '',
@ASSETCODE_FROM nvarchar(10) = null,
@ASSETCODE_TO nvarchar(10) = null,
@FUND_CD nvarchar(4000) = '',
@FUND_CD_FROM nvarchar(10) = '',
@FUND_CD_TO nvarchar(10) = '',
@PO_NO nvarchar(4000) = '',
@PO_NO_FROM nvarchar(15) = '',
@PO_NO_TO nvarchar(15) = '',
@STATUS nvarchar(4000) = '',
@STATUS_FROM int = null,
@STATUS_TO int = null,
@UNITPRICE_FROM money = null,
@UNITPRICE_TO money = null,
@CAPITALIZED bit = Null
AS
BEGIN
select cast(data as nvarchar) ASSET_NO INTO #asset_nos from dbo.split(@ASSET_NO,',')
where data is not null
select cast(data as nvarchar) HOLDER_CD INTO #holders from dbo.split(@HOLDER_CD,',')
where data is not null
select cast(data as nvarchar) SITE_CD INTO #site from dbo.split(@SITE_CD,',')
where data is not null
select cast(data as nvarchar) ASSETCODE INTO #assetcode from dbo.split(@ASSETCODE,',')
where data is not null
select cast(data as nvarchar) FUND_CD INTO #fundcode from dbo.split(@FUND_CD,',')
where data is not null
select cast(data as nvarchar) PO_NO INTO #pono from dbo.split(@PO_NO,',')
where data is not null
select cast(data as int) [STATUS] INTO #status from dbo.split(@STATUS,',')
where data is not null
DECLARE @FIELD nvarchar(20)
SET @FIELD = @Action
--- FIELD Def for report From here
SELECT
a.ASSET_NO
,a.DATE_RECEIVED as DATE_OPRT
,a.DATE_EFFECTIVE_REGISTERED as DATE_EFFECTIVE
,a.DATE_REGISTERED as DATE_MODIFIED
,a.USER_ID_REGIST as USER_ID_MODIFY
,a.DESC_1
,a.DESC_2
,a.DESC_AX
,a.DESC_1
+ CASE WHEN IsNull(a.DESC_2, '') = '' THEN '' ELSE ' ' + a.DESC_2 END
+ CASE WHEN IsNull(a.DESC_AX, '') = '' THEN '' ELSE ' ' + a.DESC_AX END
as ASSET_DESC
,a.MANUFACTURER
,a.MODEL
,a.SERIAL_NO
,a.WEIGHT
,a.ASSETCODE
,a.SITE_CD
,a.ROOM_CD
,a.BUILDING_CD
,a.HOLDER_CD
,a.HOLDER_DESC
,a.STATUS
,Left(a.STATUS_DESC, 10) as STATUS_DESC
,ac.CODE_DESCRIPTION
,a.RM_DESC_1 AS ROOM_DESC
,a.SITE_NAME_1 AS SITE_NAME
,a.BUILDING_NAME
,a.DATE_RECEIVED
,fin.DATE_INSERVICE
,fin.ORIG_COST
,fin.QTY
,fin.PM_FUND_CD as FUND_CD
,fin.CAPITALIZED
,fnd.FUND_DESC
,a.PM_PO_NO as PO_NO
-- Initial values
,u.ORIG_COST AS INIT_COST
,ui.ASSETCODE AS INIT_ASSETCODE
,uR.SITE_CD AS INIT_SITE_CD
,u.ROOM_CD AS INIT_ROOM_CD
,uR.BUILDING_CD AS INIT_BUILDING_CD
,uR.RM_DESC_1 AS INIT_ROOM_DESC
,uR.BUILDING_NAME AS INIT_BUILDING_NAME
,uR.SITE_NAME_1 AS INIT_SITE_NAME
,u.HOLDER_CD AS INIT_HOLDER_CD
,uH.ORG_DESC AS INIT_HOLDER_DESC
,uac.CODE_DESCRIPTION AS INIT_CODE_DESCRIPTION
FROM (SELECT
a.ASSET_NO
,a.ASSET_ID
,a.DATE_EFFECTIVE_REGISTERED
,a.DATE_REGISTERED
,a.USER_ID_REGIST
,a.DESC_1
,a.DESC_2
,a.DESC_AX
,a.MANUFACTURER
,a.MODEL
,a.SERIAL_NO
,a.WEIGHT
,a.ASSETCODE
,a.SITE_CD
,a.ROOM_CD
,a.BUILDING_CD
,a.HOLDER_CD
,a.HOLDER_DESC
,a.STATUS
,a.STATUS_DESC
,a.RM_DESC_1
,a.SITE_NAME_1
,a.BUILDING_NAME
,a.DATE_RECEIVED
,a.PM_PO_NO
FROM vAsset as a WHERE ASSET_NO IN (
SELECT ASSET_NO FROM vAsset as a
WHERE
( @DATE_OPRT_FROM is null OR a.DATE_RECEIVED >= @DATE_OPRT_FROM )
AND ( @DATE_OPRT_TO is null OR a.DATE_RECEIVED <= @DATE_OPRT_TO )
AND ( @DATE_EFFECTIVE_FROM is null OR a.DATE_EFFECTIVE_REGISTERED >= @DATE_EFFECTIVE_FROM )
AND ( @DATE_EFFECTIVE_TO is null OR a.DATE_EFFECTIVE_REGISTERED <= @DATE_EFFECTIVE_TO )
AND ( @DATE_MODIFIED_FROM is null OR a.DATE_REGISTERED >= @DATE_MODIFIED_FROM )
AND ( @DATE_MODIFIED_TO is null OR a.DATE_REGISTERED <= @DATE_MODIFIED_TO )
AND ( @HOLDER_CD = '' OR a.HOLDER_CD in ( SELECT HOLDER_CD from #holders ))
AND ( @HOLDER_CD_FROM = '' OR a.HOLDER_CD >= @HOLDER_CD_FROM )
AND ( @HOLDER_CD_TO = '' OR a.HOLDER_CD <= @HOLDER_CD_TO )
AND ( @SITE_CD = '' OR a.SITE_CD in ( SELECT SITE_CD from #site ))
AND ( @SITE_CD_FROM = '' OR a.SITE_CD >= @SITE_CD_FROM )
AND ( @SITE_CD_TO = '' OR a.SITE_CD <= @SITE_CD_TO )
AND ( @ASSETCODE = '' OR a.ASSETCODE in ( SELECT ASSETCODE from #assetcode ))
AND ( @ASSETCODE_FROM is null OR a.ASSETCODE >= @ASSETCODE_FROM )
AND ( @ASSETCODE_TO is null OR a.ASSETCODE <= @ASSETCODE_TO )
AND ( @PO_NO = '' OR a.PM_PO_NO in ( SELECT PO_NO from #pono ))
AND ( @PO_NO_FROM = '' OR a.PM_PO_NO >= @PO_NO_FROM )
AND ( @PO_NO_TO = '' OR a.PM_PO_NO <= @PO_NO_TO )
AND ( @STATUS = '' OR a.STATUS in ( SELECT [STATUS] from #status ))
AND ( @STATUS_FROM is null OR a.STATUS >= @STATUS_FROM )
AND ( @STATUS_TO is null OR a.STATUS <= @STATUS_TO )
)) as a
LEFT JOIN vAsset_Rgst_Info as u ON a.ASSET_ID = u.ASSET_ID
LEFT JOIN tAssetCode as ac ON a.ASSETCODE = ac.ASSETCODE
LEFT JOIN tAssetFin as fin ON a.ASSET_NO = fin.ASSET_NO
LEFT JOIN tFunding as fnd ON fin.PM_FUND_CD = fnd.FUND_CD
LEFT JOIN tItemCatalog as ui ON u.ITEM_CD = ui.ITEM_CD
LEFT jOIN tAssetCode as uac ON ui.ASSETCODE = uac.ASSETCODE
LEFT JOIN vRoom as uR ON u.ROOM_CD = uR.ROOM_CD
LEFT JOIN tOrganization as uH ON u.HOLDER_CD = uH.ORG_CD
WHERE
( @ASSET_NO = '' OR u.ASSET_NO in ( SELECT ASSET_NO from #asset_nos ))
AND ( @ASSET_NO_FROM = '' OR u.ASSET_NO >= @ASSET_NO_FROM )
AND ( @ASSET_NO_TO = '' OR u.ASSET_NO <= @ASSET_NO_TO )
AND ( @FUND_CD = '' OR PM_FUND_CD in ( SELECT FUND_CD from #fundcode ))
AND ( @FUND_CD_FROM = '' OR fin.PM_FUND_CD >= @FUND_CD_FROM )
AND ( @FUND_CD_TO = '' OR fin.PM_FUND_CD <= @FUND_CD_TO )
AND ( @UNITPRICE_FROM is null OR fin.UNIT_COST >= @UNITPRICE_FROM )
AND ( @UNITPRICE_TO is null OR fin.UNIT_COST <= @UNITPRICE_TO )
AND ( @CAPITALIZED is null OR fin.CAPITALIZED = @CAPITALIZED )
END -- proc
我现在不知所措。似乎在太小的服务器上处理的数据太多。
最佳答案
修改内容为:
1)创建一个新的标量函数来测试分隔逗号文本中是否存在数据,无需创建#temp表来检查数据是否存在。
-- test if token exis in delimited comma string, use spli function
create FUNCTION [dbo].[inList]
(
@delimited NVARCHAR(MAX) ,
@token NVARCHAR(100)
)
RETURNS NVARCHAR(100)
as
begin
declare @retval NVARCHAR(100)
select @retval=data from
dbo.split(@delimited) t
where t.data=@token
return @retval
end
go
我们替换 where 条件中的表达式,如下例所示:
-- AND ( @ASSET_NO = '' OR u.ASSET_NO in ( SELECT ASSET_NO from #asset_nos ))
修改为:
AND ( @ASSET_NO = '' OR u.ASSET_NO = dbo.inlist(@ASSET_NO,u.ASSET_NO))
和所有分隔列表相同
2) 由于您使用了许多空参数,因此在执行前重新编译 SP 以获得新的执行计划( WITH RECOMPILE)
3)修改后的代码:
Alter PROCEDURE [dbo].[rpt_Registrations_Std]
@Action nvarchar(50) = '', -- Action is field name for now
@DATE_OPRT_FROM datetime = null,
@DATE_OPRT_TO datetime = null,
@DATE_EFFECTIVE_FROM datetime = null,
@DATE_EFFECTIVE_TO datetime = null,
@DATE_MODIFIED_FROM datetime = null,
@DATE_MODIFIED_TO datetime = null,
@ASSET_NO nvarchar(4000) = '',
@ASSET_NO_FROM nvarchar(20) = '',
@ASSET_NO_TO nvarchar(20) = '',
@HOLDER_CD nvarchar(4000) = '',
@HOLDER_CD_FROM nvarchar(10) = '',
@HOLDER_CD_TO nvarchar(10) = '',
@SITE_CD nvarchar(4000) = '',
@SITE_CD_FROM nvarchar(10) = '',
@SITE_CD_TO nvarchar(10) = '',
@ASSETCODE nvarchar(4000) = '',
@ASSETCODE_FROM nvarchar(10) = null,
@ASSETCODE_TO nvarchar(10) = null,
@FUND_CD nvarchar(4000) = '',
@FUND_CD_FROM nvarchar(10) = '',
@FUND_CD_TO nvarchar(10) = '',
@PO_NO nvarchar(4000) = '',
@PO_NO_FROM nvarchar(15) = '',
@PO_NO_TO nvarchar(15) = '',
@STATUS nvarchar(4000) = '',
@STATUS_FROM int = null,
@STATUS_TO int = null,
@UNITPRICE_FROM money = null,
@UNITPRICE_TO money = null,
@CAPITALIZED bit = Null
-- hint recompile for new fresh execution plan
WITH RECOMPILE
AS
BEGIN
--select cast(data as nvarchar) ASSET_NO INTO #asset_nos from dbo.split(@ASSET_NO,',')
-- where data is not null
--select cast(data as nvarchar) HOLDER_CD INTO #holders from dbo.split(@HOLDER_CD,',')
-- where data is not null
--select cast(data as nvarchar) SITE_CD INTO #site from dbo.split(@SITE_CD,',')
-- where data is not null
--select cast(data as nvarchar) ASSETCODE INTO #assetcode from dbo.split(@ASSETCODE,',')
-- where data is not null
--select cast(data as nvarchar) FUND_CD INTO #fundcode from dbo.split(@FUND_CD,',')
-- where data is not null
--select cast(data as nvarchar) PO_NO INTO #pono from dbo.split(@PO_NO,',')
-- where data is not null
--select cast(data as int) [STATUS] INTO #status from dbo.split(@STATUS,',')
-- where data is not null
DECLARE @FIELD nvarchar(20)
SET @FIELD = @Action
--- FIELD Def for report From here
SELECT
a.ASSET_NO
,a.DATE_RECEIVED as DATE_OPRT
,a.DATE_EFFECTIVE_REGISTERED as DATE_EFFECTIVE
,a.DATE_REGISTERED as DATE_MODIFIED
,a.USER_ID_REGIST as USER_ID_MODIFY
,a.DESC_1
,a.DESC_2
,a.DESC_AX
,a.DESC_1
+ CASE WHEN IsNull(a.DESC_2, '') = '' THEN '' ELSE ' ' + a.DESC_2 END
+ CASE WHEN IsNull(a.DESC_AX, '') = '' THEN '' ELSE ' ' + a.DESC_AX END
as ASSET_DESC
,a.MANUFACTURER
,a.MODEL
,a.SERIAL_NO
,a.WEIGHT
,a.ASSETCODE
,a.SITE_CD
,a.ROOM_CD
,a.BUILDING_CD
,a.HOLDER_CD
,a.HOLDER_DESC
,a.STATUS
,Left(a.STATUS_DESC, 10) as STATUS_DESC
,ac.CODE_DESCRIPTION
,a.RM_DESC_1 AS ROOM_DESC
,a.SITE_NAME_1 AS SITE_NAME
,a.BUILDING_NAME
,a.DATE_RECEIVED
,fin.DATE_INSERVICE
,fin.ORIG_COST
,fin.QTY
,fin.PM_FUND_CD as FUND_CD
,fin.CAPITALIZED
,fnd.FUND_DESC
,a.PM_PO_NO as PO_NO
-- Initial values
,u.ORIG_COST AS INIT_COST
,ui.ASSETCODE AS INIT_ASSETCODE
,uR.SITE_CD AS INIT_SITE_CD
,u.ROOM_CD AS INIT_ROOM_CD
,uR.BUILDING_CD AS INIT_BUILDING_CD
,uR.RM_DESC_1 AS INIT_ROOM_DESC
,uR.BUILDING_NAME AS INIT_BUILDING_NAME
,uR.SITE_NAME_1 AS INIT_SITE_NAME
,u.HOLDER_CD AS INIT_HOLDER_CD
,uH.ORG_DESC AS INIT_HOLDER_DESC
,uac.CODE_DESCRIPTION AS INIT_CODE_DESCRIPTION
FROM vAsset as a
LEFT JOIN vAsset_Rgst_Info as u ON a.ASSET_ID = u.ASSET_ID
LEFT JOIN tAssetCode as ac ON a.ASSETCODE = ac.ASSETCODE
LEFT JOIN tAssetFin as fin ON a.ASSET_NO = fin.ASSET_NO
LEFT JOIN tFunding as fnd ON fin.PM_FUND_CD = fnd.FUND_CD
LEFT JOIN tItemCatalog as ui ON u.ITEM_CD = ui.ITEM_CD
LEFT jOIN tAssetCode as uac ON ui.ASSETCODE = uac.ASSETCODE
LEFT JOIN vRoom as uR ON u.ROOM_CD = uR.ROOM_CD
LEFT JOIN tOrganization as uH ON u.HOLDER_CD = uH.ORG_CD
WHERE
( @DATE_OPRT_FROM is null OR a.DATE_RECEIVED >= @DATE_OPRT_FROM )
AND ( @DATE_OPRT_TO is null OR a.DATE_RECEIVED <= @DATE_OPRT_TO )
AND ( @DATE_EFFECTIVE_FROM is null OR a.DATE_EFFECTIVE_REGISTERED >= @DATE_EFFECTIVE_FROM )
AND ( @DATE_EFFECTIVE_TO is null OR a.DATE_EFFECTIVE_REGISTERED <= @DATE_EFFECTIVE_TO )
AND ( @DATE_MODIFIED_FROM is null OR a.DATE_REGISTERED >= @DATE_MODIFIED_FROM )
AND ( @DATE_MODIFIED_TO is null OR a.DATE_REGISTERED <= @DATE_MODIFIED_TO )
-- AND ( @ASSET_NO = '' OR u.ASSET_NO in ( SELECT ASSET_NO from #asset_nos ))
AND ( @ASSET_NO = '' OR u.ASSET_NO = dbo.inlist(@ASSET_NO,u.ASSET_NO))
AND ( @ASSET_NO_FROM = '' OR u.ASSET_NO >= @ASSET_NO_FROM )
AND ( @ASSET_NO_TO = '' OR u.ASSET_NO <= @ASSET_NO_TO )
-- AND ( @HOLDER_CD = '' OR a.HOLDER_CD in ( SELECT HOLDER_CD from #holders ))
AND ( @HOLDER_CD = '' OR a.HOLDER_CD =dbo.inlist(@HOLDER_CD,a.HOLDER_CD))
AND ( @HOLDER_CD_FROM = '' OR a.HOLDER_CD >= @HOLDER_CD_FROM )
AND ( @HOLDER_CD_TO = '' OR a.HOLDER_CD <= @HOLDER_CD_TO )
-- AND ( @SITE_CD = '' OR a.SITE_CD in ( SELECT SITE_CD from #site ))
AND ( @SITE_CD = '' OR a.SITE_CD =dbo.inlist(@SITE_CD,a.SITE_CD))
AND ( @SITE_CD_FROM = '' OR a.SITE_CD >= @SITE_CD_FROM )
AND ( @SITE_CD_TO = '' OR a.SITE_CD <= @SITE_CD_TO )
-- AND ( @ASSETCODE = '' OR a.ASSETCODE in ( SELECT ASSETCODE from #assetcode ))
AND ( @ASSETCODE = '' OR a.ASSETCODE =dbo.inlist(@ASSETCODE,a.ASSETCODE))
AND ( @ASSETCODE_FROM is null OR a.ASSETCODE >= @ASSETCODE_FROM )
AND ( @ASSETCODE_TO is null OR a.ASSETCODE <= @ASSETCODE_TO )
-- PM_FUND_CD qualified by a.PM_FUND_CD
--AND ( @FUND_CD = '' OR PM_FUND_CD in ( SELECT FUND_CD from #fundcode ))
AND ( @FUND_CD = '' OR a.PM_FUND_CD =dbo.inlist(@FUND_CD,a.PM_FUND_CD))
AND ( @FUND_CD_FROM = '' OR fin.PM_FUND_CD >= @FUND_CD_FROM )
AND ( @FUND_CD_TO = '' OR fin.PM_FUND_CD <= @FUND_CD_TO )
-- AND ( @PO_NO = '' OR a.PM_PO_NO in ( SELECT PO_NO from #pono ))
AND ( @PO_NO = '' OR a.PM_PO_NO =dbo.inlist(@PO_NO,a.PM_PO_NO))
AND ( @PO_NO_FROM = '' OR a.PM_PO_NO >= @PO_NO_FROM )
AND ( @PO_NO_TO = '' OR a.PM_PO_NO <= @PO_NO_TO )
-- AND ( @STATUS = '' OR a.STATUS in ( SELECT [STATUS] from #status ))
AND ( @STATUS = '' OR a.STATUS =dbo.inlist(@STATUS,a.STATUS))
AND ( @STATUS_FROM is null OR a.STATUS >= @STATUS_FROM )
AND ( @STATUS_TO is null OR a.STATUS <= @STATUS_TO )
AND ( @UNITPRICE_FROM is null OR fin.UNIT_COST >= @UNITPRICE_FROM )
AND ( @UNITPRICE_TO is null OR fin.UNIT_COST <= @UNITPRICE_TO )
AND ( @CAPITALIZED is null OR fin.CAPITALIZED = @CAPITALIZED )
END -- proc
go
更新:
根据评论,
“您所描述的在存储过程中不起作用,因为参数值事先未知。”
参数值确实是已知的时间头,因为它们是在存储过程头中接收的。标量函数在调用时执行,并根据 SP 传递的参数返回值或 null。
例如:片段代码
AND ( @ASSETCODE = '' OR a.ASSETCODE =dbo.inlist(@ASSETCODE,a.ASSETCODE))
@ASSETCODE 是一个参数值(分隔列表)
a.ASSETCODE 是当前行的值
所以,这个表达式被及时评估并返回真/假
OP中使用的其他六个列表相同
以下测试用例模拟了我的回答中使用的标量函数 {inlist} 的使用:
create procedure test_delimeted_list (
@list1 nvarchar(100)
)
as
begin
select * from products p
where p.ProductID = dbo.[inList](@list1,p.productid)
end
go
测试 1:列表有一个值
exec test_delimeted_list '2,500,610' -- 2 is existing
北风数据库返回数据:
ProductID ProductName SupplierID CategoryID QuantityPerUnit UnitPrice UnitsInStock UnitsOnOrder ReorderLevel Discontinued
2 Chang 1 1 24 - 12 oz bottles 19.00 17 40 25 0
测试 2:列表为空
exec test_delimeted_list null
返回数据为空
我希望 OP 测试我的代码并为缺少或不起作用的内容提供评论。
关于SQL Server : query simplification - many joins and a giant WHERE section,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31686927/