The following stored procedure works fine and returns data. However I wanted to also insert the data into a table for debugging before the final select. The code for the insert is commented out just before the final select. The insert uses the exact same select, without the order by, as the data source. However when I run the procedure with the insert uncommented I get an error:
Invalid Object Name BudgetSummaryDetail
I don't why using the object name is fine in the final select but if I try to use it for the insert I get an error. I'm sure there is a reason but I've tried it a bunch of different ways and I can't seem to figure it out. Any help or insight would be most appreciated.
ALTER PROCEDURE [dbo].[rptBudgetSummaryTest]
#Fy AS CHAR(4),
#Index_No AS VARCHAR(MAX) = NULL, -- "IN" - NULL for all; otherwise, comma seperated list of values
#PCA AS VARCHAR(MAX) = NULL, -- "IN" - NULL for all; otherwise, comma seperated list of values
#Appro_Sym AS VARCHAR(MAX) = NULL, -- "IN" - NULL for all; otherwise, comma seperated list of values
#IncludeNonFundedPositions AS BIT = 1,
#OnlyNonZeroPYs AS BIT = 0,
#OnlyNonZeroAllotment AS BIT = 0,
#mrgpcain as dbo.mrgpcain READONLY
AS
IF 1=0 BEGIN
SET FMTONLY OFF
END
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON
-- SET XACT_ABORT ON causes the entire transaction to be
-- rolled back on a run-time error instead of just the sql
-- statement that caused the error.
SET XACT_ABORT ON
BEGIN
-- Tally tables for optional multi-value parameters
SELECT Item
INTO #Index_No_ParamValues
FROM [Common].dbo.Split(#Index_No, ',')
IF (SELECT COUNT(*) FROM #Index_No_ParamValues WHERE Item IS NOT NULL) < 1
BEGIN
TRUNCATE TABLE #Index_No_ParamValues
END
SELECT Item
INTO #PCA_ParamValues
FROM [Common].dbo.Split(#PCA, ',')
IF (SELECT COUNT(*) FROM #PCA_ParamValues WHERE Item IS NOT NULL) < 1
BEGIN
TRUNCATE TABLE #PCA_ParamValues
END
SELECT Item
INTO #Appro_Sym_ParamValues
FROM [Common].dbo.Split(#Appro_Sym, ',')
IF (SELECT COUNT(*) FROM #Appro_Sym_ParamValues WHERE Item IS NOT NULL) < 1
BEGIN
TRUNCATE TABLE #Appro_Sym_ParamValues
END
;WITH
BudgetSummaryDetail
AS (
SELECT
tblPCAIn.FY,
tblPCAIn.Index_No,
tblPCAIn.PCA,
tblPCAIn.Obj_Det,
tblPCAIn.Agy_Obj,
tblPCAIn.PYs,
Calc_PYs = IIF(((tblPCAIn.Obj_Det='427' AND tblPCAIn.Agy_Obj='04') OR tblPCAIn.Obj_Det='439') AND (CAST(tblPCAIn.PCA AS INT) BETWEEN 5000 AND 5999),
IIF(tblPCAFl.Fund_Src = 'F', (tblPCAIn.PYs * tblPCAFl.W_Pnct), 0),
(tblPCAIn.PYs * tblPCAFl.Pnct)),
Calc_Allot = IIF(((tblPCAIn.Obj_Det='427' AND tblPCAIn.Agy_Obj='04') OR tblPCAIn.Obj_Det='439') AND (CAST(tblPCAIn.PCA AS INT) BETWEEN 5000 AND 5999),
IIF(tblPCAFl.Fund_Src = 'F', (tblPCAIn.Allotment * tblPCAFl.W_Pnct), 0),
(tblPCAIn.Allotment * tblPCAFl.Pnct)),
tblPCAFl.Appro_Sym,
tblPCAFl.Fund_Src,
tblPCAFl.Fund_No,
tblPCAFl.Method,
tblPCAFl.Project,
PCT = ROUND(tblPCAFl.Pnct * 100, 0)
FROM
dbo.tblIndex AS tblIndex
INNER JOIN #mrgpcain AS tblPCAIn ON
tblPCAIn.FY = tblIndex.FY AND
tblPCAIn.Index_No = tblIndex.Index_No
INNER JOIN dbo.tblPCA AS tblPCA ON
tblPCA.FY = tblPCAIn.FY AND
tblPCA.PCA = tblPCAIn.PCA
INNER JOIN dbo.tblPCAFl AS tblPCAFl ON
tblPCAFl.FY = tblPCA.FY AND
tblPCAFl.PCA = tblPCA.PCA
INNER JOIN dbo.tblAppro AS tblAppro ON
tblAppro.FY = tblPCAFl.FY AND
tblAppro.Appro_Sym = tblPCAFl.Appro_Sym
LEFT JOIN #Index_No_ParamValues ON
tblIndex.Index_No = #Index_No_ParamValues.Item
LEFT JOIN #PCA_ParamValues ON
tblPCAIn.PCA = #PCA_ParamValues.Item
LEFT JOIN #Appro_Sym_ParamValues ON
tblAppro.Appro_Sym = #Appro_Sym_ParamValues.Item
WHERE
(#Index_No_ParamValues.Item IS NOT NULL OR NOT EXISTS (SELECT TOP 1 Item FROM #Index_No_ParamValues)) AND
(#PCA_ParamValues.Item IS NOT NULL OR NOT EXISTS (SELECT TOP 1 Item FROM #PCA_ParamValues)) AND
(#Appro_Sym_ParamValues.Item IS NOT NULL OR NOT EXISTS (SELECT TOP 1 Item FROM #Appro_Sym_ParamValues)) AND
(((#IncludeNonFundedPositions = 0) AND
(tblPCA.PCA <> '02727')
) OR (#IncludeNonFundedPositions = 1)) AND
(((#OnlyNonZeroPYs = 1) AND
(tblPCAIn.PYs <> 0.0)
) OR (#OnlyNonZeroPYs = 0)) AND
(((#OnlyNonZeroAllotment = 1) AND
(tblPCAIn.Allotment <> 0)
) OR (#OnlyNonZeroAllotment = 0))
)
--DELETE FROM tblBS_Test
--INSERT INTO tblBS_Test
--SELECT * FROM (
--SELECT
-- tblIndex.Dept_Id,
-- tblIndex.Dpty_Id,
-- tblIndex.Brch_Id,
-- tblIndex.Div_Id,
-- detail.Index_No,
-- tblIndex.Index_Title,
-- detail.PCA,
-- tblPCA.PCA_Title,
-- PROGLINK = REPLACE(tblPCA.Program+tblPCA.Element+tblPCA.Component+tblPCA.Task, '', '0'),
-- FUNDLINK = tblPCAFl.Appro_Sym+tblPCAFl.Fund_Src+tblPCAFl.Fund_No+tblPCAFl.Method+ IIF(tblPCAFl.Project = SPACE(6), SPACE(8), tblPCAFl.Project+'00'),
-- tblAppro.Ref,
-- detail.Obj_Det,
-- detail.Agy_Obj,
-- PYs,
-- POS = IIF(((detail.Obj_Det = '003') AND (RTRIM(detail.Agy_Obj) = '')), detail.Calc_PYs, 0.0),
-- Calc_PYs = detail.Calc_PYs,
-- detail.Calc_Allot,
-- PCT
--FROM
-- BudgetSummaryDetail AS detail
-- INNER JOIN dbo.tblIndex AS tblIndex ON
-- tblIndex.FY = detail.FY AND
-- tblIndex.Index_No = detail.Index_No
-- INNER JOIN dbo.tblPCA AS tblPCA ON
-- tblPCA.FY = detail.FY AND
-- tblPCA.PCA = detail.PCA
-- INNER JOIN dbo.tblPCAFl AS tblPCAFl ON
-- tblPCAFl.FY = tblPCA.FY AND
-- tblPCAFl.PCA = tblPCA.PCA AND
-- tblPCAFl.Appro_Sym = detail.Appro_Sym AND
-- tblPCAFl.Fund_Src = detail.Fund_Src AND
-- tblPCAFl.Fund_No = detail.Fund_No AND
-- tblPCAFl.Method = detail.Method AND
-- tblPCAFl.Project = detail.Project
-- INNER JOIN dbo.tblAppro AS tblAppro ON
-- tblAppro.FY = tblPCAFl.FY AND
-- tblAppro.Appro_Sym = tblPCAFl.Appro_Sym
-- INNER JOIN dbo.tblAgyDE AS tblAgyDE ON
-- tblAgyDE.Obj_Det = detail.Obj_Det AND
-- tblAgyDE.Agy_Obj = detail.Agy_Obj
-- INNER JOIN dbo.tblObjDe AS tblObjDe ON
-- tblObjDe.Obj_Det = tblAgyDE.Obj_Det
-- INNER JOIN dbo.tblCat AS tblCat ON
-- tblCat.Category = tblObjDe.Category) as myda
SELECT
tblIndex.Dept_Id,
tblIndex.Dpty_Id,
tblIndex.Brch_Id,
tblIndex.Div_Id,
detail.Index_No,
tblIndex.Index_Title,
detail.PCA,
tblPCA.PCA_Title,
PROGLINK = REPLACE(tblPCA.Program+tblPCA.Element+tblPCA.Component+tblPCA.Task, '', '0'),
FUNDLINK = tblPCAFl.Appro_Sym+tblPCAFl.Fund_Src+tblPCAFl.Fund_No+tblPCAFl.Method+ IIF(tblPCAFl.Project = SPACE(6), SPACE(8), tblPCAFl.Project+'00'),
tblAppro.Ref,
detail.Obj_Det,
detail.Agy_Obj,
PYs,
POS = IIF(((detail.Obj_Det = '003') AND (RTRIM(detail.Agy_Obj) = '')), detail.Calc_PYs, 0.0),
Calc_PYs = detail.Calc_PYs,
detail.Calc_Allot,
PCT
FROM
BudgetSummaryDetail AS detail
INNER JOIN dbo.tblIndex AS tblIndex ON
tblIndex.FY = detail.FY AND
tblIndex.Index_No = detail.Index_No
INNER JOIN dbo.tblPCA AS tblPCA ON
tblPCA.FY = detail.FY AND
tblPCA.PCA = detail.PCA
INNER JOIN dbo.tblPCAFl AS tblPCAFl ON
tblPCAFl.FY = tblPCA.FY AND
tblPCAFl.PCA = tblPCA.PCA AND
tblPCAFl.Appro_Sym = detail.Appro_Sym AND
tblPCAFl.Fund_Src = detail.Fund_Src AND
tblPCAFl.Fund_No = detail.Fund_No AND
tblPCAFl.Method = detail.Method AND
tblPCAFl.Project = detail.Project
INNER JOIN dbo.tblAppro AS tblAppro ON
tblAppro.FY = tblPCAFl.FY AND
tblAppro.Appro_Sym = tblPCAFl.Appro_Sym
INNER JOIN dbo.tblAgyDE AS tblAgyDE ON
tblAgyDE.Obj_Det = detail.Obj_Det AND
tblAgyDE.Agy_Obj = detail.Agy_Obj
INNER JOIN dbo.tblObjDe AS tblObjDe ON
tblObjDe.Obj_Det = tblAgyDE.Obj_Det
INNER JOIN dbo.tblCat AS tblCat ON
tblCat.Category = tblObjDe.Category
ORDER BY
tblIndex.Dept_Id,
tblIndex.Dpty_Id,
tblIndex.Brch_Id,
tblIndex.Div_Id,
detail.Index_No,
detail.PCA,
tblPCAFl.Appro_Sym+tblPCAFl.Fund_Src+tblPCAFl.Fund_No+tblPCAFl.Method+ IIF(tblPCAFl.Project = SPACE(6), SPACE(8), tblPCAFl.Project+'00'),
detail.Obj_Det,
detail.Agy_Obj
IF Object_id('tempdb..#Index_No_ParamValues') IS NOT NULL
BEGIN
DROP TABLE #Index_No_ParamValues;
END
IF Object_id('tempdb..#PCA_ParamValues') IS NOT NULL
BEGIN
DROP TABLE #PCA_ParamValues;
END
IF Object_id('tempdb..#Appro_Sym_ParamValues') IS NOT NULL
BEGIN
DROP TABLE #Appro_Sym_ParamValues;
END
RETURN 0
END
GO
Related
New to SQL Server so I am sorry if this is not correctly. We have a number of stored procedures. The one shown below is a good example.
The issue with the query is it works fine until there are thousands of records and it sometimes never returns. I am told this could be performance related and that queries like this could be improved by using local variables. Any insight would be appreciated...thanks
CREATE PROCEDURE [dbo].[Status_GetObjectConfigurationsPr]
#SiteID int,
#AnalogBinary bit,
#UserID int,
#ActionNumber int
AS
DECLARE #ProcName varchar(128),
#ErrorText varchar(200),
#ErrorID int,
#RoleID int
SELECT #RoleID = RoleID
FROM TESUserRole
WHERE UserID = #UserID
SELECT #ProcName = OBJECT_NAME(##PROCID)
SELECT
o.ObjectID,
o.ObjectName,
o.ObjectType,
o.ObjectURI,
o.KeyName,
c.UserDefinedUnits,
o.SiteID,
ts.SiteName,
p.Device_ID,
c.Dimension,
CASE
(SELECT COUNT(ParentObjectID) FROM TESObjectParent
WHERE ChildObjectID IN (o.ObjectID))
WHEN 2
THEN (SELECT TOP 1 b.ParentObjectID
FROM TESObject a
INNER JOIN TESObjectParent b ON a.ObjectID = b.ParentObjectID
WHERE a.ObjectID IN (SELECT ParentObjectID
FROM TESObjectParent
WHERE ChildObjectID IN (o.ObjectID))
AND ObjectType != 8
AND RelationshipType = 7)
WHEN 1
THEN (SELECT TOP 1 ParentObjectID
FROM TESObjectParent
WHERE ChildObjectID = o.ObjectID AND RelationshipType = 7)
END AS ParentObjectId,
CASE
(Select count(ParentObjectID) from TESObjectParent where ChildObjectID in (o.ObjectID) )
When 2 Then ((select top 1 ObjectName from TESObject a inner join TESObjectParent b
on a.ObjectID = b.ParentObjectID where a.ObjectID in
(Select ParentObjectID from TESObjectParent where ChildObjectID in (o.ObjectID))
and ObjectType != 8 and RelationshipType = 7))
When 1 Then PanelName
End
as PanelName
FROM
TESObject o
LEFT OUTER JOIN
TESObjectConfiguration c
ON
o.ObjectID = c.ObjectID
INNER JOIN
TESSite ts
ON
o.SiteID =ts.SiteID
INNER JOIN
TESPanel p
ON
o.Device_ID = p.Device_ID and o.SiteID = p.SiteID
INNER JOIN
TESObjectFamily f
ON
o.CustomFamilyNumber = f.FamilyNumber
INNER JOIN
TESEquipmentRole er
ON
er.FamilyID = f.FamilyID AND er.ObjectType = o.ObjectType
INNER JOIN
TESAction a
ON
er.ActionID = a.ActionID
WHERE
p.IsAppliedToLicense = 1 AND p.IsPanelEnabled = 1
AND
o.SiteID = #SiteID
AND
(c.Property_ID = 85 OR c.Property_ID is NULL)
AND(
(#AnalogBinary = 0 AND o.ObjectType IN (4,5))
OR
(#AnalogBinary = 1 AND o.ObjectType IN (1,2))
)
AND
er.RoleID = #RoleID
AND
a.ActionNumber = #ActionNumber
SET #ErrorID = ##ERROR
IF #ErrorID <> 0
BEGIN
SET #ErrorText = 'Unable to retrieve Object Configuration Information.'
GOTO ErrorHandler
END
---- Error Handling
RETURN 0
ErrorHandler:
BEGIN
RAISERROR ('PROC: %s - %s , Error: %d.', 16, 1, #ProcName, #ErrorText, #ErrorID)
END
RETURN 1
I have a rather long Sql query that needs different where clauses depending on user choices.
I have done some searching, and this seems to be the most comprehensive article on the matter.
However, it doesn't mention the option of using the table valued function to achieve the same effect, and to me, this seems to be the most optimum answer.
Am I missing something?
Here is my catch all query written with the TVF:
--These paramenters will always be passed
declare #tenantId int = 7;
declare #yesterday DateTime = dateadd(day,datediff(day,1,GETUTCDATE()),0);
declare #tomorrow DateTime = dateadd(day,datediff(day,-1,GETUTCDATE()),0);
--These are optional:
declare #parentId int = 230; --In this example, #parentId is populated.
declare #ownedById int = null; --In this example, #ownedBy is not populated.
--Simple if statement:
if #parentId is not null
BEGIN
if #ownedById is not null
BEGIN
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where ParentId = #parentId and OwnedById = #ownedById;
END
ELSE
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where ParentId = #parentId;
END
ELSE IF #ownedById is not null
BEGIN
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where OwnedById = #ownedById;
END
ELSE
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow);
And here is the TVF:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION GetItemInfos
(
#tenantId int,
#yesterday DateTime,
#tomorrow DateTime
)
RETURNS TABLE
AS
RETURN
(
Select i.Id,
i.AssignedToId,
i.ParentId,
i.OwnedById,
i.Budget,
i.CloseDate,
i.CloseStatusId,
AssignedToName = Concat(anu.FirstName, ' ', anu.LastName),
OwnedByName = Concat(anu2.FirstName, ' ', anu2.LastName),
CloseStatusName = cs.Name,
i.ItemTypeId,
ItemTypeIcon = it.Icon,
i.ImportanceTypeId,
ImportanceTypeDescription = ImportanceTypes.Description,
i.EntityStatusId,
i.DueDate,
IsOverdue =
case when i.CloseStatusId = 1 and i.DueDate <= #yesterday then Cast(1 as bit)
else Cast(0 as bit)
end,
IsDue =
case when i.CloseStatusId = 1 and i.DueDate >= #yesterday and i.DueDate < #tomorrow then cast(1 as bit)
else Cast(0 as bit)
end,
IsClosed = case when (i.CloseStatusId != 1) then cast(1 as bit) else cast(0 as bit) end,
i.Cost,
ItemTypeShowProperties = it.ShowProperties,
ItemTypeSortOrder = it.SortOrder,
PriorityTypeDescription = PriorityTypes.Description,
PriorityTypeSortOrder = PriorityTypes.SortOrder,
i.Name,
i.PriorityTypeId,
Progress = Convert(nvarchar, i.Progress) + '%',
i.SortOrder,
i.StartDate,
StatusTypeName = StatusTypes.Name,
i.TimeEstimate,
TimeScaleTypeName = TimeScaleTypes.Name
from Items i
left join AppUsers au
on i.AssignedToId = au.Id
left join AspNetUsers anu
on au.AspNetUserId = anu.id
left join AppUsers au2
on i.OwnedById = au2.Id
left join AspNetUsers anu2
on au2.AspNetUserId = anu2.id
left join CloseStatuses cs
on i.CloseStatusId = cs.id
left join ItemTypes it
on i.ItemTypeId = it.Id
left join ImportanceTypes
on i.ImportanceTypeId = ImportanceTypes.Id
left join PriorityTypes
on i.PriorityTypeId = PriorityTypes.Id
left join StatusTypes
on i.StatusTypeId = StatusTypes.Id
left join TimeScaleTypes
on i.TimeScaleTypeId = TimeScaleTypes.Id
where i.TenantId = #tenantid
)
GO
EDIT
Based on the comments, this seems to be the best way to write this:
Select * from GetItemInfos(#tenantId, #yesterday, #tomorrow)
where (#parentId is null or ParentId = #parentId) and (#ownedById is null or OwnedById = #ownedById) OPTION(RECOMPILE)
I am trying to create this procedure:
CREATE OR REPLACE PROCEDURE USP_DAILY_REP_REG_REFRESH
IS
BEGIN
SAVEPOINT start_tran;
EXECUTE immediate 'truncate table rep_fir_acts';
-- Insert Query
INSERT
INTO rep_fir_acts
(
PS_CD,
LANG_CD,
FIR_REG_NUM,
FIR_DT,
ACT_CD,
PEND_INV_FIR_NUM,
FINAL_REP_SRNO,
CHARGESHEET_DT,
INVTG_STATUS_CD,
FR_TYPE_CD,
FINAL_REPORT_TYPE_CD,
PEND_TRIAL_FIR,
DISPOSAL_NATURE_CD,
ACTION_TAKEN_CD,
FIR_STATUS
)
SELECT DISTINCT F.PS_CD,
F.LANG_CD,
F.FIR_REG_NUM,
F.REG_DT FIR_DT,
C.ACT_CD ,
fnl.FIR_REG_NUM PEND_INV_FIR_NUM,
fnl.FINAL_REP_SRNO ,
fnl.CHARGESHEET_DT,
fnl.INVTG_STATUS_CD,
fnl.FR_TYPE_CD,
fnl.FINAL_REPORT_TYPE_CD ,
dis.FIR_REG_NUM PEND_TRIAL_FIR,
dis.DISPOSAL_NATURE_CD ,
f.ACTION_TAKEN_CD,
f.FIR_STATUS
FROM t_fir_registration f
INNER JOIN t_crime_act_section c
ON f.fir_reg_num = c.fir_reg_num
AND f.lang_cd = c.lang_cd
INNER JOIN t_crime_detail cd
ON c.fir_reg_num = cd.fir_reg_num
AND c.lang_cd = cd.lang_cd
AND c.CRM_DETAIL_SRNO = cd.CRM_DETAIL_SRNO
AND cd.RECORD_STATUS = 'C'
LEFT JOIN t_final_report fnl
ON f.fir_reg_num = fnl.fir_reg_num
AND f.lang_cd = fnl.lang_cd
AND IS_CHARGESHEET_ORIGINAL = 'Y'
AND fnl.final_rep_srno IN
(SELECT MAX(final_rep_srno)
FROM t_final_report fn
WHERE f.fir_reg_num = fn.fir_reg_num
AND f.lang_cd = fn.lang_cd
AND fn.IS_CHARGESHEET_ORIGINAL = 'Y'
)
LEFT JOIN t_court_disposal dis
ON f.fir_reg_num = dis.fir_reg_num
AND dis.DISPOSAL_SRNO IN
(SELECT MAX(DISPOSAL_SRNO)
FROM t_court_disposal cdis
WHERE dis.fir_reg_num = cdis.fir_reg_num
)
WHERE c.act_cd <> 0
AND f.fir_status NOT IN(2,20,104,103);
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO start_tran;
RAISE;
END;
When I try to run this I get:
PL/SQL: SQL Statement ignored
ORA-01799: a column may not be outer-joined to a subquery with insert
statement
How can I resolve this problem?
You need to convert what you're left joining into subqueries, rather than having the subquery in the join conditions. E.g., something like:
SELECT DISTINCT f.ps_cd,
f.lang_cd,
f.fir_reg_num,
f.reg_dt fir_dt,
c.act_cd,
fnl.fir_reg_num pend_inv_fir_num,
fnl.final_rep_srno,
fnl.chargesheet_dt,
fnl.invtg_status_cd,
fnl.fr_type_cd,
fnl.final_report_type_cd,
dis.fir_reg_num pend_trial_fir,
dis.disposal_nature_cd,
f.action_taken_cd,
f.fir_status
FROM t_fir_registration f
INNER JOIN t_crime_act_section c
ON f.fir_reg_num = c.fir_reg_num
AND f.lang_cd = c.lang_cd
INNER JOIN t_crime_detail cd
ON c.fir_reg_num = cd.fir_reg_num
AND c.lang_cd = cd.lang_cd
AND c.crm_detail_srno = cd.crm_detail_srno
AND cd.record_status = 'C'
LEFT JOIN (SELECT fir_reg_num,
lang_cd,
final_rep_srno,
chargesheet_dt,
invtg_status_cd,
fr_type_cd,
final_report_type_cd
FROM (SELECT fnl1.*,
MAX(fnl1.final_rep_srno) OVER (PARTITION BY fnl1.fir_reg_num, fnl1.lang_cd) max_final_rep_srno
FROM t_final_report fnl1
WHERE fnl1.is_chargesheet_original = 'Y')
WHERE final_rep_srno = max_final_rep_srno) fnl
ON f.fir_reg_num = fnl.fir_reg_num
AND f.lang_cd = fnl.lang_cd
LEFT JOIN (SELECT fir_reg_num,
disposal_nature_cd
FROM (SELECT dis1.*,
MAX(disposal_srno) OVER (PARTITION BY dis1.fir_reg_num) max_disposal_srno
FROM t_court_disposal dis1)
WHERE disposal_srno = max_disposal_srno) dis
ON f.fir_reg_num = dis.fir_reg_num
WHERE c.act_cd <> 0
AND f.fir_status NOT IN (2, 20, 104, 103);
Here is the story: I have to implement filter. And in this filter there are certain categories I filter by.
One of the filters is "favourite" filter (#includeFavourites ).
I have this huge SQL with paging and sorting and everything.
Now, when "includeFavourites" option in filter is clicked, then I also have to select unique ID's from different table (this entries are stored in different datatable), where favourites are stored.
I have tried left outer join, but it returns "number of favourites" records for each record in primary table. Coalesce didn't help at all.
Here is my SQL:
--this is needed because stored procedure must know how many days are selected
DECLARE #daysCount int
SET #daysCount = 0
IF (#mon IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#tue IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#wed IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#thu IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#fri IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sat IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
IF (#sun IS NOT NULL)
BEGIN
SET #daysCount = #daysCount+1
END
-- Insert statements for procedure here
SELECT * FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy = 'NA' THEN title END,
CASE WHEN #OrderBy = '' THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS Row,
Articles.ArticleId, Articles.userId, Articles.timestamp as datePosted, users.screenName,
defaultSmallImagePath, authorRating, ArticleCosts, title,
FROM Articles
LEFT OUTER JOIN
Users on Articles.userId = Users.userId
LEFT OUTER JOIN
ArticleAdditionalInformation ON ArticleAdditionalInformation.ArticleId = Articles.ArticleId
--JOIN FOR CONTINENT
LEFT OUTER JOIN
Codings as Continent ON Continent.codingKeyId = ArticleAdditionalInformation.continentId AND Continent.languageId = #languageId
-- JOIN FOR COUNTRY
LEFT OUTER JOIN
CodingsAssociated as Country ON Country.codingKeyId = ArticleAdditionalInformation.countryId AND Country.languageId = #languageId
-- JOIN FOR Article TRANSLATION DATA
LEFT OUTER JOIN
ArticlesTranslations ON ArticlesTranslations.ArticleId = Articles.ArticleId AND ArticlesTranslations.languageId=#languageId
LEFT OUTER JOIN
ArticleCategories ON ArticleCategories.ArticleId = Articles.ArticleId
WHERE
(
ArticleCategories.categorieId =1 OR ArticleCategories.categorieId =2 OR
ArticleCategories.categorieId =3 OR ArticleCategories.categorieId =4 OR
ArticleCategories.categorieId = 5
) AND
(ArticlesTranslations.title LIKE '%' + #searchString + '%' OR #searchString IS NULL)
-- COST filter
AND
(ArticleCosts < #cost OR #cost = 0)
AND
(ArticleCosts > 0 OR #cost = 0)
--END cost filter
-- EXCLUDE already stored for selected days
AND Articles.ArticleId -- exclude these ArticleIds
NOT IN
(
SELECT DailyContent.ArticleId
FROM DailyContent
WHERE
sectionId=#sectionId AND
(
weekDayId=#mon OR
weekDayId=#tue OR
weekDayId=#wed OR
weekDayId=#thu OR
weekDayId=#fri OR
weekDayId=#sat OR
weekDayId=#sun
)
GROUP BY
DailyContent.ArticleId
HAVING
(COUNT(sectionId) = #daysCount)
)
-- END exclude
) p
WHERE (Row > #startRowIndex AND Row <=#startRowIndex + #pageSize)
ORDER BY Row
END
So, I would only like to include unique articleIds from favourite table, when #includeFavourites parameter is not null.
Any hint would be greatly appreciated ;)
I am using SQL server 2008.
Try this one -
DECLARE #daysCount INT
SELECT #daysCount =
ISNULL(#mon, 0) + -- if #mon = 1, #tue = 2, .... 1 + (2-1)=1 + (3-2)=1 + ...
ISNULL(#tue - 1, 0) +
ISNULL(#wed - 2, 0) +
ISNULL(#thu - 3, 0) +
ISNULL(#fri - 4, 0) +
ISNULL(#sat - 5, 0) +
ISNULL(#sun - 6, 0)
SELECT *
FROM (
SELECT ROW_NUMBER() OVER
(
ORDER BY
CASE WHEN #OrderBy = 'ND' THEN title END DESC,
CASE WHEN #OrderBy IN ('NA', '') THEN title END,
CASE WHEN #OrderBy = 'RD' THEN authorRating END DESC,
CASE WHEN #OrderBy = 'RA' THEN authorRating
) AS [Row]
, a.ArticleId
, a.userId
, a.[timestamp] as datePosted
, u.screenName
, defaultSmallImagePath
, authorRating
, ArticleCosts
, title
FROM dbo.Articles a -- always use schema and alias
LEFT JOIN dbo.Users u on a.userId = u.userId -- OUTER is unnecessary
LEFT JOIN dbo.ArticleAdditionalInformation aai ON aai.ArticleId = a.ArticleId
LEFT JOIN dbo.Codings cd ON cd.codingKeyId = aai.continentId AND cd.languageId = #languageId
LEFT JOIN dbo.CodingsAssociated c ON c.codingKeyId = aai.countryId AND c.languageId = #languageId
LEFT JOIN dbo.ArticlesTranslations at ON at.ArticleId = a.ArticleId AND at.languageId = #languageId
LEFT JOIN dbo.ArticleCategories ac ON ac.ArticleId = a.ArticleId
WHERE ac.categorieId IN (1, 2, 3, 4, 5)
AND (
at.title LIKE '%' + #searchString + '%'
OR
#searchString IS NULL
)
AND (ArticleCosts < #cost OR #cost = 0)
AND (ArticleCosts > 0 OR #cost = 0)
AND a.ArticleId NOT IN (
SELECT dc2.ArticleId
FROM dbo.DailyContent dc2
WHERE sectionId = #sectionId
AND (
weekDayId % #daysCount = 0 -- possible it's works
--weekDayId = #mon OR
--weekDayId = #tue OR
--weekDayId = #wed OR
--weekDayId = #thu OR
--weekDayId = #fri OR
--weekDayId = #sat OR
--weekDayId = #sun
)
GROUP BY dc2.ArticleId
HAVING COUNT(sectionId) = #daysCount
)
) p
WHERE [Row] BETWEEN #startRowIndex AND #startRowIndex + #pageSize
--ORDER BY [Row] -- ROW_COUNT already sorted your rows
Select #vCtlPeriod = period from ctl
IF #vCtlPeriod = #Period
Begin
SET #vHdr = 'StkHdr'
SET #vDtl = 'StkDtl'
End
ELSE
Begin
SET #vHdr = 'HStkHdr'
SET #vDtl = 'HStkDtl'
End
SELECT H.Loc, D.MatCod, D.MatQty, H.Slipno, H.SapWH,
P.InvPri, P.InvPri * D.MatQty as InvAmt, P.ProCat, P.MaiGrp, P.SubGrp1,P.SerCod ,
SUBSTRING(Z.LotNum,1,4) As ProdMth, F.UpdGSPI,
Class = Case WHen F.UpdGSPI = '9' Then 'D'
When Cast(SUBSTRING(Z.LotNum,1,2) AS INT) * 12 + Cast(SUBSTRING(Z.LotNum,3,2) AS INT)>= #vPerClsA Then 'A'
When Cast(SUBSTRING(Z.LotNum,1,2) AS INT) * 12 + Cast(SUBSTRING(Z.LotNum,3,2) AS INT)>= #vPerClsB Then 'B'
When Cast(SUBSTRING(Z.LotNum,1,2) AS INT) * 12 + Cast(SUBSTRING(Z.LotNum,3,2) AS INT)>= #vPerClsC1 Then 'C1'
When Cast(SUBSTRING(Z.LotNum,1,2) AS INT) * 12 + Cast(SUBSTRING(Z.LotNum,3,2) AS INT)>= #vPerClsC2 Then 'C2'
ELSE 'C3'
END,
FGType = Case F.UpdGSPI WHen '1' Then 'Production'
When '2' Then 'Trading'
When '3' Then 'Non GSPI'
When '9' Then 'DisContinue'
Else
'Not Maintain'
End,
FGSTATUS = Case When NOT ISNULL(Z.HolCod,'')='' or NOT ISNULL(Z.ResCod,'')='' Then 'Hold/Reserved'
When NOT ISNULL(Pd.Slipno,'')='' OR NOT ISNULL(Tg.Slipno,'')='' Then 'Pick'
ELSE ''
End,
Tg.SONum , Tg.Seq1, Tg.SptNum, Tg.Qty, Od.LPNum ,
Z.LotNum, Z.DocRefNo, IsNull(Z.HolCod,'') As HolCod, IsNull(Z.HolInf,'') As HolInf, IsNull(Z.ResCod,'') As ResCod, IsNull(Z.ResInf,'') As ResInf
FROM #vHdr H Join #vDtl D ON D.Slipno = H.Slipno And H.Period = #Period
Join Prd P ON D.MatCod = P.ProCod
Join LOCW L ON L.Loc = H.Loc AND L.Pickable <> 'Z' AND L.Putable <> 'Z' AND L.WhCod =H.SapWh
Join ZV00 Z ON Z.SlipNo = H.SlipNo
LEFT JOIN PrdFG F on F.Procod = D.MatCod
LEFT JOIN (SELECT Slipno, MatCod, Qty =Sum(QtyPck) from PickD group by Slipno, matcod) Pd on D.SlipNo = Pd.Slipno and D.MatCod = Pd.MatCod
LEFT JOIN TagLotQty Tg ON TG.SlipNo = D.SlipNo and Tg.procod = D.MatCod
LEFT JOIN OrdD Od ON Od.SONum = Tg.SONum and Od.Seq1 = Tg.Seq1
Above is some of my code in my stored procedure, I intend to check the current period from the ctl file, if the period is current period then I will get from current transaction table or else it will be retrieved from history transaction table.
But I failed at the last select statement. Can we predefined the table name in the variable?
No, we can't. You should use Dynamic SQL or move your SELECT into IF statement
Isn't it simpler to just:
Select #vCtlPeriod = period from ctl
IF #vCtlPeriod = #Period
Begin
SELECt A.*, B.* from StkHdr A Join StkDtl B ON A.Slipno = B.Slipno
End
ELSE
Begin
SELECt A.*, B.* from HStkHdr A Join HStkDtl B ON A.Slipno = B.Slipno
End
You have to use Dynamic SQL like this:
Select #vCtlPeriod = period from ctl
IF #vCtlPeriod = #Period
Begin
SET #vHdr = 'StkHdr'
SET #vDtl = 'StkDtl'
End
ELSE
Begin
SET #vHdr = 'HStkHdr'
SET #vDtl = 'HStkDtl'
End
declare #cmd varchar(500)
select #cmd = "SELECT A.*, B.* from " + #vHDr + " A Join " + #vHdtl + " B ON A.Slipno = B.Slipno "
exec (#cmd)