SQL Server : query simplification - many joins and a giant WHERE section - sql

I am trying to run a stored procedure, but it keeps timing out from using too much ram. The server its being run on only has 1.5GB of ram to work with. Here is the original query:
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
I added some subquerying to speed it up, but it still times out:
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
I'm at a loss now. Seems there is simply too much data to process on too small a server.

The modifications are:
1) create a new scalar function to test if data exist in delimited comma text and no need to create #temp tables to check if data exist.
-- 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
we replace the expression in where condition, as in the following example:
-- AND ( #ASSET_NO = '' OR u.ASSET_NO in ( SELECT ASSET_NO from #asset_nos ))
modified to:
AND ( #ASSET_NO = '' OR u.ASSET_NO = dbo.inlist(#ASSET_NO,u.ASSET_NO))
and the same for all delimited lists
2) As you use many null parameters, recompile SP before execution to get fresh execution plan ( WITH RECOMPILE)
3) The modified code:
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
Update:
Based on the comments that
"What you have described will not work in a stored procedure because the parameter values are not known ahead of time."
The parameter values are really known a head of time,because they are received in the stored procedure header. The scalar function is executed in time of call and return value or null based on the passed parameters of the SP.
for example: The snippet code
AND ( #ASSETCODE = '' OR a.ASSETCODE =dbo.inlist(#ASSETCODE,a.ASSETCODE))
#ASSETCODE is a parameter value (delimited list )
a.ASSETCODE is the value of the current row
so, this expression is evaluated in time and return true/false
The same for the other six lists used in OP
The following test case simulate the use of the scalar function {inlist} as used in my answer:
create procedure test_delimeted_list (
#list1 nvarchar(100)
)
as
begin
select * from products p
where p.ProductID = dbo.[inList](#list1,p.productid)
end
go
Test1: list has a value
exec test_delimeted_list '2,500,610' -- 2 is existing
The return data from northwind database :
ProductID ProductName SupplierID CategoryID QuantityPerUnit UnitPrice UnitsInStock UnitsOnOrder ReorderLevel Discontinued
2 Chang 1 1 24 - 12 oz bottles 19.00 17 40 25 0
Test2: list is null
exec test_delimeted_list null
The return data is null
I hope the OP test my code and provide comments for something missing or not working.

There is lot of scope of improving your query .
i) From DBA point of view : you need to understand table structure .
ii) Query can also be improve :If business logic and table purpose is clear.
BTW,Alter proc is more confusing .
I am only talking about very genral thing.
Improvement no. 1 : Instead of so many passing comma seperated value.you can create single Table type with as many columns and pass it as parameter.Then you can directly join them in your query. This is one time effort,but will save so many query in your proc.
Improvement 2 : Are you sure about so may Left join.Can we convert some into Inner join ?
Improvement 3 : There is no pagination.Are you trying to pull million of records?
Improvement 4 :For Example,#UNITPRICE_FROM is not null then is it possible that #UNITPRICE_TO is null.
Improvment No 5 : Some of your parameter and there use in where condition suggest that,data type are wrongly implemently,like
#ASSET_NO nvarchar(4000) = '', #ASSET_NO_FROM nvarchar(20) = ''
As far as I know > or < operator best suited for int or datetime type.
I am coming to #FranciscoGoldenstein point of view but lets make few thing clear and improve few thing.
Now let me hear from you.

Related

BizTalk 2013R2 SQL Query Timeouts

