CASE Statement Force an Error Message as a Condition - sql-server

I want to implement this sort of logic:
select
many_columns,
case
when something then 'whatever'
else Generate Error Message and Stop the Query
end as [whatever]
from
table_1
Is this possible?
Edit #1:
Based on the comments that I got, I did some experimenting.
drop table if exists #testing;
go
with whatever as (
select 1 as [num] union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9 union
select 10
)
declare #counter INT
set #counter = 0
while (#counter <= (select count(*) from #testing))
begin
IF (#counter) < 5
print 'hi'
set #counter = #counter + 1
else
select * from #testing
print 'bye'
select #counter = #counter + 1
end
go
Hmm...the If statement is having issues with the else part...all I get is "Incorrect Syntax".

Seems the answer to my question is to combine a while loop with an if statement AFTER producing my main query to find the error message.
The final if statement will look something like this:
declare #counter INT
set #counter = 0
while (#counter <= (select count(*) from #testing))
begin
--print #counter
IF (#counter = (select [num] from #testing where [num] = #counter))
--print 'hi'
print cast(#counter as varchar) + ' ' + 'hi'
else
--select * from #testing where [num] = #counter
--print 'bye'
print cast(#counter as varchar) + ' ' + 'bye'
select #counter = #counter + 1
end
go

I can't put it better than the comment from #marc_s:
CASE in T-SQL is an expression (like a+b) that returns a single, atomic value. It is NOT a construct to deal with program flow and such - for that, you need to use IF / ELSE
👍
So let's take your original CASE expression code:
case
when something then 'whatever'
else Generate Error Message and Stop the Query
end as [whatever]
As an IF/ELSE (using BEGIN/END) flow:
IF call_that_a_knife = 'yes'
BEGIN
SELECT 'This is a knife' AS yes_i_call_that_a_knife;
END
ELSE
BEGIN
RAISERROR ('That's not a knife!', 16, 1);
END
;
RAISERROR()

The way I have implemented this kind of construct is by attempting to perform an addition operation with the error message in case the condition for the error is true:
select
many_columns,
1 + case
when <error_condition>
then 'Error Message Here will Stop the Query'
else 0 end as [success]
from
table_1
Assuming that the <error_condition> uses data from the rows fetched from table_1 or calls out some function that returns a value that may mean an error condition, this will run the query until it reaches the point the condition is true and then will error out with something like:
Msg 245, Level 16, State 1, Line 15
Conversion failed when converting the varchar value 'Error Message Here will Stop the Query' to data type int.

Related

How do I use WHILE loop in CASE statement in SQL

In 'CASE' statement in SQL we use a bool condition and get a TRUE or FALSE result. In this situation I have to use non-bool unlimited condition. But I can't...
ALTER proc [dbo].[sp_StudentList](#CreatedBy nvarchar(max))
as
begin
declare #LikedBy nvarchar(max) = (Select LikedBy from LikeStatus)
declare #TeacherRequestID int = (Select TeacherRequestID from LikeStatus where LikedBy=#CreatedBy)
declare #UserName nvarchar(max) = #CreatedBy
declare #i int = 1
declare #NumberOfRows int = (select count(*) from TeacherRequest)
select SP.StuThana, SP.StuDist, TR.StudentName,TR.StudentCode, TR.Class, TR.Subject, TR.StuGroup,TR.StuRelation, TR.Institute,TR.Status, TR.LikeStatus,
**CASE
WHEN
WHILE(#i <= #NumberOfRows)
BEGIN
#TeacherRequestID = TR.ID THEN 'Liked' Else 'Like'
set #i = #i + 1
END
END as LikeFlag**
from StudentsProfile SP join TeacherRequest TR on SP.CreatedBy=TR.CreatedBy
--sp_StudentList 'teacher1#gmail.com'
end
The technical answer to your question as posed in your title is that you can't.
declare #i int = 5;
select case when (while #i > 0 begin set #i = #i - 1 end) then 1 else 0 end;
-- Incorrect syntax near the keyword 'while'
Is your intention to just determine whether a student listed in a row likes the associated teacher? If so, then you're looking for whether an entry exists in another table, not how often it occurs. And I would tie it to sp.createdBy, not #createdBy.
select // ...,
likeFlag =
case when exists (
select 0
from likeStatus ls
where ls.likedBy = sp.createdBy
and ls.TeacherRequestId = tr.id
) then 'Liked'
else 'Like'
end
from studentsProfile sp
join teacherRequest tr on sp.createdBy = tr.createdBy
If for some reason you really only need 'Liked' based on #createdBy, then change ls.likedBy = sp.createdBy to ls.likedBy = #createdBy, but I don't see a strong use case for that.

Why am I always getting "The multi-part identifier Column could not be bound"?

I'm new to SQL Server and I want to compare a value from one column with another value from another column. The flow was like this:
if value from table1 != value from table 2
continue
...but how do I just compare the value from the columns.
If I do SELECT #variable=COLUMN FROM TABLE and IF #variable1!=#variable2, it is not working.
I'm using SQL Server 2012.
Here's the query:
SELECT #AgentID=AGENTID
,#CreateTime1=CREATEDATE
FROM AGENT
SELECT #Agid=AgentNo
,#CreateTime2=[Join Date]
,#AccCount2=AgentID
FROM LOCALDB_AGENT
IF #CreateTime1>#CreateTime2
BEGIN
IF #AgentID!=#Agid
BEGIN
INSERT INTO LOCALDB_AGENT (AgentName,AgentID,AgentNo,Email,[Join Date],CreatedDate)
SELECT [FIRSTNAME],[AGENTID],[AGENTID],[EMAIL],CREATEDATE,GetDate() AS CreatedDate
FROM AGENT
WHERE #AgentID!=#Agid
SELECT #AccCount2=COUNT(*)
FROM LOCALDB_AGENT
WHERE [Status]='ACTIVE' AND CreatedDate=Getdate()
SET #msg = 'New Record to DMTM' + ' = ' + #AccCount2 + char(10)
PRINT #msg
END
ELSE
BEGIN
PRINT 'Data Already Exist'
END
END
Option1:
IF (SELECT 1) != (SELECT 2)
BEGIN
PRINT 'CONTINUE'
END
Else you can use a variable to store the column value and then compare the variables.
Option2:
DECLARE #Variable1 INT
DECLARE #Variable2 INT
SELECT #Variable1 = 1
SELECT #Variable2 = 2
IF #Variable1 != #Variable2
BEGIN
PRINT 'CONTINUE'
END
REPLACE the SELECT Statement with your query

BEGIN...END block in SQL Server

Are there any rules defined for grouping the T-SQL statements under the BEGIN...END block ?
Because when I try the BEGIN...END block inside the CASE statement OR IIF statement, it fails.
I need BEGIN...END block because there are multiple operations that I want to perform under the CASE result.
SELECT
CASE #ChargePaid
WHEN 1 THEN
BEGIN
SELECT 'Paid'
END
WHEN 0 THEN
BEGIN
SELECT 'Not Paid'
END
END
OR
SELECT IIF( #ChargePaid > 0, BEGIN SELECT 'Paid' END , BEGIN SELECT 'Not Paid' END )
EDIT:
IF #cond = 'First'
WITH CTE AS (
SELECT 'A missing' Result
UNION
SELECT 'B missing' Result
UNION
SELECT 'C missing' Result
)
SET #msg = SELECT Result from CTE
IF #cond = 'Second'
WITH CTE AS (
SELECT 'A missing' Result
UNION
SELECT 'B missing' Result
UNION
SELECT 'C missing' Result
)
SET #msg = SELECT Result from CTE
IF #ChargePaid = 0
...
Some code goes here to generate the message.
Then I store the actual message into #msg variable.
...
In the end I store the #msg values (I trim the #msg if it requires) to the table.
What I want is:
I want to validate the #ChargePaid condition.
If it comes false, I want to avoid further processing for optimization of code & store charge missing info to #msg variable\table.
BEGIN / END delimit program statements.
Encloses a series of Transact-SQL statements so that a group of Transact-SQL statements can be executed.
CASE blocks accept expressions.
Evaluates a list of conditions and returns one of multiple possible result expressions.
So you are trying to fit a square peg in a round hole.

Incorrect syntax near '=' near WHILE LOOP

I've wirtten below script, but when i try to execute it give below err -
Msg 102, Level 15, State 1, Line 6 Incorrect syntax near '='.
declare #PostDate date
declare #PostID int
DECLARE #count INT
DECLARE #updatecounter INT
WHILE exists (select top 1 #PostDate = postdate from dateTemp order by postdate desc)
BEGIN
PRINT #PostDate
SELECT #count = COUNT(*) from cs_posts_bkup20160209 where CONVERT(date,Postdate) = #PostDate
print #COUNT
SET #updatecounter = 1
WHILE (#count>=1)
BEGIN
select top 1 #PostID = PostId from cs_posts_bkup20160209 where CONVERT(date,Postdate) = #PostDate and Postorder IS NULL order by postdate desc
pRINT #POSTID
--update cs_posts_bkup20160209 set PostOrder = #updatecounter where postid= #PostID
SET #updatecounter = #updatecounter + 1
SET #count = #count - 1
Print #updatecounter
Print #count
END
DELETE from dateTemp where Postdate = #PostDate
END
GO
what i am missing here...
please help!!
If you assign a variable in a select, the select will not also return a result set - and a result set is required for EXISTS.
Easiest fix is probably to re-run the query that sets #PostDate inside your loop and remove the assignment from the query used by the while loop.

Update column using comma-separated values in SQL Server

I have 2 tables in SQL Server:
Table1
ID SkillSetRequired SkillDesc
1 100-1,101-1,102-2,103-3 null
2 100-4,105-2 null
3 100-1,102-2,104-2 null
4 100-5,102-2 null
5 105-1 null
Table2
ID SkillName
100 .Net
101 Java
102 JQuery
103 Sql
104 PHP
105 C
I need to update the SkillDesc column of Table1 with the SkillNames. For example in first row I need to update skilldesc as '.Net,Java,Jquery,SQL'
How can I do this with out using cursors?
I am getting the result in a string from the below query for a single record. But I need to update all the rows.
declare #result varchar(max)
SET #result = ''
SELECT #result = #result + ltrim(rtrim(SkillName)) + ',' from #Table2 where id in(
select SUBSTRING(items, 0 + 1, CHARINDEX('-', items, 1) - 0 - 1) from split('100-1,101-1,102-2,103-3',','))
select #result
Firstly, How did u insert 100-1,101-1,102-2,103-3 into the table ?
Do the below maping while adding the above.
Use a Case statement like
Case
when #Skillset = '100' THEN #desc = .Net
when #Skillset = '101' THEN #desc = Java
....
END
same way for other skill sets.
Then while inserting into the table for every id add the skillset and use the #Desc for the which updates
How did u manage adding 100-1,101-1,102-2,103-3 . This is not the proper way to add...
I think cursor is the best option even though it is taking time to execute.
SELECT ID,SkillSetRequired
FROM #Table1
OPEN #CurSkillUpdate
FETCH NEXT
FROM #CurSkillUpdate INTO #id,#skills
WHILE ##FETCH_STATUS = 0
BEGIN
SET #result = ''
SELECT #result = #result + ltrim(rtrim(SkillName)) + ',' from #Table2 where id in(
select SUBSTRING(items, 0 + 1, CHARINDEX('-', items, 1) - 0 - 1) from split(#skills,','))
update #Table1 set SkillDesc=#result where ID= #id
FETCH NEXT
FROM #CurSkillUpdate INTO #id,#skills
END

Resources