SQL Server - Variable assignment using UNION - sql

I'm trying to assign a variable value using UNION ALL but i receive an error:
Variable assignment is not allowed in a statement containing a top
level UNION, INTERSECT or EXCEPT operator.
How can I assign a value using UNION? Here is the sql that i'm trying to make:
SELECT #Totals = SUM(Quantity)
FROM ConsData A WITH(NOLOCK)
INNER JOIN #TmpData B ON B.DataId = A.DataId
INNER JOIN Data cp ON cp.DataId = A.DataId
WHERE A.Status = -1 AND cp.Date IS NOT NULL
UNION ALL
SELECT #Totals = cg.Total
FROM ConsDataGenerated cg
INNER JOIN #TmpData B ON B.DataId = cg.DataId
INNER JOIN Data cp ON cp.DataId = B.DataId
WHERE cp.Date IS NULL

Try something like this....
DECLARE #Totals1 INT, #Totals2 INT, #GrandTotal INT;
SELECT #Totals1 = SUM(Quantity)
FROM ConsData A WITH(NOLOCK)
INNER JOIN #TmpData B ON B.DataId = A.DataId
INNER JOIN Data cp ON cp.DataId = A.DataId
WHERE A.Status = -1 AND cp.Date IS NOT NULL
SELECT #Totals2 = cg.Total --<-- Assuming this returns a Scalar value
FROM ConsDataGenerated cg
INNER JOIN #TmpData B ON B.DataId = cg.DataId
INNER JOIN Data cp ON cp.DataId = B.DataId
WHERE cp.Date IS NULL
SELECT #GrandTotal = ISNULL(#Totals1, 0) + ISNULL(#Totals2, 0);

Related

How to pass multiple values in parameter