Using BizTalk to call a SQL Server stored procedure (see below), which:
Writes data to 5 tables
Checks each table to see if the record exists
Updates or Inserts accordingly
The problem is that when BizTalk receives hundreds of calls, the stored procedure is called each time which appears to add an overhead to the SQL Server and eventually causes timeout errors returned in BizTalk, resulting in the data not being written to the database.
Can anyone advise on the best way to optimise my query so that it processes these tables without much overhead, or have I got it optimised enough already?
USE [MDH]
GO
/****** Object: StoredProcedure [dbo].[spcuPersonStudentProgrammeModule] Script Date: 8/15/2022 2:29:04 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spcuPersonStudentProgrammeModule]
-- person/personref params
#student_id VARCHAR(max)
,#account_id VARCHAR(max) = NULL
,#prefix_honorific VARCHAR(max) = NULL
,#first_name VARCHAR(max) = NULL
,#middle_name VARCHAR(max) = NULL
,#surname VARCHAR(max) = NULL
,#familiar_name VARCHAR(max) = NULL
,#date_of_birth DATE = NULL
,#external_email_address VARCHAR(max) = NULL
,#mobile_phone_no VARCHAR(max) = NULL
,#gender VARCHAR(max) = NULL
,#ethnicity VARCHAR(max) = NULL
,#domicile VARCHAR(max) = NULL
,#disability VARCHAR(max) = NULL
,#nationality VARCHAR(max) = NULL
,#telephone_no VARCHAR(max) = NULL
,#prev_surname VARCHAR(max) = NULL
,#country_of_birth VARCHAR(max) = NULL
-- student params
,#student_email_address VARCHAR(max) = NULL
,#currently_studying_flag VARCHAR(max) = NULL
,#HesaStudentID VARCHAR(max) = NULL
,#UCAS_ID VARCHAR(max) = NULL
,#uln VARCHAR(max) = NULL
,#VisaReq VARCHAR(max) = NULL
,#PurposeOfResidency VARCHAR(max) = NULL
,#cas_status VARCHAR(max) = NULL
,#student_status VARCHAR(max) = NULL
,#source_system VARCHAR(max) = NULL
,#main_programme_code VARCHAR(max) = NULL
,#type VARCHAR(max) = NULL
,#student_support_no VARCHAR(max) = NULL
,#exam_id VARCHAR(max) = NULL
,#su_opt VARCHAR(max) = NULL
,#change_type VARCHAR(max) = NULL
,#international_sponsored_students varchar(80) = null
,#visa_type VARCHAR(max) = null
-- student_programmes params
,#programme_code VARCHAR(50)
,#programme_description VARCHAR(MAX) = NULL
,#start_date DATETIME = NULL
,#end_date DATETIME = NULL
,#mdh_stage_code VARCHAR(MAX) = NULL
,#main_award_flag VARCHAR(10) = NULL
,#load_category VARCHAR(10) = NULL
,#qualification_level VARCHAR(10) = NULL
,#student_study_level VARCHAR(10) = NULL
,#school_code VARCHAR(10) = NULL
,#college_code VARCHAR(10) = NULL
,#campus_code VARCHAR(10) = NULL
,#graduate_yn VARCHAR(10) = NULL
,#is_wbdl VARCHAR(80) = NULL
,#ul_qual_aim VARCHAR(MAX) = NULL
,#ul_qual_aim_desc VARCHAR(MAX) = NULL
-- student_modules params
,#module_code VARCHAR(50)
,#module_desc VARCHAR(MAX) = NULL
,#mod_date_time DATETIME = NULL
-- student_address params
,#perm_address1 VARCHAR(50) = NULL
,#perm_address2 VARCHAR(50) = NULL
,#perm_address3 VARCHAR(50) = NULL
,#perm_address4 VARCHAR(50) = NULL
,#perm_address5 VARCHAR(50) = NULL
,#perm_postcode VARCHAR(50) = NULL
,#perm_country_code VARCHAR(50) = NULL
,#term_address1 VARCHAR(50) = NULL
,#term_address2 VARCHAR(50) = NULL
,#term_address3 VARCHAR(50) = NULL
,#term_address4 VARCHAR(50) = NULL
,#term_address5 VARCHAR(50) = NULL
,#term_postcode VARCHAR(50) = NULL
,#term_country_code VARCHAR(50) = NULL
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
DECLARE #person_id UNIQUEIDENTIFIER
SET NOCOUNT ON;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
-- Create/Update person_test/person_reference_test
IF EXISTS ( SELECT person_id FROM dbo.person_reference WHERE account_id = #account_id and ISNULL(status,'') <> 'Delete')
BEGIN
SELECT 'Student exists, updating'
SET #person_id = ( SELECT person_id FROM dbo.person_reference WITH (NOLOCK) WHERE account_id = #account_id and ISNULL(status,'') <> 'Delete')
UPDATE person
SET prefix_honorific = CASE WHEN #prefix_honorific = 'null' or #prefix_honorific is null or #prefix_honorific = '' THEN prefix_honorific ELSE #prefix_honorific END
,first_name = ISNULL(#first_name, first_name)
,middle_name = ISNULL(#middle_name, middle_name)
,surname = ISNULL(#surname, surname)
,familiar_name = #familiar_name
,date_of_birth = ISNULL(#date_of_birth, date_of_birth)
,external_email_address = ISNULL(#external_email_address, external_email_address)
,gender = ISNULL(#gender, gender)
,ethnicity = ISNULL(#ethnicity, ethnicity)
,domicile = ISNULL(#domicile, domicile)
,disability = ISNULL(#telephone_no, disability)
,telephone_no = ISNULL(#telephone_no, telephone_no)
,prev_surname = ISNULL(#prev_surname, prev_surname)
,country_of_birth = ISNULL(#country_of_birth, country_of_birth)
,proc_date_time = GETDATE()
,mobile_phone_no = ISNULL(#mobile_phone_no, mobile_phone_no)
,nationality = ISNULL(#nationality, nationality)
WHERE person_id_guid = #person_id
IF #account_id IS NOT NULL
BEGIN
UPDATE dbo.person_reference
SET account_id = #account_id
,proc_date_time = GETDATE()
WHERE person_id = #person_id
END
END
ELSE
BEGIN
SELECT 'Student does not exist, creating'
--INSERT person
SET #person_id = NEWID()
INSERT INTO dbo.person (
person_id_guid
,prefix_honorific
,first_name
,middle_name
,surname
,familiar_name
,date_of_birth
,external_email_address
,mobile_phone_no
,gender
,ethnicity
,domicile
,disability
,nationality
,telephone_no
,prev_surname
,country_of_birth
,source_system
,proc_date_time
)
VALUES (
#person_id
,#prefix_honorific
,#first_name
,#middle_name
,#surname
,#familiar_name
,#date_of_birth
,#external_email_address
,#mobile_phone_no
,#gender
,#ethnicity
,#domicile
,#disability
,#nationality
,#telephone_no
,#prev_surname
,'OneUni'
,#country_of_birth
,GETDATE()
)
--INSERT person_reference
INSERT INTO dbo.person_reference (
person_id
,student_id
,proc_date_time
,account_id
)
VALUES (
#person_id
,#student_id
,GETDATE()
,#account_id
)
END
-- Create/Update student
IF EXISTS ( SELECT account_id FROM dbo.student WITH (NOLOCK) WHERE account_id = #account_id and ISNULL(status,'') <> 'Delete')
BEGIN
SELECT 'Student exists, updating'
UPDATE student
SET
--account_id = #account_id
--,student_id = #student_id
ucas_id = #UCAS_ID
,unique_learner_number = #uln
,main_programme_code = isnull(#main_programme_code, main_programme_code)
,student_email_address = #student_email_address
,currently_studying_flag = #currently_studying_flag
,hesa_student_id = #HesaStudentID
,visa_required = #VisaReq
,cas_status = #cas_status
,student_status = #student_status
,purpose_of_residency = #PurposeOfResidency
,mod_date_time = GETDATE()
,student_support_no = #student_support_no
,source_system = #source_system
,exam_id = #exam_id
,su_opt = #su_opt
,international_sponsored_students = #international_sponsored_students
,visa_type = #visa_type
WHERE account_id = #account_id
END
-- Create Student/Student Programme/Student Module
ELSE
BEGIN
SELECT 'Student does not exist, creating'
SET #person_id = ( SELECT person_id FROM dbo.person_reference WITH (NOLOCK) WHERE account_id = #account_id and ISNULL(status,'') <> 'Delete')
INSERT INTO student (
person_id_guid
,account_id
,ucas_id
,unique_learner_number
,student_email_address
,currently_studying_flag
,hesa_student_id
,visa_required
,cas_status
,student_status
,purpose_of_residency
,proc_date_time
,source_system
,main_programme_code
,student_id
,student_support_no
,exam_id
,su_opt
,international_sponsored_students
,visa_type
)
VALUES (
#person_id
,#account_id
,#UCAS_ID
,#uln
,#student_email_address
,#currently_studying_flag
,#HesaStudentID
,#VisaReq
,#cas_status
,#student_status
,#PurposeOfResidency
,getdate()
,#source_system
,#main_programme_code
,#student_id
,#student_support_no
,#exam_id
,#su_opt
,#international_sponsored_students
,#visa_type
)
END
-- Create/Update student_programmes if change_record is 'Course'
IF #change_type = 'Programme'
BEGIN
-- Create/Update student_programmes
IF EXISTS ( SELECT student_id FROM student_programmes WITH (NOLOCK) WHERE account_id = #account_id and programme_code = #programme_code)
BEGIN
SELECT 'Student Programme exists, updating'
--UPDATE student_programme? (Wait for confirmation)
UPDATE student_programmes
SET
--account_id = #account_id
--,student_id = #student_id
--course_code = #course_code
programme_description = #programme_description
,[start_date] = #start_date
,end_date = #end_date
,mdh_stage_code = #mdh_stage_code
,main_award_flag = #main_award_flag
,load_category = #load_category
,qualification_level = #qualification_level
,student_study_level = #student_study_level
,is_wbdl = #is_wbdl
,school_code = #school_code
,college_code = #college_code
,campus_code = #campus_code
,ul_qual_aim = #ul_qual_aim
,ul_qual_aim_description = #ul_qual_aim_desc
,mod_date_time = GETDATE()
WHERE account_id = #account_id
and programme_code = #programme_code
END
ELSE
BEGIN
SELECT 'Student Programme does not exist, creating'
SET #person_id = ( SELECT person_id FROM dbo.person_reference WITH (NOLOCK) WHERE account_id = #account_id and ISNULL(status,'') <> 'Delete')
--INSERT student_programme
INSERT INTO student_programmes (
person_id_guid
,account_id
,student_id
,programme_code
,programme_description
,[start_date]
,end_date
,mdh_stage_code
,main_award_flag
,load_category
,qualification_level
,student_study_level
,is_wbdl
,school_code
,college_code
,campus_code
,ul_qual_aim
,ul_qual_aim_description
,mod_date_time
)
VALUES (
#person_id
,#account_id
,#student_id
,#programme_code
,#programme_description
,#start_date
,#end_date
,#mdh_stage_code
,#main_award_flag
,#load_category
,#qualification_level
,#student_study_level
,#is_wbdl
,#school_code
,#college_code
,#campus_code
,#ul_qual_aim
,#ul_qual_aim_desc
,GETDATE()
)
END
END
-- Create/Update student_modules if change_record is 'Module'
IF #change_type = 'Module'
BEGIN
IF EXISTS ( SELECT student_id FROM student_modules WITH (NOLOCK) WHERE account_id = #account_id and programme_code = #programme_code and module_code = #module_code)
BEGIN
SELECT 'Student Module exists, updating'
--UPDATE student_module? (Wait for confirmation)
UPDATE student_modules
SET
--account_id = #account_id
--,student_id = #student_id
--course_code = #course_code
--module_code = #module_code
module_description = #module_desc
,mdh_stage_code = #mdh_stage_code
,student_study_level = #student_study_level
,mod_date_time = GETDATE()
WHERE account_id = #account_id
and programme_code = #programme_code
and module_code = #module_code
END
ELSE
BEGIN
SELECT 'Student Module does not exist, creating'
SET #person_id = ( SELECT person_id FROM dbo.person_reference WITH (NOLOCK) WHERE account_id = #account_id and ISNULL(status,'') <> 'Delete')
-- If the programme for the module/student doesnt exist, insert it
IF NOT EXISTS ( SELECT student_id FROM dbo.student_programmes WITH (NOLOCK) WHERE account_id = #account_id and programme_code = #programme_code)
BEGIN
SET #person_id = ( SELECT person_id FROM dbo.person_reference WITH (NOLOCK) WHERE account_id = #account_id )
--INSERT student_programme
INSERT INTO student_programmes (
person_id_guid
,account_id
,student_id
,programme_code
,programme_description
,[start_date]
,end_date
,mdh_stage_code
,main_award_flag
,load_category
,qualification_level
,student_study_level
,is_wbdl
,school_code
,college_code
,campus_code
,ul_qual_aim
,ul_qual_aim_description
,mod_date_time
)
VALUES (
#person_id
,#account_id
,#student_id
,#programme_code
,#programme_description
,#start_date
,#end_date
,#mdh_stage_code
,#main_award_flag
,#load_category
,#qualification_level
,#student_study_level
,#is_wbdl
,#school_code
,#college_code
,#campus_code
,#ul_qual_aim
,#ul_qual_aim_desc
,GETDATE()
)
END
--INSERT student_module
INSERT INTO student_modules (
person_id_guid
,account_id
,student_id
,programme_code
,module_code
,module_description
,mdh_stage_code
,student_study_level
,mod_date_time
)
VALUES (
#person_id
,#account_id
,#student_id
,#programme_code
,#module_code
,#module_desc
,#mdh_stage_code
,#student_study_level
,GETDATE()
)
END
END
END

Parameterized stored procedure union all which is conditional with left joins

I want to do, I think, a UNION ALL query so I can return the results from my order table based on the manufacturer id entered in a search field.
Order links to > OrderItem which then can be linked to Product.
I have manually typed up the query, and it works but I'm having trouble making it conditional in my stored procedure.
Here is the query I typed up manually:
SELECT TOP 100 *
FROM [Test].[dbo].[Order] o
LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
LEFT JOIN [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
WHERE p.[ManufacturerId] = 'mid'
Here is my stored procedure:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
#OrderId INT = 0,
#CustomerId INT = 0,
#ProductId INT = 0,
#WarehouseId INT = 0,
#BillingCountryId INT = 0,
#PaymentMethodSystemName NVARCHAR(MAX) = NULL,
#OrderStatusId INT = 0,
#PaymentStatusId INT = 0,
#ShippingStatusId INT = 0,
#BillingEmail NVARCHAR(MAX) = NULL,
#BillingFirstName NVARCHAR(MAX) = NULL,
#BillingLastName NVARCHAR(MAX) = NULL,
#ManCode NVARCHAR(MAX) = NULL,
#Current BIT = NULL,
#ShippingMethod NVARCHAR(MAX) = NULL,
#CreatedFromUtc DATETIME = NULL,
#CreatedToUtc DATETIME = NULL,
#PageIndex INT = 0,
#PageSize INT = 2147483644,
#TotalRecords INT = NULL OUTPUT
AS
BEGIN
DECLARE #sql NVARCHAR(MAX)
SET NOCOUNT ON;
CREATE TABLE #TempTotal (RowNum INT IDENTITY(1,1), id INT);
CREATE INDEX #IK_temp ON #TempTotal (RowNum);
INSERT INTO #TempTotal ([id])
SELECT o.[Id]
FROM [Test].[dbo].[Order] o WITH (NOLOCK)
LEFT JOIN [Test].[dbo].[Address] a ON a.Id = o.BillingAddressId
AND (COALESCE(#BillingEmail, '') <> ''
OR COALESCE(#BillingFirstName, '') <> ''
OR COALESCE(#BillingLastName, '') <> '')
/* LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.OrderId = o.Id
AND (COALESCE(#ManCode,'') <> '')
LEFT join [Test].[dbo].[Product] p ON p.Id = oi.ProductId
AND (COALESCE(#ManCode, '') <> '')*/
WHERE (#BillingEmail IS NULL OR a.[Email] = #BillingEmail)
AND (#BillingFirstName IS NULL OR a.[FirstName] = #BillingFirstName)
AND (#BillingLastName IS NULL OR a.[LastName] = #BillingLastName)
-- AND (#ManCode IS NULL OR p.[ManufacturerId] = #ManCode)
UNION ALL
(SELECT *
FROM [Test].[dbo].[Product] p
LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
LEFT JOIN [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
WHERE (#ManCode IS NULL OR p.[ManufacturerId] = #ManCode))
AND -- here is error
o.[Deleted] = 0
AND (o.[Id] = #OrderId OR #OrderId = 0)
AND (o.[CustomerId] = #CustomerId OR #CustomerId = 0)
AND (o.[WarehouseId] = #WarehouseId OR #WarehouseId = 0)
AND (#PaymentMethodSystemName IS NULL OR o.[PaymentMethodSystemName] = #PaymentMethodSystemName)
AND (o.[OrderStatusId] = #OrderStatusId OR #OrderStatusId = 0)
AND (o.[PaymentStatusId] = #PaymentStatusId OR #PaymentStatusId = 0)
AND (o.[ShippingStatusId] = #ShippingStatusId OR #ShippingStatusId = 0)
AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId] != '40'))) OR #Current = 0)
AND o.[CreatedOnUtc] >= ISNULL(#CreatedFromUtc, '1/1/1900')
AND o.[CreatedOnUtc] < ISNULL(#CreatedToUtc, '1/1/2999')
ORDER BY
o.[CreatedOnUtc] DESC;
--paging
DECLARE #PageLowerBound INT
SET #PageLowerBound = #PageSize * #PageIndex
-- Return the paged records
SELECT
[Id], [OrderGuid], [StoreId], [CustomerId],
[BillingAddressId], [ShippingAddressId],
[OrderStatusId], [ShippingStatusId],
[PaymentStatusId], [PaymentMethodSystemName],
[TaxRates], [OrderTax], [OrderDiscount], [OrderTotal],
[ShippingMethod], [CustomValuesXml], [Deleted],
[CreatedOnUtc], [EditedStatusId],
[WarehouseId], [PrintedOnUtc]
FROM
[Test].[dbo].[Order] ord
WHERE
ord.[Id] IN (SELECT id FROM #TempTotal tt)
ORDER BY
ord.[CreatedOnUtc] DESC
OFFSET #PageLowerBound ROWS FETCH NEXT #PageSize ROWS ONLY;
--total records
SELECT #TotalRecords = COUNT(*) FROM #TempTotal;
DROP TABLE #TempTotal
END
I'm not sure if UNION ALL is what I need but I feel like it is. I also tried the left joins which are commented out but didn't have any luck there.
Also here is a screenshot of the error at the AND statement.
Anyone able to help me here?
USE [Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
#OrderId int = 0,
#CustomerId int = 0,
#ProductId int = 0,
#WarehouseId int = 0,
#BillingCountryId int = 0,
#PaymentMethodSystemName nvarchar(max) = null,
#OrderStatusId int = 0,
#PaymentStatusId int = 0,
#ShippingStatusId int = 0,
#BillingEmail nvarchar(max) = null,
#BillingFirstName nvarchar(max) = null,
#BillingLastName nvarchar(max) = null,
#ManCode nvarchar(max) = null,
#Current bit = null,
#ShippingMethod nvarchar(max) = null,
#CreatedFromUtc datetime = null,
#CreatedToUtc datetime = null,
#PageIndex int = 0,
#PageSize int = 2147483644,
#TotalRecords int = null OUTPUT
AS
BEGIN
DECLARE
#sql nvarchar(max)
SET NOCOUNT ON;
create table #TempTotal (RowNum int identity(1,1), id int);
create index #IK_temp on #TempTotal (RowNum);
INSERT INTO #TempTotal ([id])
SELECT o.[Id]
FROM [Test].[dbo].[Order] o with (NOLOCK)
LEFT join [Test].[dbo].[Address] a on a.Id = o.BillingAddressId and (
coalesce(#BillingEmail,'') <> ''
or coalesce(#BillingFirstName,'') <> ''
or coalesce(#BillingLastName,'') <> ''
)
/*LEFT join [Test].[dbo].[OrderItem] oi on oi.OrderId = o.Id and (
coalesce(#ManCode,'') <> ''
)
LEFT join [Test].[dbo].[Product] p on p.Id = oi.ProductId and (
coalesce(#ManCode,'') <> ''
)*/
WHERE (#BillingEmail IS null OR a.[Email] = #BillingEmail)
AND (#BillingFirstName IS null OR a.[FirstName] = #BillingFirstName)
AND (#BillingLastName IS null OR a.[LastName] = #BillingLastName)
--AND (#ManCode IS null OR p.[ManufacturerId] = #ManCode)
UNION ALL
select oi.[Id] from [Test].[dbo].[Product] p
LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
LEFT JOIN [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
WHERE (#ManCode IS null OR p.[ManufacturerId] = #ManCode)
AND -- here is error
o.[Deleted] = 0
AND (o.[Id] = #OrderId OR #OrderId = 0)
AND (o.[CustomerId] = #CustomerId OR #CustomerId = 0)
AND (o.[WarehouseId] = #WarehouseId OR #WarehouseId = 0)
AND (#PaymentMethodSystemName IS null OR o.[PaymentMethodSystemName] = #PaymentMethodSystemName)
AND (o.[OrderStatusId] = #OrderStatusId OR #OrderStatusId = 0)
AND (o.[PaymentStatusId] = #PaymentStatusId OR #PaymentStatusId = 0)
AND (o.[ShippingStatusId] = #ShippingStatusId OR #ShippingStatusId = 0)
AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId] != '40'))) OR #Current = 0)
AND o.[CreatedOnUtc] >= ISNULL(#CreatedFromUtc, '1/1/1900')
AND o.[CreatedOnUtc] < ISNULL(#CreatedToUtc, '1/1/2999')
ORDER BY o.[CreatedOnUtc] DESC;
--paging
DECLARE #PageLowerBound int
SET #PageLowerBound = #PageSize * #PageIndex
-- Return the paged records
select [Id]
,[OrderGuid]
,[StoreId]
,[CustomerId]
,[BillingAddressId]
,[ShippingAddressId]
,[OrderStatusId]
,[ShippingStatusId]
,[PaymentStatusId]
,[PaymentMethodSystemName]
,[TaxRates]
,[OrderTax]
,[OrderDiscount]
,[OrderTotal]
,[ShippingMethod]
,[CustomValuesXml]
,[Deleted]
,[CreatedOnUtc]
,[EditedStatusId]
,[WarehouseId]
,[PrintedOnUtc]
from [Test].[dbo].[Order] ord
where ord.[Id] in (
select id
from #TempTotal tt
)
ORDER BY ord.[CreatedOnUtc] DESC
OFFSET #PageLowerBound ROWS FETCH NEXT #PageSize ROWS ONLY;
--total records
select #TotalRecords = count(*) from #TempTotal;
DROP TABLE #TempTotal
END
ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
#OrderId int = 0,
#CustomerId int = 0,
#ProductId int = 0,
#WarehouseId int = 0,
#BillingCountryId int = 0,
#PaymentMethodSystemName nvarchar(max) = null,
#OrderStatusId int = 0,
#PaymentStatusId int = 0,
#ShippingStatusId int = 0,
#BillingEmail nvarchar(max) = null,
#BillingFirstName nvarchar(max) = null,
#BillingLastName nvarchar(max) = null,
#ManCode nvarchar(max) = null,
#Current bit = null,
#ShippingMethod nvarchar(max) = null,
#CreatedFromUtc datetime = null,
#CreatedToUtc datetime = null,
#PageIndex int = 0,
#PageSize int = 2147483644,
#TotalRecords int = null OUTPUT
AS
BEGIN
DECLARE
#sql nvarchar(max)
SET NOCOUNT ON;
create table #TempTotal (RowNum int identity(1,1), id int);
create index #IK_temp on #TempTotal (RowNum);
INSERT INTO #TempTotal ([id])
SELECT o.[Id]
FROM [Test].[dbo].[Order] o with (NOLOCK)
LEFT join [Test].[dbo].[Address] a on a.Id = o.BillingAddressId and (
coalesce(#BillingEmail,'') <> ''
or coalesce(#BillingFirstName,'') <> ''
or coalesce(#BillingLastName,'') <> ''
)
/*LEFT join [Test].[dbo].[OrderItem] oi on oi.OrderId = o.Id and (
coalesce(#ManCode,'') <> ''
)
LEFT join [Test].[dbo].[Product] p on p.Id = oi.ProductId and (
coalesce(#ManCode,'') <> ''
)*/
WHERE (#BillingEmail IS null OR a.[Email] = #BillingEmail)
AND (#BillingFirstName IS null OR a.[FirstName] = #BillingFirstName)
AND (#BillingLastName IS null OR a.[LastName] = #BillingLastName)
--AND (#ManCode IS null OR p.[ManufacturerId] = #ManCode)
UNION ALL
SELECT * FROM
(
select * from [Test].[dbo].[Product] p
LEFT JOIN [Test].[dbo].[OrderItem] oi ON oi.[OrderId] = o.[Id]
LEFT JOIN [Test].[dbo].[Product] p ON p.[Id] = oi.[ProductId]
WHERE (#ManCode IS null OR p.[ManufacturerId] = #ManCode)
)O
WHERE -- here is error (Here Procdure Can't Findout the object O) ---So, take 'O' Object Outside........
o.[Deleted] = 0
AND (o.[Id] = #OrderId OR #OrderId = 0)
AND (o.[CustomerId] = #CustomerId OR #CustomerId = 0)
AND (o.[WarehouseId] = #WarehouseId OR #WarehouseId = 0)
AND (#PaymentMethodSystemName IS null OR o.[PaymentMethodSystemName] = #PaymentMethodSystemName)
AND (o.[OrderStatusId] = #OrderStatusId OR #OrderStatusId = 0)
AND (o.[PaymentStatusId] = #PaymentStatusId OR #PaymentStatusId = 0)
AND (o.[ShippingStatusId] = #ShippingStatusId OR #ShippingStatusId = 0)
AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId] != '40'))) OR #Current = 0)
AND o.[CreatedOnUtc] >= ISNULL(#CreatedFromUtc, '1/1/1900')
AND o.[CreatedOnUtc] < ISNULL(#CreatedToUtc, '1/1/2999')
ORDER BY o.[CreatedOnUtc] DESC;
--paging
DECLARE #PageLowerBound int
SET #PageLowerBound = #PageSize * #PageIndex
-- Return the paged records
select [Id]
,[OrderGuid]
,[StoreId]
,[CustomerId]
,[BillingAddressId]
,[ShippingAddressId]
,[OrderStatusId]
,[ShippingStatusId]
,[PaymentStatusId]
,[PaymentMethodSystemName]
,[TaxRates]
,[OrderTax]
,[OrderDiscount]
,[OrderTotal]
,[ShippingMethod]
,[CustomValuesXml]
,[Deleted]
,[CreatedOnUtc]
,[EditedStatusId]
,[WarehouseId]
,[PrintedOnUtc]
from [Test].[dbo].[Order] ord
where ord.[Id] in (
select id
from #TempTotal tt
)
ORDER BY ord.[CreatedOnUtc] DESC
OFFSET #PageLowerBound ROWS FETCH NEXT #PageSize ROWS ONLY;
--total records
select #TotalRecords = count(*) from #TempTotal;
DROP TABLE #TempTotal
END
Note:- (Here Procdure Can't Findout the object O) ---So, take 'O' Object Outside........If can't find out object (alias) ...so it will not work in where condition......
Ok so I figured this out, I needed to use a select statement with a left join which is dependent on the #ManCode parameter not being null.
Paging still works fine too, without having to add extra temp tables :)
Here is how I did it:
AND (#ManCode IS null OR EXISTS (
SELECT [OrderId], [ManufacturerId] FROM [Test].[dbo].[OrderItem] oi with (NOLOCK)
LEFT join [Test].[dbo].[Product] p on p.ManufacturerId = oi.ManufacturerId
WHERE oi.OrderId = o.Id AND p.[ManufacturerId] = '' + #ManCode + ''))
So now my full updated stored procedure looks like so:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[OrderLoadAllPaged]
#OrderId INT = 0,
#CustomerId INT = 0,
#ProductId INT = 0,
#WarehouseId INT = 0,
#BillingCountryId INT = 0,
#PaymentMethodSystemName NVARCHAR(MAX) = NULL,
#OrderStatusId INT = 0,
#PaymentStatusId INT = 0,
#ShippingStatusId INT = 0,
#BillingEmail NVARCHAR(MAX) = NULL,
#BillingFirstName NVARCHAR(MAX) = NULL,
#BillingLastName NVARCHAR(MAX) = NULL,
#ManCode NVARCHAR(MAX) = NULL,
#Current BIT = NULL,
#ShippingMethod NVARCHAR(MAX) = NULL,
#CreatedFromUtc DATETIME = NULL,
#CreatedToUtc DATETIME = NULL,
#PageIndex INT = 0,
#PageSize INT = 2147483644,
#TotalRecords INT = NULL OUTPUT
AS
BEGIN
DECLARE #sql NVARCHAR(MAX)
SET NOCOUNT ON;
CREATE TABLE #TempTotal (RowNum INT IDENTITY(1,1), id INT);
CREATE INDEX #IK_temp ON #TempTotal (RowNum);
INSERT INTO #TempTotal ([id])
SELECT o.[Id]
FROM [Test].[dbo].[Order] o WITH (NOLOCK)
LEFT JOIN [Test].[dbo].[Address] a ON a.Id = o.BillingAddressId
AND (COALESCE(#BillingEmail, '') <> ''
OR COALESCE(#BillingFirstName, '') <> ''
OR COALESCE(#BillingLastName, '') <> '')
WHERE (#BillingEmail IS NULL OR a.[Email] = #BillingEmail)
AND (#BillingFirstName IS NULL OR a.[FirstName] = #BillingFirstName)
AND (#BillingLastName IS NULL OR a.[LastName] = #BillingLastName)
AND (#ManCode IS null OR EXISTS (
SELECT [OrderId], [ManufacturerId] FROM [Test].[dbo].[OrderItem] oi with (NOLOCK)
LEFT join [Test].[dbo].[Product] p on p.ManufacturerId = oi.ManufacturerId
WHERE oi.OrderId = o.Id AND p.[ManufacturerId] = '' + #ManCode + ''))
AND
o.[Deleted] = 0
AND (o.[Id] = #OrderId OR #OrderId = 0)
AND (o.[CustomerId] = #CustomerId OR #CustomerId = 0)
AND (o.[WarehouseId] = #WarehouseId OR #WarehouseId = 0)
AND (#PaymentMethodSystemName IS NULL OR o.[PaymentMethodSystemName] = #PaymentMethodSystemName)
AND (o.[OrderStatusId] = #OrderStatusId OR #OrderStatusId = 0)
AND (o.[PaymentStatusId] = #PaymentStatusId OR #PaymentStatusId = 0)
AND (o.[ShippingStatusId] = #ShippingStatusId OR #ShippingStatusId = 0)
AND ((o.[OrderStatusId] != '40' AND o.[OrderStatusId] != '30' AND ((o.[ShippingStatusId] != '30' OR o.[ShippingStatusId] != '40') AND o.[Printed] = '0' AND (o.[PaymentStatusId] != '30' OR o.[PaymentStatusId] != '35' OR o.[PaymentStatusId] != '40'))) OR #Current = 0)
AND o.[CreatedOnUtc] >= ISNULL(#CreatedFromUtc, '1/1/1900')
AND o.[CreatedOnUtc] < ISNULL(#CreatedToUtc, '1/1/2999')
ORDER BY
o.[CreatedOnUtc] DESC;
--paging
DECLARE #PageLowerBound INT
SET #PageLowerBound = #PageSize * #PageIndex
-- Return the paged records
SELECT
[Id], [OrderGuid], [StoreId], [CustomerId],
[BillingAddressId], [ShippingAddressId],
[OrderStatusId], [ShippingStatusId],
[PaymentStatusId], [PaymentMethodSystemName],
[TaxRates], [OrderTax], [OrderDiscount], [OrderTotal],
[ShippingMethod], [CustomValuesXml], [Deleted],
[CreatedOnUtc], [EditedStatusId],
[WarehouseId], [PrintedOnUtc]
FROM
[Test].[dbo].[Order] ord
WHERE
ord.[Id] IN (SELECT id FROM #TempTotal tt)
ORDER BY
ord.[CreatedOnUtc] DESC
OFFSET #PageLowerBound ROWS FETCH NEXT #PageSize ROWS ONLY;
--total records
SELECT #TotalRecords = COUNT(*) FROM #TempTotal;
DROP TABLE #TempTotal
END

Give an Explanation for this SQL error "Conversion of a varchar data type to a datetime data type Which resulted in an out-of-range value"

ALTER PROCEDURE [dbo].[TRN_Hold_GetData]
#XMLSearch XML = '<DocumentElement><TRN_Hold_GetData_Custom><HoldId>0</HoldId><FromDate>17-3-2017</FromDate><ToDate>17-2-2017</ToDate></TRN_Hold_GetData_Custom></DocumentElement>'
AS
BEGIN
DECLARE #HoldId INT = 0,
#HoldNo VARCHAR(50) = '',
#Party VARCHAR(100) = '',
#StoneNo VARCHAR(50) = '',
#FromDate VARCHAR(50) = '',
#ToDate VARCHAR(50) = '',
#HoldStatus VARCHAR(20) = '',
#FilterQry NVARCHAR(MAX) = '',
#FinalQry NVARCHAR(MAX) = ''
SELECT
#HoldNo = doc.col.value('HoldNo[1]', 'VARCHAR(50)'),
#Party = doc.col.value('Party[1]', 'VARCHAR(MAX)'),
#StoneNo = doc.col.value('StoneNo[1]', 'VARCHAR(MAX)'),
#FromDate = doc.col.value('FromDate[1]', 'VARCHAR(11)'),
#ToDate = doc.col.value('ToDate[1]', 'VARCHAR(11)'),
#HoldStatus = doc.col.value('HoldStatus[1]', 'VARCHAR(20)')
FROM
#XMLSearch.nodes('/DocumentElement/TRN_Hold_GetData_Custom') doc(col)
SELECT
convert(varchar(11), cast(OnHoldDate as datetime), 103),
ISNULL(TH.HoldId, '') AS HoldId,
ISNULL(TH.HoldNo, '') AS HoldNo,
ISNULL(TH.PartyId, '') AS PartyId,
ISNULL(MP.Party, '') AS Party,
ISNULL(TH.OnHoldDate, '') AS HoldDate,
ISNULL(TH.ExpReleaseDays, '') AS ExpReleaseDays,
ISNULL(TH.ExpReleaseDate, '') AS ExpReleaseDate,
ISNULL(TH.TotalPkt, '') AS TotalPkt,
ISNULL(TH.TotalCts, '') AS TotalCts,
HOLDSTONE, RELEASESTONE,
ISNULL(TH.TotalAmount, '') AS TotalAmount,
ISNULL(TH.HoldById, '') AS HoldById,
ISNULL(TH.Remark, '') AS Remark,
ISNULL(MEmp.firstname, '') + ' ' + ISNULL(MEmp.middlename, '') + ' ' + ISNULL(MEmp.lastname, '') AS HoldUser,
ISNULL(MEmp.firstname, '') + ' ' + ISNULL(MEmp.middlename, '') + ' ' + ISNULL(MEmp.lastname, '') AS UnHoldUser
FROM
dbo.TRN_Hold TH WITH ( NOLOCK )
INNER JOIN
( SELECT SUM(CASE WHEN HoldStatus = 0 THEN 1
ELSE 0
END) AS HOLDSTONE, SUM(CASE WHEN HoldStatus = 1 THEN 1
ELSE 0
END) AS RELEASESTONE, HoldId
FROM TRN_Hold_Detail
GROUP BY HoldId ) AS THD ON TH.HoldId = THD.HoldId
INNER JOIN TRN_Hold_Detail AS HDD WITH ( NOLOCK ) ON HDD.HoldId = THD.HoldId
INNER JOIN mst_Stone AS MS WITH ( NOLOCK ) ON HDD.StoneId = MS.Stone_id
LEFT JOIN MST_Party MP ON TH.PartyId = MP.party_id
LEFT JOIN MST_Employee MEmp ON TH.HoldById = MEmp.employee_id
WHERE HoldNo = (
CASE WHEN #HoldNo = '' or #HoldNo is null THEN HoldNo ELSE #HoldNo END ) AND
convert(varchar(11),cast(OnHoldDate as datetime),101)
between
CASE WHEN #FromDate= ''
THEN OnHoldDate
ELSE convert(varchar(11),#FromDate,101)
END
AND
CASE WHEN #ToDate = ''
THEN OnHoldDate
ELSE convert(varchar(11),#ToDate,101)
END
print #FromDate
print #ToDate
--????????????????????????????????????????????????????????????????
--AND ( CASE WHEN convert(varchar(50),cast(#FromDate as datetime),103)= ''
-- THEN convert(varchar(50),cast(#FromDate as datetime),103)
-- ELSE OnHoldDate
-- END ) >= convert(varchar(50),cast(#FromDate as datetime),103)
--AND ( CASE WHEN convert(varchar(50),cast(#ToDate as datetime),103) = ''
-- THEN convert(varchar(50),cast(#ToDate as datetime),103)
-- ELSE OnHoldDate
-- END ) <= convert(varchar(50),cast(#ToDate as datetime),103)
--????????????????????????????????????????????????????????????????
--AND ( #StoneNo = '' OR ms.Stone_no = #stoneNo )
-- --realse
--AND ((#HoldStatus = 'RELEASE' AND ISNULL(THD.HOLDSTONE, 0) = 0 AND ISNULL(THD.RELEASESTONE, 0) <> 0)
-- --Hold
--OR ( #HoldStatus = 'HOLD' AND ISNULL(THD.HOLDSTONE, 0) <> 0 AND ISNULL(THD.RELEASESTONE, 0) = 0)
-- --Partial
--OR (#HoldStatus = 'PARTIAL' AND ISNULL(THD.HOLDSTONE, 0) <> 0 AND ISNULL(THD.RELEASESTONE, 0) <> 0 )
--OR #HoldStatus = 'ALL'
-- )
-- print #FromDate
-- print convert(nvarchar(20), #FromDate ,106)
--print convert(nvarchar(20), #ToDate ,103)
--OnHoldDate between (case when #FromDate ='' then OnHoldDate else #FromDate end)
--and (case when #ToDate = '' then OnHoldDate else #ToDate end)
END
This is my stored proedure; when I execute it, I get the following error
Msg 242, Level 16, State 3, Procedure TRN_Hold_GetData, Line 45
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value
The DateTime in the XML "17-3-2017" can be interpreted in two different ways - one of which 3rd day of 17th month, is not valid. Make sure you use explicit date formats in your XML in line with XML standards (YYYY-MM-DDThh:mm:ss)
You really should have datetime strings in a universal format, as suggested by Phillip. However, if you do not have control this should properly handle your convert pattern:
declare #dAsStr varchar(max) = '17-3-2017'
select convert(datetime, #dAsStr, 105)

Improve case statement in order clause

I have the store sql
ALTER procedure [dbo].[TNNews_User_SearchBasic]
#Title nvarchar(400),
#CategoryId int,
#IsInterested int,
#IsHot int,
#IsTopCategory int,
#IsPublish int,
#PageSize int,
#PageIndex int,
#OrderBy varchar(20),
#PortalId int,
#LanguageId varchar(6)
as
DECLARE #EndTime DATETIME
DECLARE #StartTime DATETIME
SET #StartTime = GETDATE()
declare #tbCategory table(Id int)
DECLARE #StartRowIndex INT
IF #PageSize=0 SELECT #PageSize=count(*) FROM TNNews
IF(#PageIndex<0) SET #PageIndex=0
SET #StartRowIndex = #PageSize*(#PageIndex-1)+1
;WITH tmpCategory(Id, Name,ParentId,Level)
AS (
SELECT
e.Id,
e.Name,
e.ParentId,
1
FROM dbo.TNCategory AS e
WHERE
Id = #CategoryId or (#CategoryId='' and ParentId<=0)
UNION ALL
SELECT
e.Id,
e.Name,
e.ParentId,
Level + 1
FROM dbo.TNCategory AS e
JOIN tmpCategory AS d ON e.ParentId = d.Id
)
insert #tbCategory select Id from tmpCategory
;WITH tmpNews as
(
SELECT
a.Id,a.Title,a.Subject
,ROW_NUMBER() OVER (ORDER BY (Publisheddate) desc) as ThuTuBanGhi
FROM dbo.TNNews a
where 1 = 1
--and ( Title like '%'+#Title+'%')
and (#CategoryId = -1 or exists (select 0 from #tbCategory b where b.Id = a.CategoryId))
and (#IsInterested = -1 or IsIntrested = #IsInterested )
and (#IsHot = -1 or IsHot = #IsHot )
and (#IsTopCategory = -1 or IsTopCategory = #IsTopCategory )
and (#IsPublish = -1 or IsPublished = #IsPublish)
and PortalId=#PortalId
and LanguageId = #LanguageId
)
select *, (select COUNT(Id) from tmpNews) as 'TongSoBanGhi' from tmpNews
WHERE
ThuTuBanGhi BETWEEN (#StartRowIndex) AND (#StartRowIndex + #PageSize-1)
SET #EndTime = GETDATE()
PRINT 'StartTime = ' + CONVERT(VARCHAR(30),#StartTime,121)
PRINT ' EndTime = ' + CONVERT(VARCHAR(30),#EndTime,121)
PRINT ' Duration = ' + STR(DATEDIFF(MILLISECOND,#StartTime,#EndTime)) + ' millisecond'
select STR(DATEDIFF(MILLISECOND,#StartTime,#EndTime))
After this store excute
EXEC [dbo].[TNNews_User_SearchBasic]
#Title='',
#CategoryId = '',
#IsInterested = -1,
#IsHot = -1,
#IsTopCategory = -1,
#IsPublish = -1,
#PageSize = 20,
#PageIndex = 1,
#OrderBy = '',
#PortalId = 0,
#LanguageId = N'vi-VN'
go
The time excute about "200ms". And I create a new store "TNNews_User_SearchBasic1" with some change.
.....
--,ROW_NUMBER() OVER (ORDER BY (Publisheddate) desc) as ThuTuBanGhi
,ROW_NUMBER() OVER (ORDER BY (case when #OrderBy='VIEW_COUNT' then ViewCount else PublishedDate end) desc) as ThuTuBanGhi
.....
and now the time excute this store
EXEC [dbo].[TNNews_User_SearchBasic1]
#Title='',
#CategoryId = '',
#IsInterested = -1,
#IsHot = -1,
#IsTopCategory = -1,
#IsPublish = -1,
#PageSize = 20,
#PageIndex = 1,
#OrderBy = '',
#PortalId = 0,
#LanguageId = N'vi-VN'
GO
about 900ms.
I don't understand why there is a change. Please help me improve these stores.
PS: I put example db at: http://anhquan22.tk/Portals/0/Videos/web.rar
Finished analysis the structure of your database. The part of the problem is hiding in the table structure.
I have prepared a backup for you. In it, I slightly modified scheme to improve performance and some normalize the table. You can download it from this link.
...to your question, I would do like this -
DECLARE #SQL NVARCHAR(1000)
SELECT #SQL = N'
;WITH tmpCategory (Id, Name, ParentId, [Level]) AS
(
SELECT
e.Id
, e.Name
, e.ParentId
, 1
FROM dbo.TNCategory e
WHERE Id = #CategoryId OR (#CategoryId = '''' AND ParentId <= 0)
UNION ALL
SELECT
e.Id
, e.Name
, e.ParentId
, [Level] + 1
FROM dbo.TNCategory e
JOIN tmpCategory d ON e.ParentId = d.Id
)
SELECT
a.Id
, ROW_NUMBER() OVER (ORDER BY ' +
CASE WHEN #OrderBy = 'VIEW_COUNT'
THEN 'ViewCount'
ELSE 'PublishedDate'
END +' DESC) AS ThuTuBanGhi
FROM dbo.TNNewsMain a
where PortalId = #PortalId
AND LanguageId = #LanguageId'
+ CASE WHEN #IsInterested != -1 THEN ' AND IsInterested = #IsInterested' ELSE '' END
+ CASE WHEN #IsHot != -1 THEN ' AND IsHot = #IsHot' ELSE '' END
+ CASE WHEN #IsTopCategory != -1 THEN ' AND IsTopCategory = #IsTopCategory' ELSE '' END
+ CASE WHEN #IsPublish != -1 THEN ' AND IsPublish = #IsPublish' ELSE '' END
+ CASE WHEN #CategoryId != -1 THEN '' ELSE ' AND EXISTS(SELECT 1 FROM tmpCategory b WHERE b.Id = a.CategoryId)' END
INSERT INTO #temp (Id, ThuTuBanGhi)
EXECUTE sp_executesql
#SQL
, N'#PortalId INT
, #LanguageId VARCHAR(6)
, #CategoryId INT
, #IsInterested INT
, #IsHot INT
, #IsTopCategory INT
, #IsPublish INT'
, #PortalId = #PortalId
, #LanguageId = #LanguageId
, #CategoryId = #CategoryId
, #IsInterested = #IsInterested
, #IsHot = #IsHot
, #IsTopCategory = #IsTopCategory
, #IsPublish = #IsPublish;
SELECT
d.Id
, tm.Title
, tm.[Subject]
, d.ThuTuBanGhi
, c.TongSoBanGhi
FROM (
SELECT t.Id
, t.ThuTuBanGhi
FROM #temp t
WHERE t.ThuTuBanGhi BETWEEN #StartRowIndex AND #StartRowIndex + #PageSize - 1
) d
JOIN TNNewsMain tm ON d.Id = tm.Id
CROSS JOIN (
SELECT TongSoBanGhi = (SELECT COUNT(1) FROM #temp)
) c

Error converting data type varchar to numeric in SQL

I have spent the last 3 hours trying to figure this out but I have had not luck. When executing this SP I get the below error:
Msg 8114, Level 16, State 5, Procedure sp_SPLIT_CARTON, Line 28
Error converting data type varchar to numeric.
Here is the SP and help is really appreciated
USE [1_WMS]
GO
ALTER PROCEDURE [dbo].sp_SPLIT_CARTON
#FROM_CARTON VARCHAR(20)
, #TO_CARTON VARCHAR(20)
, #SKU VARCHAR(20)
, #QTY DECIMAL
, #USER VARCHAR(20)
AS
DECLARE
#DATE VARCHAR(10)
, #TIME VARCHAR(8)
, #SYS_CONFIG_CODE VARCHAR(5)
, #SYS_CONFIG_VALUE INT
, #CN_STATUS INT
, #CN_STATUS_1 INT --USE FOR BETWEEN STATEMENT
, #CN_STATUS_2 INT --USE FOR BETWEEN STATEMENT
, #CN_STORE VARCHAR(10)
SET #DATE = CONVERT(VARCHAR(10), GETDATE(),101);
SET #TIME = CONVERT(VARCHAR(8), GETDATE(),114);
SET #SYS_CONFIG_CODE = 'SPLCN';
SET #CN_STATUS_1 = '10';
--SET #CN_STATUS_2 = 20;
--THIS IS LINE 28
/*CHECK FOR VALID CARTON STATUS BEFORE SPLITTING*/
SELECT #CN_STATUS = cn_status
, #CN_STORE = cn_store
FROM CARTON
WHERE cn_number = #FROM_CARTON --I BELIEVE THIS IS THE PIECE OF CODE CAUSING THE ISSUE
IF #CN_STATUS = #CN_STATUS_1
BEGIN
/*CHECK FOR SYSTEM CONFIGURATION*/
SELECT #SYS_CONFIG_VALUE = sys_value FROM SYS_CONFIG
WHERE sys_code = #SYS_CONFIG_CODE
IF #SYS_CONFIG_VALUE = 1
BEGIN
/*REMOVE SKU FROM CURRENT CARTON*/
DELETE FROM CARTON_DETAIL
WHERE cd_carton_number = #FROM_CARTON
AND cd_barcode = #SKU
/*UPDATE THE CARTON HEADER*/
UPDATE CARTON
SET cn_packed_qty = cn_packed_qty - #QTY
, cn_modify_date = #DATE
, cn_modify_time = #TIME
, cn_modify_by = #USER
WHERE cn_number = #FROM_CARTON
AND cn_status BETWEEN #CN_STATUS_1 AND #CN_STATUS_2
/*CREATE NEW CARTON HEADER*/
INSERT INTO CARTON
(
cn_number
)
VALUES
(
#FROM_CARTON
)
/*CREATE CARTON DETAIL*/
INSERT INTO CARTON_DETAIL
(
cd_carton_number
)
VALUES
(
#TO_CARTON
)
END
ELSE IF #SYS_CONFIG_VALUE = 0
BEGIN
/*REMOVE SKU FROM CURRENT CARTON*/
DELETE FROM CARTON_DETAIL
WHERE cd_carton_number = #FROM_CARTON
AND cd_barcode = #SKU
/*UPDATE THE CARTON HEADER*/
UPDATE CARTON
SET cn_packed_qty = cn_packed_qty - #QTY
, cn_modify_date = #DATE
, cn_modify_time = #TIME
, cn_modify_by = #USER
WHERE cn_number = #FROM_CARTON
AND cn_status BETWEEN #CN_STATUS_1 AND #CN_STATUS_2
/*GET THE NEXT CARTON FROM COUNTERS*/
SELECT #TO_CARTON = counter_current FROM COUNTERS WHERE counter_name = (
SELECT DISTINCT so_counter_name FROM STORES WHERE SO_NUMBER = (
SELECT DISTINCT cn_store FROM CARTON WHERE cn_number = #FROM_CARTON))
/*UPDATE THE COUNTER AFTER GETTING THE NEXT CARTON NUMBER*/
UPDATE COUNTERS SET counter_current = counter_current + 1
, counter_next = counter_next + 1
WHERE counter_name = (SELECT DISTINCT so_counter_name FROM STORES WHERE SO_NUMBER = (
SELECT DISTINCT cn_store FROM CARTON WHERE cn_number = #FROM_CARTON))
/*CREATE NEW CARTON HEADER*/
DECLARE
#CN_NUMBER VARCHAR(20) , #CN_PICKTICKET VARCHAR(20) , #2ndCN_STORE VARCHAR(10) , #CN_LOAD_NUMBER VARCHAR(20)
, #CN_SHIPMENT_NUMBER VARCHAR(20) , #CN_MANIFEST_NUMBER VARCHAR(20) , #CN_PACKED_QTY DECIMAL , #CN_TRACKING_NUMBER VARCHAR(20)
, #CN_TYPE VARCHAR(5) , #CN_PACK_TYPE VARCHAR(5) , #CN_ROUTE VARCHAR(5) , #CN_SHIP_VIA VARCHAR(5)
, #CN_BOL VARCHAR(20) , #CN_MBOL VARCHAR(20) , #CN_PARCEL_NUMBER VARCHAR(10) , #CN_TRAILER_NUMBER VARCHAR(10)
, #CN_AREA VARCHAR(10) , #CN_ZONE VARCHAR(10) , #CN_AISLE VARCHAR(10) , #CN_LEVEL VARCHAR(10)
, #CN_POSITION VARCHAR(10) , #CN_HEIGHT DECIMAL , #CN_WIDTH DECIMAL , #CN_DIMENSION DECIMAL
, #CN_WEIGHT DECIMAL , #CN_VOLUME DECIMAL , #2ndCN_STATUS INT , #CN_ADDRESS VARCHAR(150)
, #CN_ADDRESS_1 VARCHAR(150) , #CN_CITY VARCHAR(50) , #CN_STATE VARCHAR(50) , #CN_ZIP_CODE VARCHAR(20)
, #CN_COUNTRY VARCHAR(50) , #CN_MISC7 VARCHAR(50) , #CN_MISC8 VARCHAR(50) , #CN_MISC9 VARCHAR(50)
, #CN_MISC10 VARCHAR(50)
SET #CN_NUMBER = #TO_CARTON SET #2ndCN_STORE = #CN_STORE SET #CN_LOAD_NUMBER = ''
SET #CN_SHIPMENT_NUMBER = '' SET #CN_MANIFEST_NUMBER = '' SET #CN_PACKED_QTY = ''
SET #CN_TRACKING_NUMBER = '' SET #CN_TYPE = 'SPLIT' SET #CN_PACK_TYPE = 'SPLITTED'
SET #CN_ROUTE = '' SET #CN_SHIP_VIA = '' SET #CN_BOL = ''
SET #CN_MBOL = '' SET #CN_PARCEL_NUMBER = '' SET #CN_TRAILER_NUMBER = ''
SET #CN_AREA = '' SET #CN_ZONE = '' SET #CN_AISLE = ''
SET #CN_LEVEL = '' SET #CN_POSITION = '' SET #CN_HEIGHT = ''
SET #CN_WIDTH = '' SET #CN_DIMENSION = '' SET #CN_WEIGHT = ''
SET #CN_VOLUME = '' SET #2ndCN_STATUS = '10' SET #CN_MISC7 = ''
SET #CN_MISC8 = '' SET #CN_MISC9 = '' SET #CN_MISC10 = ''
/*GET STORE INFORMATION*/
SELECT #CN_ADDRESS = so_address
, #CN_ADDRESS_1 = so_address_1
, #CN_CITY = so_city
, #CN_STATE = so_state
, #CN_ZIP_CODE = so_zip_code
, #CN_COUNTRY = so_country
FROM STORES
WHERE so_number = #CN_STORE
EXECUTE sp_CREATE_CARTON
#CN_NUMBER , #CN_PICKTICKET , #CN_STORE , #CN_LOAD_NUMBER , #CN_SHIPMENT_NUMBER
, #CN_MANIFEST_NUMBER , #CN_PACKED_QTY , #CN_TRACKING_NUMBER , #CN_TYPE , #CN_PACK_TYPE
, #CN_ROUTE , #CN_SHIP_VIA , #CN_BOL , #CN_MBOL , #CN_PARCEL_NUMBER
, #CN_TRAILER_NUMBER , #CN_AREA , #CN_ZONE , #CN_AISLE , #CN_LEVEL
, #CN_POSITION , #CN_HEIGHT , #CN_WIDTH , #CN_DIMENSION , #CN_WEIGHT
, #CN_VOLUME , #CN_STATUS , #CN_ADDRESS , #CN_ADDRESS_1 , #CN_CITY
, #CN_STATE , #CN_ZIP_CODE , #CN_COUNTRY , #CN_MISC7 , #CN_MISC8
, #CN_MISC9 , #CN_MISC10 , #USER
INSERT INTO CARTON
(
cn_number
)
VALUES
(
#TO_CARTON
)
/*CREATE CARTON DETAIL*/
INSERT INTO CARTON_DETAIL
(
cd_carton_number
)
VALUES
(
#TO_CARTON
)
END
END
--ELSE
-- BEGIN
-- EXECUTE sp_CREATE_ERROR_MESSAGE
-- #ER_TYPE
-- END
GO
--Find the row that is not numeric and fix data
SELECT *
FROM CARTON
WHERE ISNUMERIC(cn_number) != 1 OR
ISNUMERIC(cn_status) != 1
--If you can't fix the data you will need to cast as varchar and compare