Stored Procedure If / Then Statement - sql-server

We are trying to implement a password interval, if there is one.
If sm_Setting(PasswordExpireDays) has a value, we use it. If not, continue on
CREATE Procedure user_password_date_interval_check
#ua_pk uniqueidentifier
AS
DECLARE #PasswordExpireDays int
SET #PasswordExpireDays = 0
SELECT
sm_Setting, sm_Value
FROM
Setting_Misc AS sm
INNER JOIN
Syndicates As syn ON sm.syn_fk = syn.syn_pk
INNER JOIN
Company As c ON c.syn_fk = syn.syn_pk
INNER JOIN
User_Accounts As ua ON ua.c_fk = c.c_pk
WHERE
sm.sm_Setting = 'PasswordExpireDays'
THEN sm.sm_Value = #PasswordExpireDays
I'm having issues with the WHERE clause. I have tried CASE. Bottom line is, this row (based on a PK and Setting), I want to grab the value from the Value column.

CREATE Procedure user_password_date_interval_check
#ua_pk uniqueidentifier
AS
DECLARE #PasswordExpireDays int
SELECT
--sm_Setting,
#PasswordExpireDays =COALESCE(sm_Value,0)
FROM
Setting_Misc AS sm
INNER JOIN
Syndicates As syn
ON sm.syn_fk = syn.syn_pk
INNER JOIN
Company As c
ON c.syn_fk = syn.syn_pk
INNER JOIN
User_Accounts As ua
ON ua.c_fk = c.c_pk
WHERE sm.sm_Setting = 'PasswordExpireDays'
--#PasswordExpireDays is either default 0 or the value from the table if not null.

Related

Query works as expected, SSRS finds error?