In this stored procedure, I need to pass multiple parameter values in #GDNNO. Right now I can pass only a single value.
Please help me.
ALTER PROCEDURE dbo.xspSHEGONPrintQuery4
#GDNNO varchar(4000) = ''
AS
BEGIN
SELECT
a.ID, a.[To], a.FlowCode, a.TranNum, a.Status,
ART.ARTICLECODE, StockGDNID, DetailID, SubDocCode, ArticleID,
ColorCode, ColorName, SizeCode, SizeName,
DispatchedUnits * (CASE WHEN u.value IS NULL THEN FreezeStoringUOM ELSE u.value END) AS DispatchedUnits
FROM
xtstockgdn a (nolock)
JOIN
xtstockgdndetail b (nolock) ON a.id = b.stockgdnid
JOIN
XTARTICLE ART (nolock) ON ART.ID = B.ARTICLEID
LEFT JOIN
xtUOMConversion u (nolock) ON u.FromUOM = art.StoringUOM
AND u.ToUOM = art.consuom
WHERE
a.ID IN (#GDNNO)
AND FlowCode = 'POO_RET[E-]'
END
Since your query is only Select it can be change to TVF(table-value function). Change your Procedure to TVF
CREATE FUNCTION dbo.xspSHEGONPrintQuery4(
#GDNNO varchar(4000) = ''
)
RETURNS TABLE
AS
RETURN
SELECT
a.ID, a.[To], a.FlowCode, a.TranNum, a.Status,
ART.ARTICLECODE, StockGDNID, DetailID, SubDocCode, ArticleID,
ColorCode, ColorName, SizeCode, SizeName,
DispatchedUnits * (CASE WHEN u.value IS NULL THEN FreezeStoringUOM ELSE u.value END) AS DispatchedUnits
FROM
xtstockgdn a (nolock)
JOIN
xtstockgdndetail b (nolock) ON a.id = b.stockgdnid
JOIN
XTARTICLE ART (nolock) ON ART.ID = B.ARTICLEID
LEFT JOIN
xtUOMConversion u (nolock) ON u.FromUOM = art.StoringUOM
AND u.ToUOM = art.consuom
WHERE
a.ID IN (#GDNNO)
AND FlowCode = 'POO_RET[E-]'
END
Then use Cross apply to your TVF
Select a.GDNNO,b.* from yourtable a /*list of GDNNO Values */
Cross Apply dbo.xspSHEGONPrintQuery4(a.GDNNO) b
you can use Dynamic query as well

Where Clause Using Conditional Statement

i have query below
SELECT #RoleUser = MR.Code FROM MasterRole MR INNER JOIN MasterUsersRole MUR ON MR.Id = MUR.RoleId
INNER JOIN MasterUsers MU ON Mu.UserCode = MUR.UserCode
WHERE MU.UserCode = #UserLoginID
select 1 Num
, MyHistory.ID
, MyHistory.RequestNumber
, MyHistory.FlowID
, MyHistory.FlowProcessStatusID
from
(
select *
from Requests R
inner join
(
--DECLARE #UserLoginID nvarchar(200) = 'dum.testing.3'
select distinct
RequestID
from dbo.RequestTrackingHistory RTH
where IIF(#UserLoginID = 'admin', #UserLoginID, RTH.CreatedBy) = #UserLoginID
OR ( CreatedBy IN
SELECT Mu.UserCode from MasterUsers MU
INNER JOIN MasterUsersRole MUR ON MU.UserCode = MUR.UserCode
INNER JOIN MasterRole MR ON MUR.RoleId = MR.Id
WHERE MR.Code = #RoleUser
)
)
) RT on R.ID = RT.RequestID
) as MyHistory
inner join MasterFlow F on MyHistory.FlowID = F.ID
inner join
(
select FP.ID
, FP.Name
, FP.AssignType
, FP.AssignTo
, FP.IsStart
, case FP.AssignType
when 'GROUP' then
G.Name
end as 'AssignToName'
from MasterFlowProcess FP
left join dbo.MasterRole G on FP.AssignTo = G.ID and FP.AssignType = 'GROUP'
) FP on MyHistory.FlowProcessID = FP.ID
inner join MasterFlowProcessStatus FPS on MyHistory.FlowProcessStatusID = FPS.ID
left join MasterFlowProcessStatusNext FPSN on FPS.ID = FPSN.ProcessStatusFlowID
left join MasterFlowProcess FPN on FPSN.NextProcessFlowID = FPN.ID
left JOIN MasterRole MR ON MR.Id = FPN.AssignTo
left join MasterUsersRole MUR on MR.Id = MUR.RoleId
left join MasterUsers MURO on MUR.UserCode = MURO.UserCode
inner join MasterUsers UC on MyHistory.CreatedBy = UC.UserCode
left join MasterUsers UU on MyHistory.UpdatedBy = UU.UserCode
LEFT JOIN RequestMT RMT ON MyHistory.ID = RMT.RequestID
LEFT JOIN RequestGT RGT ON MyHistory.ID = RGT.RequestID
left join (SELECT sum(QtyCU) countQty , RequestId from dbo.RequestGTDetail where IsActive = 1 group by RequestId) RGTD on RGTD.RequestId = RGT.RequestId
left join (SELECT sum(QtyPCS) countQty , RequestId from dbo.RequestMTDetail where IsActive = 1 group by RequestId) RMTD on RMTD.RequestId = RMT.RequestId
left join (SELECT COUNT(IIF(returnable = 0, returnable, null)) countReturnable , RequestId from dbo.RequestMTDetail group by RequestId) RMTR on RMTR.RequestId = RMT.RequestId
left JOIN dbo.MasterDistributor md ON md.Code = RGT.CustId or md.Code = RMT.CustId
left JOIN dbo.MasterUsersDistributor MUD ON MUD.UserCode = MURO.UserCode AND md.Code = MUD.DistributorCode
LEFT JOIN dbo.MasterReason MRMT ON RMT.ReasonId = MRMT.Id
LEFT JOIN dbo.MasterReason MRGT ON RGT.ReasonId = MRGT.Id
LEFT JOIN dbo.MasterDistributorGroup MDG ON MDG.Id = MD.GroupId
OUTER APPLY dbo.FnGetHistoryApproveDate(MyHistory.Id) AS x
where REPLACE(FPS.Name, '#Requestor', uc.Name) <> 'DRAFT'
AND MUD.DistributorCode IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = #UserLoginID)
i want to add some logic in where clause
this line
==> AND MUD.DistributorCode IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = #UserLoginID)
it depend on the #RoleUser variable, if #RoleUser IN ('A','B') then where clause above is executed, but if #RoleUser Not IN ('A','B') where clause not executed
i,m trying this where clause
AND IIF(#RoleUser IN ('A','B'), MUD.DistributorCode, #RoleUser) IN (SELECT DistributorCode FROM dbo.MasterUsersDistributor WHERE UserCode = IIF(#RoleUser IN ('A','B'), #UserLoginID, NULL))
it didn't work, only executed if #RoleUser IS ('A','B') other than that it return 0 record
any help or advice is really appreciated
thank you
The cleanest way I'm implemented these kind of crazy rules is a
holderTable
and a countVariable against the holder table.
I'll give a generic examples.
This is a "approach" and "philosophy", not a specific answer....with complex WHERE clauses.
DECLARE #customerCountryCount int
DECLARE #customerCountry TABLE ( CountryName varchar(15) )
if ( "the moon is blue on tuesday" ) /* << whatever rules you have */
BEGIN
INSERT INTO #customerCountry SELECT "Honduras" UNION ALL SELECT "Malaysia"
END
if ( "favorite color = green" ) /* << whatever rules you have */
BEGIN
INSERT INTO #customerCountry SELECT "Greenland" UNION ALL SELECT "Peru"
END
SELECT #customerCountryCount = COUNT(*) FROM #customerCountry
Select * from dbo.Customers c
WHERE
(#customerCountryCount = 0)
OR
( exists (select null from #customerCountry innerVariableTable where UPPER(innerVariableTable.CountryName) = UPPER(c.Country) ))
)
This way, instead of putting all the "twisted logic" in an overly complex WHERE statement..... you have "separation of concerns"...
Your inserts into #customerCountry are separated from your use of #customerCountry.
And you have the #customerCountryCount "trick" to distinguish when nothing was used.
You can add a #customerCountryNotExists table as well, and code it to where not exists.
As a side note, you may want to try using a #temp table (instead of a #variabletable (#customerCountry above)... and performance test these 2 options.
There is no "single answer". You have to "try it out".
And many many variables go into #temp table performance (from a sql-server SETUP, not "how you code a stored procedure". That is way outside the scope of this question.
Here is a SOF link to "safe" #temp table usage.
Temporary table in SQL server causing ' There is already an object named' error

scalar variable error after it has been declared

I'm running Microsoft SQL Server 17.7 and I keep getting an error message when trying to filter my data set by a date range with a where clause using a scalar variable. I declared both variables but I continue to get this error message "Must declare the scalar variable "#startDate". I'm guessing I'm not declaring the scalar variable correctly. Please assist.
DECLARE #MatterList NVARCHAR(100) = '(21940-00035)'
declare #startDate datetime = '1/1/2012'
declare #endDate datetime = '6/30/2015'
SELECT #MatterList = NULL
WHERE #MatterList = ''
DROP TABLE IF EXISTS #listMatter
DROP TABLE IF EXISTS #Matterlist
CREATE TABLE #MatterList (rowid int identity, MatterNumber nvarchar(20))
CREATE INDEX tMatterListIndex_MatterNumber on #MatterList (MatterNumber)
select value into #listMatter from
string_split(replace(replace(replace(#MatterList,'(',''),')',''), ' ' , ''), ',')
Insert into #MatterList (MatterNumber)
select m.Number as MatterNumber
from #listMatter lm
inner join Matter m with (nolock) on lm.value = m.Number
where m.Number not in (select matterNumber from #MatterList)
If OBJECT_ID('tempdb..#fees_detail') is not NULL drop table #fees_detail
GO
SELECT DISTINCT 'Fees' AS [type],
t.code AS tudef2,
tc.PostDate AS bfindt,
tc.IsActive AS isActive,
tc.IsNoCharge AS isNoCharge,
m.OpenDate AS mopendt,
m.CloseDate AS mclosedt,
m.ContactInfo AS 'matter_contact',
a.DESCRIPTION AS 'matter_arrangement',
m.BillingInstruc AS 'billing_instructions',
m.Comments AS 'terms',
m.Number AS 'matter_id',
c.DisplayName AS 'client_name',
m.DisplayName AS 'matt_desc',
m.Narrative_UnformattedText AS 'matt_nar',
btk.Number AS 'batty_id',
btk.DisplayName AS 'batty_name',
tk.Number AS 'tk_id',
tk.DisplayName AS 'tk_name',
td.HireDate AS 'tkemdate',
title.DESCRIPTION AS 'tktitle',
htitle.DESCRIPTION AS 'htitle',
CASE htitle.DESCRIPTION
WHEN 'partner'
THEN 1
WHEN 'associate'
THEN 2
WHEN 'summer assoc.'
THEN 3
WHEN 'staff counsel'
THEN 4
WHEN 'paralegal'
THEN 5
WHEN 'als'
THEN 6
WHEN 'CSS admin'
THEN 7
WHEN 'legal graphics'
THEN 8
WHEN 'library'
THEN 9
WHEN 'case clerks'
THEN 10
WHEN 'lit analyst'
THEN 11
ELSE 12
END AS 'tktitle_sort',
d.DESCRIPTION AS 'mdept',
pg.DESCRIPTION AS 'mprac',
o.DESCRIPTION AS 'mloc',
tc.TimeIndex AS 't_index',
tc.WorkDate AS 'worked_date',
CONVERT(VARCHAR(6),tc.workdate,112) AS 'worked_period',
tc.WorkHrs AS 'tworkhrs',
tc.WorkRate AS 'tworkrt',
tc.WorkAmt AS 'tworkdol',
tc.WIPRemoveDate AS 'tbilldt',
tc.WIPHrs AS 'tbillhrs',
tc.WIPRate AS 'tbillrt',
tc.WIPAmt AS 'tbilldol',
tc.Narrative_UnformattedText AS 'time_desc',
'' AS 'ccode',
'' AS 'codesc1',
CASE
WHEN tc.IsNB = 1
THEN 0.00
ELSE tc.WIPAmt - tc.WorkAmt
END AS 'adj'
INTO #fees_detail
FROM timecard tc WITH (NOLOCK)
INNER JOIN matter AS m WITH (NOLOCK)
ON tc.matter = m.mattindex
INNER JOIN #MatterList AS tm
ON m.Number = tm.MatterNumber
INNER JOIN mattdate AS md WITH (NOLOCK)
ON m.MattIndex = md.MatterLkUp
AND CONVERT(DATE,GETDATE()) BETWEEN md.NxStartDate AND md.NxEndDate
INNER JOIN client AS c WITH (NOLOCK)
ON m.client = c.ClientIndex
INNER JOIN PracticeGroup AS pg WITH (NOLOCK)
ON md.PracticeGroup = pg.Code
INNER JOIN Department AS d WITH (NOLOCK)
ON md.Department = d.Code
INNER JOIN Arrangement AS a WITH (NOLOCK)
ON md.Arrangement = a.Code
INNER JOIN Office AS o WITH (NOLOCK)
ON md.Office = o.Code
INNER JOIN Timekeeper AS tk WITH (NOLOCK)
ON tc.Timekeeper = tk.TkprIndex
INNER JOIN TkprDate AS td WITH (NOLOCK)
ON tk.TkprIndex = td.TimekeeperLkUp
AND CONVERT(DATE,GETDATE()) BETWEEN td.NxStartDate AND td.NxEndDate
INNER JOIN TkprDate AS htd WITH (NOLOCK)
ON tk.TkprIndex = htd.TimekeeperLkUp
AND tc.WorkDate BETWEEN htd.NxStartDate AND htd.NxEndDate
INNER JOIN Timekeeper AS btk WITH (NOLOCK)
ON md.BillTkpr = btk.TkprIndex
INNER JOIN title WITH (NOLOCK)
ON td.title = title.code
INNER JOIN title AS htitle WITH (NOLOCK)
ON htd.title = htitle.code
LEFT OUTER JOIN task AS t WITH (NOLOCK)
ON tc.Task = t.TaskID
Where tc.WorkDate between #startDate and #enddate
ORDER BY m.Number, tc.WorkDate, tc.TimeIndex
SELECT
[type], tudef2, bfindt, isActive, isNoCharge, mopendt, mclosedt, matter_contact,
matter_arrangement, billing_instructions, terms, matter_id, client_name, matt_desc, matt_nar,
batty_id, batty_name, tk_id, tk_name, tkemdate, tktitle, htitle, tktitle_sort, mdept, mprac,
mloc, t_index, worked_date, worked_period, tworkhrs, tworkrt, tworkdol, tbilldt, tbillhrs,
tbillrt, tbilldol, time_desc, ccode, codesc1, adj
FROM #fees_detail
ORDER BY 29
GO flags the end of a batch of statements, i.e. everything from the beginning of the file (or the previous GO) is sent as one batch, and executed; this was probably ok, then everything following GO until the end of the file or the next GO is sent and executed, when this happened your declarations were already gone (not part of this batch. Remove GO.

WHERE not null for nested column SQL

I have a select statement with a nested column called Contents
EDIT: this is the full statement, just need results back without Contents at null.
Playlists = (
Select pl.Id as Id
,pl.Name as Name
,f.[Url] as PrimaryImageUrl
,up.Id as MemberId
,up.ProfessionalName
,up.AvatarUrl
,Contents = ( select c.Id as Id
,c.Name as Name
,c.ContentImageUrl as ImageUrl
,c.Price as Price
,c.BPM as BPM
,f.Id as 'File.Id'
,f.Url as 'File.Name'
,g.Id as 'Genre.Id'
,g.Name as 'Genre.Name'
,kt.Id as 'KeyType.Id'
,kt.Name as 'KeyType.Name'
,tt.Id as 'TrackType.Id'
,tt.Name as 'TrackType.Name'
,TotalCount = count(c.Id)Over()
from dbo.Content c
inner join dbo.PlayListContents pm on c.Id = pm.ContentId and pm.PlaylistId = pl.Id
inner join dbo.Files f on c.ContentFileId = f.Id
inner join dbo.Genres g on c.GenreTypeId = g.Id
inner join dbo.KeyType kt on c.KeyTypeId = kt.Id
inner join dbo.TrackType tt on tt.Id = c.TrackTypeId
WHERE (NOT EXISTS (SELECT b.Bpm
FROM #Bpm AS b
WHERE b.Bpm IS NOT NULL)
OR c.Bpm IN (SELECT * FROM #Bpm))
AND (NOT EXISTS (SELECT p.Price
FROM #Price AS p
WHERE p.Price IS NOT NULL)
OR c.Price <= ANY(SELECT * FROM #Price ))
AND (NOT EXISTS (SELECT gt.GenreTypeId
FROM #GenreTypeId AS gt
WHERE gt.GenreTypeId IS NOT NULL)
OR g.Id IN (SELECT * FROM #GenreTypeId))
AND (NOT EXISTS (SELECT kt.KeyTypeId
FROM #KeyTypeId AS kt
WHERE kt.KeyTypeId IS NOT NULL)
OR kt.Id IN (SELECT * FROM #KeyTypeId))
AND (NOT EXISTS (SELECT tt.TrackTypeId
FROM #TrackTypeId AS tt
WHERE tt.TrackTypeId IS NOT NULL)
OR tt.Id IN (SELECT * FROM #TrackTypeId))
for json path
)
from dbo.Playlist pl
inner join dbo.UserProfiles up on pl.UserId = up.UserId
inner join [dbo].[Files] as f ON pl.[PrimaryImageId] = f.[Id]
where ( pl.Name LIKE '%' + #SearchInput + '%')
order by newId()
For Json path)
Right now, the result set will bring back objects with some having Contents at null.
I tried to write out a WHERE Contents IS NOT NULL but this doesn't work. What am I missing?

using CTE while declaring variables in SQL

I have two decraed variables and I am trying to set the values from the result of my CTE,
declare #Total_new_claims_received int
declare #Total_Claims_Processed int
End solution I'm looking for is being able to set both declared values from CTE results:
select #Total_new_claims_received = count(id)
from cte
where benefit_code_id not in ('739')
select #Total_Claims_Processed = count(id)
from cte2
where benefit_code_id not in ('739')
Current Code:
declare #Total_new_claims_received int
declare #Total_Claims_Processed int
with cte (ID, Date)
as (
select c.id, c.date
from axiscore.dbo.claim c with (nolock)
inner join claim_line cl on c.Claim_ID = cl.Claim_ID and cl.Linenum = 1
left join axiscore.dbo.member_policy mp with (nolock) on c.Member_Policy_ID = mp.Member_Policy_ID
left join axiscore.dbo.policy p with (nolock) on mp.policy_id = p.policy_id
inner join axiscore.dbo.Claim_Status s with (nolock) on c.Claim_Status_ID = s.Claim_Status_ID
left outer join axiscore.dbo.Claim_Reason_Type r with (nolock) on c.Claim_Reason_Type_ID = r.Claim_Reason_Type_ID
where
c.Updated_Date between '10-1-2019' and '10-31-2019'
and p.Payor_ID = 8
and (c.Claim_Status_ID <> 8)),
cte2 (ID, Date)
as
(
select c.id, c.date
from axiscore.dbo.claim c with (nolock)
inner join claim_line cl on c.Claim_ID = cl.Claim_ID and cl.Linenum = 1
left join axiscore.dbo.member_policy mp with (nolock) on c.Member_Policy_ID = mp.Member_Policy_ID
left join axiscore.dbo.policy p with (nolock) on mp.policy_id = p.policy_id
inner join axiscore.dbo.Claim_Status s with (nolock) on c.Claim_Status_ID = s.Claim_Status_ID
left outer join axiscore.dbo.Claim_Reason_Type r with (nolock) on c.Claim_Reason_Type_ID = r.Claim_Reason_Type_ID
where
c.Updated_Date between '10-1-2019' and '10-31-2019'
and p.Payor_ID = 8
and (c.Claim_Status_ID in (7,6))
and (c.Claim_Reason_Type_ID not in (136,137)))
select #Total_new_claims_received = count(id)
from cte
where benefit_code_id not in ('739')
select #Total_Claims_Processed = count(id)
from cte2
where benefit_code_id not in ('739')
Currently,
it's only setting the value for Total_new_claims_received. It errors out on the second select when I'm setting the value for Total_Claims_Processed. The error is 'invalid object name 'cte2'.
I'm using CTE instead of temp tables becuase I'm calling this proc in a SSIS package. SSIS package doesn't do well with Temp tables. Any other ideas welcome as well.
thanks for your time!
From WITH common_table_expression (Transact-SQL):
A CTE must be followed by a single SELECT, INSERT, UPDATE, or
DELETE statement that references some or all the CTE columns
So define each of your CTEs before each of the select statements that uses it:
declare #Total_new_claims_received int
declare #Total_Claims_Processed int
with cte (ID, Date) as (
select c.id, c.date
from axiscore.dbo.claim c with (nolock)
inner join claim_line cl on c.Claim_ID = cl.Claim_ID and cl.Linenum = 1
left join axiscore.dbo.member_policy mp with (nolock) on c.Member_Policy_ID = mp.Member_Policy_ID
left join axiscore.dbo.policy p with (nolock) on mp.policy_id = p.policy_id
inner join axiscore.dbo.Claim_Status s with (nolock) on c.Claim_Status_ID = s.Claim_Status_ID
left outer join axiscore.dbo.Claim_Reason_Type r with (nolock) on c.Claim_Reason_Type_ID = r.Claim_Reason_Type_ID
where
c.Updated_Date between '10-1-2019' and '10-31-2019'
and p.Payor_ID = 8
and (c.Claim_Status_ID <> 8)
)
select #Total_new_claims_received = count(id)
from cte
where benefit_code_id not in ('739');
with cte2 (ID, Date) as (
select c.id, c.date
from axiscore.dbo.claim c with (nolock)
inner join claim_line cl on c.Claim_ID = cl.Claim_ID and cl.Linenum = 1
left join axiscore.dbo.member_policy mp with (nolock) on c.Member_Policy_ID = mp.Member_Policy_ID
left join axiscore.dbo.policy p with (nolock) on mp.policy_id = p.policy_id
inner join axiscore.dbo.Claim_Status s with (nolock) on c.Claim_Status_ID = s.Claim_Status_ID
left outer join axiscore.dbo.Claim_Reason_Type r with (nolock) on c.Claim_Reason_Type_ID = r.Claim_Reason_Type_ID
where
c.Updated_Date between '10-1-2019' and '10-31-2019'
and p.Payor_ID = 8
and (c.Claim_Status_ID in (7,6))
and (c.Claim_Reason_Type_ID not in (136,137))
)
select #Total_Claims_Processed = count(id)
from cte2
where benefit_code_id not in ('739');