SQL Server: how to declare and set variable in dynamic procedure - sql

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

Related

if else change declared variable in database SQL

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

Spiting filter values into conditions sql

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

Stored procedure update specific column by parameter

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

Invalid length parameter passed to the LEFT or SUBSTRING function

Following is my query and it works fine when I have like TRAILER_MAKE_MODEL 'testing ~ testing, test ~ testq,' ends with comma but can't handle 'testing ~ testing, test ~ testq' same as for other variable TRAILER_IDV. I tried my best but cant work it out any help would be appreciated.
My aim is to get the comma separated value for xml.
DECLARE #TRAILER_MAKE_MODEL VARCHAR(MAX)
DECLARE #TRAILER_IDV VARCHAR(MAX)
DECLARE #USER_TYPE VARCHAR(MAX)
DECLARE #START_INDEX_1 INT
DECLARE #START_INDEX_4 INT
DECLARE #END_INDEX_1 INT
DECLARE #END_INDEX_4 INT
DECLARE #VALUE VARCHAR(50)
DECLARE #QUERY VARCHAR(MAX)
set #TRAILER_MAKE_MODEL='testing ~ testing, test ~ testq,'
set #TRAILER_IDV='3500, 3400,'
set #USER_TYPE='MOBILE'
set #QUERY = ''
set #START_INDEX_1 = 1
set #START_INDEX_4 = 1
set #END_INDEX_1 = 0
if ISNULL(#TRAILER_MAKE_MODEL,'') <> ''
begin
WHILE #START_INDEX_1 > 0 and #START_INDEX_1 < len(#TRAILER_MAKE_MODEL)
BEGIN
SET #END_INDEX_1 = CHARINDEX(',',#TRAILER_MAKE_MODEL,#START_INDEX_1)
if #END_INDEX_1 = 0 and #START_INDEX_1 = 1
Begin
SET #END_INDEX_1 = len(#TRAILER_MAKE_MODEL)
END
if #USER_TYPE <> 'MOBILE'
Begin
SET #END_INDEX_1 = #END_INDEX_1 +1
End
SET #VALUE = SUBSTRING(#TRAILER_MAKE_MODEL,#START_INDEX_1,#END_INDEX_1 - #START_INDEX_1)
SET #QUERY = #QUERY + 'UNION ALL SELECT ''' + #VALUE + ''' TRAILER_MAKE_MODEL'
SET #END_INDEX_4 = CHARINDEX(',',#TRAILER_IDV,#START_INDEX_4)
if #END_INDEX_4 = 0 and #START_INDEX_4 = 1
Begin
SET #END_INDEX_4 = len(#TRAILER_IDV)
END
if #USER_TYPE <> 'MOBILE'
Begin
SET #END_INDEX_4 = #END_INDEX_4 +1
End
SET #VALUE = SUBSTRING(#TRAILER_IDV,#START_INDEX_4,#END_INDEX_4 - #START_INDEX_4)
SET #QUERY = #QUERY + ',' + #VALUE + 'TRAILER_IDV '
print #QUERY
SET #START_INDEX_1 = #END_INDEX_1 + 1
SET #START_INDEX_4 = #END_INDEX_4 + 1
END
select #QUERY=substring(#QUERY, 10, LEN(#QUERY) - 9)
EXEC (#QUERY)
END
You already have a lot of code here so two extra lines where you assign a comma at the end of each string should probably not slow things down for you or make the code less maintainable.
SET #TRAILER_MAKE_MODEL += ',';
SET #TRAILER_IDV += ',';
I don't really understand what your code does but to get the result you are getting you can use a split string function that returns the index of the item like this.
select T1.Item as TRAILER_MAKE_MODEL,
T2.Item as TRAILER_IDV
from dbo.SplitString(#TRAILER_MAKE_MODEL, ',') as T1
inner join dbo.SplitString(#TRAILER_IDV, ',') as T2
on T1.ItemNumber = T2.ItemNumber

SQL CASE Expression - Setting values of local variables

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.