Incorrect syntax near '=' near WHILE LOOP - sql-server

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.

Related

CASE Statement Force an Error Message as a Condition

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.

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 do variables not work with TOP command?

Why does below SQL script throw errors?
Is this issue with TOP command?
Or is it because of the SELECT statement which does not support SQL variables?
My code:
DECLARE #cnt INTEGER = 0;
Declare #cnt_total INT;
SET #cnt_total = 5
WHILE (#cnt < #cnt_total)
BEGIN
SET #cnt = #cnt + 1;
SELECT TOP #cnt *
FROM FOCUSCDR.PATIENTDXHISTORY
END;
Error:
Msg 102, Level 15, State 1, Line 9
Incorrect syntax near '#cnt'.
While above works when used.
SELECT TOP 1 *
FROM FOCUSCDR.PATIENTDXHISTORY
Because the syntax requires parentheses:
DECLARE #cnt INTEGER = 0;
Declare #cnt_total int ;
Set #cnt_total = 5
WHILE (#cnt < #cnt_total)
BEGIN
SET #cnt = #cnt + 1;
Select top (#cnt) * from FOCUSCDR.PATIENTDXHISTORY
END;
Edit:
As mentioned in the comment by #Tim Biegeleisen, you should be using ORDER BY, otherwise it makes no sense using TOP since the order will not be guaranteed and you might get non consistent results. Check out this article for more info on it.

SQL Server if statement does not execute as expected

I am trying to use the following stored procedure but there are some instances WHERE only the incremental happens AND the code does not run. What I need is that, when the program enters the IF statement, either it should run both the statements or None.
Stored procedure goes like this:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spflpunch]
AS
BEGIN
DECLARE #id NUMERIC(18,0)
DECLARE #studname NVARCHAR(50)
DECLARE #punchtime DATETIME
DECLARE #samedaycount NUMERIC(2)
SELECT #id = (MAX(lastid)) FROM [smartswype].[dbo].[read]
PRINT #id
SELECT #studname = studname
FROM [SSWYPE_WEBDB].[dbo].[attdview]
WHERE id =#id
PRINT #studname
SELECT #punchtime = punchtime
FROM [SSWYPE_WEBDB].[dbo].[attdview]
WHERE id = #id
PRINT #punchtime
--SELECT #punchvarchar = CONVERT(VARCHAR(10),#punchtime, 103) + ' ' + CONVERT(VARCHAR(5), #punchtime, 14)
IF #id = (SELECT MAX(id) FROM [SSWYPE_WEBDB].[dbo].[attdview])
BEGIN
SELECT #samedaycount = COUNT(*)
FROM [SSWYPE_WEBDB].[dbo].[attdview]
WHERE (studname = #studname
AND CONVERT(DATE, punchtime) = CONVERT(DATE, #punchtime)) -- If firstpunch = 1 then it is the first punch
PRINT #samedaycount
IF #samedaycount =1
BEGIN
INSERT INTO [smartswype].[dbo].[firstlastpunch] ([studname], [DATE], [punch1], [punch2])
VALUES(#studname, CONVERT(DATE, #punchtime), #punchtime, NULL);
UPDATE [smartswype].[dbo].[read]
SET lastid = #id + 1;
END
ELSE IF (#samedaycount > 1)
BEGIN
UPDATE [smartswype].[dbo].[firstlastpunch]
SET punch2 = #punchtime
WHERE (studname = #studname AND DATE = CONVERT(DATE, #punchtime));
UPDATE [smartswype].[dbo].[read]
SET lastid = #id + 1;
END
END
END
If you want to ensure that both or none of the statements run, you should wrap the contents of the if statement in a transaction.
By wrapping it in a transaction, you can ensure that if one statement fails, that the other statement will not run.
Here is a link to the docs on transactions in SQL Server
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/commit-transaction-transact-sql

T - SQL statement IF EXIST SELECT and INSERT

How can I make this possible..really need advice? I want to get the id where my condition is met, then used it in my queries.
IF EXISTS (Select sn_id as snid FROM device.sn WHERE dname_id = 62 and sn_value = '123415')
BEGIN
SELECT MAX(id) AS maxid FROM device.list
INSERT INTO parts (sn_id,device_id) VALUES (snid, maxid)
END
ELSE
BEGIN
PRINT 'id does not exist'
return
END
You can use variables to store the results from the two queries and then use those values in your INSERT statement.
If you're using Microsoft SQL Server then the following may work (but there may be superficial syntax errors as it hasn't been tested). Note that I've assumed the type of your columns is int.
DECLARE #snid int
SET #snid = NULL
Select #snid = sn_id FROM device.sn WHERE dname_id = 62 and sn_value = '123415'
IF #snid IS NULL
BEGIN
PRINT 'id does not exist'
END
ELSE
BEGIN
DECLARE #maxid int
SELECT #maxid = MAX(id) AS maxid FROM device.list
INSERT INTO parts (sn_id,device_id) VALUES (#snid, #maxid)
END
In SQLServer. This script at first insert records and after checks count of the inserted rows
INSERT INTO parts (sn_id, device_id)
SELECT sn_id, (SELECT MAX(id) FROM device.list)
FROM device.sn
WHERE dname_id = 62 and sn_value = '123415'
IF ##ROWCOUNT = 0 PRINT 'id does not exist'
Declare #snid int=null
Declare #maxid int=1 -- if no value exists in device.list table
set #snid = (select sn_id from device.sn WHERE dname_id = 62 and sn_value = '123415')
set #maxid = (select MAX(id) AS maxid FROM device.list)
if #snid is not null
Begin
insert into parts(sn_id,device_id)
values(#snid,#maxid)
End
else
Begin
print 'ID does not exist'
End

Resources