I have some T-SQL code using multiple if statements (about 100) as below. If the first IF statement condition evaluates to TRUE it still evaluates the rest of 99 statements.
IF(#check = 'abc') SET #var1 = #value
IF(#check = 'def') SET #var2 = #value
IF(#check = 'ghi') SET #var3 = #value
IF(#check = 'jkl') SET #var4 = #value
IF(#check = 'mno') SET #var5 = #value
…
…
I want to convert these to use a CASE Expression. for e.g
CASE #check
WHEN 'abc' THEN SET #var1 = #value
WHEN 'def' THEN SET #var2 = #value
WHEN 'ghi' THEN SET #var3 = #value
WHEN 'jkl' THEN SET #var4 = #value
WHEN 'mno' THEN SET #var5 = #value
…
…
END
However, I am not able to do so, and I get a SQL error that says I cannot use SET within a CASE Expression.
Does anyone have any ideas how I can achieve this? Thanks!
A case statement won't cut it: the only way you can use SET with CASE is to do:
SET #var = CASE #check
WHEN 'abc' THEN #value
[etc]
END
...which won't work for you as this can only set a single variable. So you need to use ELSE, i.e.:
IF (#check = 'abc') SET #var1 = #value
ELSE IF (#check = 'def') SET #var2 = #value
ELSE IF (#check = 'ghi') SET #var3 = #value
ELSE IF (#check = 'jkl') SET #var4 = #value
ELSE IF (#check = 'mno') SET #var5 = #value
[...]
However if you've got 100 clauses like this setting 100 different variables then it sounds like your approach may be wrong: I'd take a step back and ask yourself why you need 100 separate variables. There may be something better you can do as a set-based solution, either reading from core or temporary tables. However we'd need more details of what you're trying to do (with a small, but fully working, example).
As an ammendment to Chris J's answer. Anyone here looking to set MULTIPLE parameters within a single if, else if or else -- use the following syntax:
IF (#check = 'abc')
begin
SET #var1 = #value
SET #var2 = #value
end
ELSE IF (#check = 'def')
begin
SET #var1 = #value
SET #var2 = #value
end
ELSE IF (#check = 'ghi')
begin
SET #var1 = #value
SET #var2 = #value
end
ELSE IF (#check = 'jkl')
begin
SET #var1 = #value
SET #var2 = #value
end
ELSE IF (#check = 'mno')
begin
SET #var1 = #value
SET #var2 = #value
end
Notice the use of "begin" and "end" statements. These keywords are analogous to the curly braces found in most programming languages and allow for multiple lines to be specified in a given statement.
Related
I don't know how to change the value of already declared variable.
I want to update something in my table base on the declared variable.
what I've tried so far
IF NOT EXISTS
(SELECT 1 FROM [DB_databaseOne].[dbo].[data_tblOne]
WHERE orderBy= 'AC038234'
and prodCode = 'P0008'
and batchID = '1'
and is_buy = 3 and voidFlag is null)
BEGIN
DECLARE #MSG VARCHAR(300) = 'GOOD'
END
ELSE
BEGIN
DECLARE #MSG VARCHAR(300) = 'NOT GOOD'
END
You should DECLARE your variable only once. You can have multiple SET statements to assign a value:
DECLARE #MSG VARCHAR(300)
IF NOT EXISTS
(SELECT 1 FROM [DB_databaseOne].[dbo].[data_tblOne]
WHERE orderBy= 'AC038234'
and prodCode = 'P0008'
and batchID = '1'
and is_buy = 3 and voidFlag is null)
BEGIN
SET #MSG = 'GOOD'
PRINT #MSG
END
ELSE
BEGIN
SET #MSG = 'NOT GOOD'
PRINT #MSG
END
I have a filter and condition in a function, which works for only one condition
i:e '='
I want it to work for all condition like ' IN', ' >=', '<='
Here is the Code
declare #filter VARCHAR(1000)
DECLARE #TempFilter VARCHAR(1000)
declare #Condition VARCHAR(1000)
set #Condition='Blocked'
SET #Filter=N'Blocked=0 and TYPE = 2 and ID = 1635729'
SET #Condition=#Condition+'='
SELECT
#TempFilter=SUBSTRING(#Filter,CHARINDEX(#Condition,#Filter),LEN(#Filter))
IF CHARINDEX('and',#TempFilter)=0
BEGIN
SET #Filter=SUBSTRING(#Filter,CHARINDEX(#Condition,#Filter)+LEN(#Condition),
LEN(#Filter)-LEN(#Condition)-LEN(#TempFilter))
END
ELSE
BEGIN
SET #Filter=SUBSTRING(#Filter,CHARINDEX(#Condition,#Filter)+LEN(#Condition),
CHARINDEX(' ',#TempFilter)-LEN(#Condition))
END
Please help or suggest.
Can you test this code
DECLARE #tempFilter VARCHAR(1000)
declare #condition VARCHAR(1000)
declare #filter VARCHAR(1000)
declare #operator VARCHAR(1000)
declare #trimmedFilter VARCHAR(1000)
set #Condition='Blocked'
SET #filter=N'Blocked IN(0) and TYPE > = 2 and ID IN (1635729,15454)'
WHILE LEN(#Filter) > 0
BEGIN
IF CHARINDEX(' and',#filter)<> 0
begin
SET #TempFilter = RIGHT ( #filter , LEN(#filter) - CHARINDEX(' and',#filter)-4)
SET #filter = LEFT ( #filter , CHARINDEX(' and',#filter))
end
SET #trimmedFilter = REPLACE(#filter,' ','')
set #operator =
case
when CHARINDEX('NOTIN(',#trimmedFilter) <> 0 then 'NOTIN'
when CHARINDEX('IN(',#trimmedFilter) <> 0 then 'IN'
when CHARINDEX('>=',#trimmedFilter) <> 0 then '>='
when CHARINDEX('<=',#trimmedFilter) <> 0 then '<='
else '='
end
IF CHARINDEX(#Condition,#filter) <> 0
BEGIN
SET #filter = REPLACE(RIGHT(#trimmedFilter,LEN(#trimmedFilter) - CHARINDEX(#operator,#trimmedFilter)+1), 'NOTIN', 'NOT IN')
BREAK
END
ELSE
BEGIN
SET #filter = #TempFilter
CONTINUE
END
END
I am developing a stored procedure to update specific columns using parameters.
For example:
CREATE PROCEDURE save_proc
(
#userid varchar(5),
#column varchar(10),
#data varchar(50)
)
AS
BEGIN
UPDATE MyProfile
SET #column = #data
WHERE userid = #userid
The following is my code that I've tried but didn't work. Is it possible to do such an update by updating specific columns through parameters? Thanks
You can build up a query in your stored procedure and execute.
CREATE PROCEDURE save_proc
(
#userid varchar(5),
#column varchar(10),
#data varchar(50)
)
AS
BEGIN
exec sp_executesql N'UPDATE MyProfile SET ' + #column + '=''' + #data + ''' WHERE userid = ''' + #userid + ''''
END
The method may lead to security concern however.
Its doable but i would avoid doing it.... you code should be like below:
DECLARE #column varchar(10)
DECLARE #data varchar(50)
UPDATE DummyTable
SET
col1 = CASE WHEN #column = 'Col1' THEN #data ELSE col1 END ,
col2 = CASE WHEN #column = 'Col2' THEN #data ELSE col2 END
where userid = #userid
.
.
.
Hope that this is what you are looking for
Using a CASE statement causes all columns identified to once again be updated; this would invoke a reindexing for some indexes upon columns wherein that change, even if the same value, occurs. Waste of execution updates on server.
An IF statement is best option for single value, especially if value is NOT the same type as the column datatype.
IF(#fieldName IS NULL) SELECT #fieldName = ''
IF(#updateValue IS NULL) SELECT #updateValue = ''
DECLARE #myCount int
SELECT #myCount = count(*) FROM [dbo].[myTable] WHERE #inventoryID = #updateInventoryID
--if no valid data to update, return -1 for noUpdate
IF(0 = #updateInventoryID
OR 0 = #myCount
OR '' = #fieldName
OR '' = #updateValue)
RETURN -1
BEGIN TRAN
IF('notes' = #fieldName)
UPDATE [dbo].[myTable]
SET [notes] = #updateValue, [modifyDate] = GETDATE()
WHERE [inventoryID] = #updateInventoryID
IF('reorderPoint' = #fieldName)
BEGIN
SET #newValueInt = CONVERT(int, #updateValue)
UPDATE [dbo].[myTable]
SET [reorderPoint] = #newValueInt, [modifyDate] = GETDATE()
WHERE [inventoryID] = #updateInventoryID
END
IF('safetyStock' = #fieldName)
BEGIN
SET #newValueInt = CONVERT(int, #updateValue)
UPDATE [dbo].[myTable]
SET [safetyStock] = #newValueInt, [modifyDate] = GETDATE()
WHERE [inventoryID] = #updateInventoryID
END
IF('quantityOnHand' = #fieldName)
BEGIN
SET #newValueInt = CONVERT(int, #updateValue)
UPDATE [dbo].[myTable]
SET [quantityOnHand] = #newValueInt, [modifyDate] = GETDATE()
WHERE [inventoryID] = #updateInventoryID
END
IF('totalLeadTimeDays' = #fieldName)
BEGIN
SET #newValueInt = CONVERT(int, #updateValue)
UPDATE [dbo].[myTable]
SET [totalLeadTimeDays] = #newValueInt, [modifyDate] = GETDATE()
WHERE [inventoryID] = #updateInventoryID
END
IF('stockTakeETADate' = #fieldName)
BEGIN
SET #newValueDatetime = CONVERT(datetime, #updateValue)
UPDATE [dbo].[myTable]
SET [stockTakeETADate] = #newValueDatetime, [modifyDate] = GETDATE()
WHERE [inventoryID] = #updateInventoryID
END
COMMIT
A Try/Catch is advisable
I would like to declare and set a variable as part of a dynamic procedure.
I am new to this so the following is just to indicate what I am trying to achieve.
Can someone show me how to write this correctly (just regarding these lines) ?
#searchMain nvarchar(100) = '',
#searchInput nvarchar(256) = ''
AS
BEGIN
SET NOCOUNT ON;
BEGIN
DECLARE #sql nvarchar(max),
#searchDate datetime
CASE WHEN #searchMain = 'col1' THEN SET #searchDate = #searchInput ELSE SET #searchDate = '' END
SET #sql = 'SELECT TOP 100
-- ...
Many thanks in advance for any help with this, Mike.
Change this:
CASE WHEN #searchMain = 'col1' THEN SET #searchDate = #searchInput ELSE SET #searchDate = '' END
To this:
SET #searchDate = CASE WHEN #searchMain = 'col1' THEN #searchInput ELSE '' END
i got a problem of my homework~
i want execute different sql in proc to use CASE WHEN
and the code like this
CREATE proc [dbo].[removeFileNew] (#transerid int,#Type int)
as
--PRINT #file
--PRINT #transerid
CASE
WHEN #Type=1 --report
THEN
UPDATE order_report_path SET ReportPath=''
WHERE tran_ser_id=#transerid
WHEN #Type=2--gl
UPDATE order_report_path SET GRpath=''
WHERE tran_ser_id=#transerid
WHEN #Type=3--ic
UPDATE order_report_path SET ICpath=''
WHERE tran_ser_id=#transerid
END
but it got some error like 'Incorrect syntax near the keyword 'CASE''
How can i use the case when like use if in c++.
thx all..
Best Wishes.
You can't use CASE WHEN like this. In SQL this is meant to return a value, not control flow.
Use IF statements instead.
IF #Type=1 --report
BEGIN
UPDATE order_report_path SET ReportPath=''
WHERE tran_ser_id=#transerid
END
ELSE IF #Type=2 --gl
BEGIN
UPDATE order_report_path SET GRpath=''
WHERE tran_ser_id=#transerid
END
ELSE IF #Type=3 --ic
BEGIN
UPDATE order_report_path SET ICpath=''
WHERE tran_ser_id=#transerid
END
Note that BEGIN / END statements are optional as long as you only have one instruction per block, but I still recommend that you keep them.
Same goes for ELSE: not THAT useful in this context but it would be if your expressions were more complex and/or if needs be that you must make sure only one block is executed.
IF #Type = 1
BEGIN
UPDATE order_report_path
SET ReportPath = ''
WHERE tran_ser_id = #transerid
END
ELSE IF #Type = 2
BEGIN
UPDATE order_report_path
SET GRpath = ''
WHERE tran_ser_id = #transerid
END
ELSE IF #Type = 3
BEGIN
UPDATE order_report_path
SET ICpath = ''
WHERE tran_ser_id = #transerid
END
You can do this in a single query by putting the case inside the update:
UPDATE order_report_path
SET ReportPath = (case when #Type = 1 then '' else ReportPath end),
GRpath = (case when #Type = 2 then '' else GRPath end),
ICpath = (case when #Type = 3 then '' else ICpath end)
WHERE tran_ser_id = #transerid
AND #Type in (1, 2, 3);