This question was closed because someone thought it was the same issue as SSRS multi-value parameter using a stored procedure
But it is not. My report is not a stored procedure and thus, behaves differently. Also, this issue describes a result of getting no results if multi-valued params are used and that too is inaccurate for this scenario. So I'll try posting this again.
My report for the most part works. It is when I select more than one value from either of 2 specific params (#global, #manual) that I get this error:
Here is the SQL:
DECLARE #STATE VARCHAR(2) = 'mn'
,#START DATE = '6/1/2020'
,#END DATE = '7/1/2020'
,#GLOBAL VARCHAR(50) = 'indigent fee'
,#MANUAL VARCHAR(100) = '''misc charges'',''discount'''
DROP TABLE
IF EXISTS #customers
,#test
SELECT DISTINCT ch.amount
,ch.vehicle_program_id
,c.customer_id
,ch.customer_charge_id
,ch.charge_type
INTO #customers
FROM customer c
JOIN customer_charge ch(NOLOCK) ON c.customer_id = ch.customer_id
JOIN service_history sh(NOLOCK) ON sh.customer_id = c.customer_id
JOIN header h(NOLOCK) ON h.service_history_id = sh.service_history_id
WHERE ch.entry_date BETWEEN #START
AND #END
AND ch.price_trigger_id IN (
16
,15
)
AND ch.source_type = 1
AND sh.service_type = 5
AND h.is_duplicate = 0;
WITH CTE_global
AS (
SELECT DISTINCT ch.charge_type
,'global' AS type
FROM customer_charge ch
JOIN store s ON ch.store_id = s.store_id
JOIN address a ON a.id = s.address_id
JOIN locality l ON a.locality_id = l.id
WHERE l.region = #state
AND ch.price_trigger_id = 16
UNION ALL
SELECT 'None'
,'global'
)
,CTE_manual
AS (
SELECT DISTINCT ch.charge_type
,'manual' AS type
FROM customer_charge ch
JOIN store s ON ch.store_id = s.store_id
JOIN address a ON a.id = s.address_id
JOIN locality l ON a.locality_id = l.id
WHERE l.region = #state
AND ch.price_trigger_id = 15
UNION ALL
SELECT 'None'
,'manual'
)
SELECT DISTINCT c.last_name
,c.first_name
,vp.account_no
,cust.charge_type
,cust.amount
,sh.service_date
,s.store_name_short
,GLOBAL = g.charge_type
,manual = m.charge_type
INTO #test
FROM vehicle_program vp(NOLOCK)
JOIN vehicle v(NOLOCK) ON v.vehicle_id = vp.vehicle_id
JOIN service_history sh(NOLOCK) ON sh.vehicle_program_id = vp.program_id
AND service_type = 5
JOIN customer c(NOLOCK) ON v.customer_id = c.customer_id
AND c.customer_id = sh.customer_id
JOIN store s(NOLOCK) ON vp.current_store_id = s.store_id
JOIN #customers cust ON cust.customer_id = c.customer_id
AND cust.vehicle_program_id = sh.vehicle_program_id
JOIN customer_condition cc(NOLOCK) ON c.customer_id = cc.customer_id
JOIN customer_charge ch(NOLOCK) ON ch.customer_id = c.customer_id
JOIN service_charge sc ON sc.service_history_id = sh.service_history_id
AND sc.customer_charge_id = cust.customer_charge_id
JOIN header h(NOLOCK) ON h.service_history_id = sh.service_history_id
JOIN CTE_global g ON g.charge_type = ch.charge_type
JOIN CTE_manual m ON m.charge_type = ch.charge_type
WHERE cc.state_of_conviction = #state
AND sh.service_date BETWEEN #START
AND #END
AND h.is_duplicate = 0
SELECT *
FROM #test
WHERE GLOBAL IN (
CASE
WHEN #global IN ('None')
THEN charge_type
WHEN #global NOT IN ('None')
THEN #global
END
)
OR manual IN (
CASE
WHEN #manual IN ('None')
THEN charge_type
WHEN #manual NOT IN ('None')
THEN #manual
END
)
For clarity, the last bit in the query there is some logic to allow for these two params to be optional: so by selecting 'None' that param is rendered useless basically. It seems clear that the issue is with this last bit, specifically my WHERE clause using the CASE expression. When I remove that, I don't get the error, but I of course lose my logic. What's most confusing is that the error indicates an issue with a comma, but there's no comma in that part of the SQL?? Any help is going to be greatly appreciated.
Assuming users will only select 'None' from the list on it's own and never with another value then the following should work.
WHERE (GLOBAL IN (#Global) OR #Global = 'None')
AND
(manual IN (#manual) OR #manual = 'None')
this question was closed because someone thought it was the same issue
It is a dupe, but you kind of have to read between the lines in the other answers to apply it to this scenario. The point is that SSRS replaces multi-select parameters with delimited strings in the query body itself, and this transformation can lead either to unexpectedly getting no results, or in an illegal SQL query, depending on where the parameter marker appears in the original query.
I'll make it a bit clearer exactly what's going on. You can repro this behavior with this as your Data Set query:
drop table if exists #foo
create table #foo(charge_type varchar(200) , global varchar(200))
select *
from #foo
WHERE GLOBAL IN (
CASE
WHEN #global IN ('None')
THEN charge_type
WHEN #global NOT IN ('None')
THEN #global
END
)
And configure #global as a parameter that allows multi-select. When the user selects multiple values SSRS transforms the query into:
drop table if exists #foo
create table #foo(charge_type varchar(200) , global varchar(200))
select *
from #foo
WHERE GLOBAL IN (
CASE
WHEN N'a',N'b' IN ('None')
THEN charge_type
WHEN N'a',N'b' NOT IN ('None')
THEN N'a',N'b'
END
)
Which fails with An expression of non-boolean type specified in a context where a condition is expected, near ','.

Instantiating temp table based on the result of joins after creating a new variable

I am trying to store the result of a query as a temp table in SQL Server. Can someone explain why the set syntax is wrong here? I thought I followed for format from here correctly.
select *
into #temp_Academic
set XlistGrp_Course_CRN = s.Subject+' '+s.Course_Number+' ('+x.XlistGrp_Course_CRN+')'
from AcademicYear r
inner join Xlist x on r.XlistGrp = x.xlistgrp and r.term=x.term
inner join Sections s on x.term = s.Term and x.XlistGrp_Course_CRN = s.CRN
Error:
Msg 102, Level 15, State 1, Line 21
Incorrect syntax near '='.
That set is for assigning the variable, and I assume you have a typo, missing , in your post. and generally speaking you should not have both select, set in one selecting clause.
What you are looking for is just alias the column, you can try:
select *,XlistGrp_Course_CRN = s.Subject+' '+s.Course_Number+' ('+x.XlistGrp_Course_CRN+')'
into #temp_Academic,
from AcademicYear r
inner join Xlist x on r.XlistGrp = x.xlistgrp and r.term=x.term
inner join Sections s on x.term = s.Term and x.XlistGrp_Course_CRN = s.CRN
OR
select *,s.Subject+' '+s.Course_Number+' ('+x.XlistGrp_Course_CRN+')' as XlistGrp_Course_CRN
into #temp_Academic,
from AcademicYear r
inner join Xlist x on r.XlistGrp = x.xlistgrp and r.term=x.term
inner join Sections s on x.term = s.Term and x.XlistGrp_Course_CRN = s.CRN
For your reference post, the op's question is how to assign the result from a query to one variable instead giving value directly.
Compare:
SELECT #varble = value FROM TABLE -- assume only one value returned
VS
SET #varable = 5 --assume you declared #varable as INT
declare #CListGrp as nvarchar(255)
select *, #XlistGrp_Course_CRN = s.Subject+' '+s.Course_Number+' ('+x.XlistGrp_Course_CRN+')' into #temp_Academic
from AcademicYear r
inner join Xlist x on r.XlistGrp = x.xlistgrp and r.term=x.term
inner join Sections s on x.term = s.Term and x.XlistGrp_Course_CRN = s.CRN

MS SQL Join based on One conditional if NULL, two if value passed

We have an SMS Text Message sender for various merchants that sends text messages based on the merchant ID. They can also send SMS Messages to limiting them to the Location ID.
When the SMS Campaign is set, the Merchant ID (MID) will be set, but the Location ID (LID) will be NULL unless the user wants to limit the SMS campaign to only those that have visited a specific location.
Here's my attempt:
SELECT * FROM tblOrders_SMS
INNER JOIN tblMerchants ON sms_order_mid = merchant_mid
(
CASE
WHEN ISNULL(sms_order_lid,1)
INNER JOIN tblLookup_Locations_Members ON lm_mid = sms_order_mid
ELSE
INNER JOIN tblLookup_Locations_Members ON lm_mid = sms_order_mid AND lm_lid = sms_order_lid
END
)
INNER JOIN tlbMembers ON member_id = lm_member_id
WHERE sms_order_sent = 0
So the idea is do an inner join on just the MID fields if the sms_order_lid is NULL, but if the SMS Campaign order has a LID set in sms_order_lid, then make it join on both fields.
First, ISNULL is a function and replaces a null value if the value in the column is null.
Almost exactly like COALESCE in ANSI-Standard-SQL
It's not an if clause.
Second, if you want to catch NULL in a "case when" clause in T-SQL, your syntax
CASE
WHEN ISNULL(sms_order_lid,1)
...
is wrong, and this syntax is right:
CASE
WHEN sms_order_lid IS NULL THEN [...]
ELSE [...]
END
Third, unless I interpreted your ISNULL wrong, this is what you actually want:
SELECT *
FROM tblOrders_SMS
INNER JOIN tblMerchants
ON sms_order_mid = merchant_mid
INNER JOIN tblLookup_Locations_Members
ON lm_mid = sms_order_mid
AND
(
lm_lid = sms_order_lid
OR
sms_order_lid IS NULL
)
INNER JOIN tlbMembers
ON member_id = lm_member_id
WHERE sms_order_sent = 0
Try this:
SELECT *
FROM tblOrders_SMS
INNER JOIN
tblMerchants ON sms_order_mid = merchant_mid
INNER JOIN
tblLookup_Locations_Members ON
(sms_order_lid IS NULL AND lm_mid = sms_order_mid) OR
(lm_mid = sms_order_mid AND lm_lid = sms_order_lid)
INNER JOIN
tlbMembers ON member_id = lm_member_id
WHERE sms_order_sent = 0

SQL Server stored procedure delete statement

I wish to delete a result a select statement returns, reason I'm doing this is because I have relationships between tables and if I delete from the top-most table its children rows in other tables have to be deleted, too.
Can anyone correct this stored procedure for me please?
ALTER proc [dbo].[storedprocname]
(#Parameter uniqueidentifier = '00000000-0000-0000-0000-000000000000')
AS BEGIN
DELETE FROM TableOne
WHERE IDOne IN
(SELECT
IDOne,
DescOne, IndexOne,
IDTwo,
QuestionTwo, ControlTypeTwo, IndexTwo,
IDThree,
DescThree, IndexThree,
QuestionFour,
OptionFour
FROM
TableOne
INNER JOIN
TableTwo ON TableTwo.CatID = TableOne.IDOne
INNER JOIN
TableThree ON TableThree.Question = TableTwo.IDTwo
LEFT OUTER JOIN
TableFour ON TableFour.Question = TableThree.IDThree
WHERE
TableOne.IDOne = #Parameter)
END
ALTER proc [dbo].[storedprocname]
(#Parameter uniqueidentifier = '00000000-0000-0000-0000-000000000000')
AS BEGIN
DELETE FROM TableOne
WHERE IDOne IN
(SELECT
IDOne
FROM
TableOne
INNER JOIN
TableTwo ON TableTwo.CatID = TableOne.IDOne
INNER JOIN
TableThree ON TableThree.Question = TableTwo.IDTwo
LEFT OUTER JOIN
TableFour ON TableFour.Question = TableThree.IDThree
WHERE
TableOne.IDOne = #Parameter)
END
Since you want to delete all rows where IDOne is in a list of possible values - then you need to make sure the subquery after the IN (...) also returns a single column which can be used to compare! After all, you cannot compare a single IDOne value to the whole list of columns that you're currently returning ....
Try something like this:
ALTER proc [dbo].[storedprocname]
(#Parameter uniqueidentifier = '00000000-0000-0000-0000-000000000000')
AS BEGIN
DELETE FROM TableOne
WHERE IDOne IN
(SELECT
IDOne
FROM
TableOne
INNER JOIN
TableTwo ON TableTwo.CatID = TableOne.IDOne
INNER JOIN
TableThree ON TableThree.Question = TableTwo.IDTwo
LEFT OUTER JOIN
TableFour ON TableFour.Question = TableThree.IDThree
WHERE
TableOne.IDOne = #Parameter)
END
I don't know (your question is too vague and not clear enough) whether all those JOIN's inside the subquery are really needed .... you might need to tweak that to your requirements.

T-SQL stored procedure returns table

How do I make a T-SQL stored procedure that returns the (tabular) result of this SELECT statement:
USE automation
SELECT insurer.name,
insurer.case_name,
contact.name,
contact_address.line_1,
contact_address.city,
state.state_abbr,
contact_address.zip
FROM person as insurer
INNER JOIN persons_relationship on persons_relationship.person2_id = insurer.person_id
INNER JOIN person contact on contact.person_id = persons_relationship.person_id
INNER JOIN person_address contact_person_address on contact_person_address.person_id = contact.person_id
INNER JOIN address contact_address on contact_address.address_id = contact_person_address.address_id
INNER JOIN state on state.state_id = contact_address.state_id
insurer.person_class_id = 2
Do something like this:
USE Automation
GO
CREATE PROCEDURE dbo.YourProcedureNameHere
AS
SELECT
insurer.name,
insurer.case_name,
contact.name,
contact_address.line_1,
contact_address.city,
state.state_abbr,
contact_address.zip
FROM
person as insurer
INNER JOIN
persons_relationship on persons_relationship.person2_id = insurer.person_id
INNER JOIN
person contact on contact.person_id = persons_relationship.person_id
INNER JOIN
person_address contact_person_address on contact_person_address.person_id = contact.person_id
INNER JOIN
address contact_address on contact_address.address_id = contact_person_address.address_id
INNER JOIN
state on state.state_id = contact_address.state_id
and you're done. Now you can call your statement as:
EXEC sp_executesql N'dbo.YourProcedureNameHere'
I suggest you also put
SET NOCOUNT ON
Straight after the AS. Some data access libraries are confused by the x records affected message and this turns it off.
put this query in the stored procedure and when you will run this stored procedure you will get tabular result

Resources