Setting variable to its own value's value dynamically - Possible? - sql

Using TSQL
Trying to set the #DynamicValue = 23 which is the parameter it is "equal" to in the below but can't figure it out.
DECLARE #DynamicValue VARCHAR(MAX) = '#PersonID';
DECLARE #PersonID INT = 23;
DECLARE #PlaceID INT = 48;
DECLARE #ThingID INT = 29;
DECLARE #nSQL NVARCHAR(MAX);
SET #nSQL = N'SELECT #Parameter2 = ' + CAST(#DynamicValue AS VARCHAR(MAX));
-- This is where the error is. If I used #PersonID here it would be fine but I want this to be dynamic
EXEC sp_executesql #nSQL,
N'#Parameter2 NVARCHAR(MAX) OUTPUT',
#Parameter2 = #DynamicValue OUTPUT;
SELECT #DynamicValue;
Any ideas? Different approaches?

You just have to pass all the parameters into the dynamic batch that performs the assignment.
Like this:
DECLARE #DynamicValue VARCHAR(MAX) = '#PersonID';
DECLARE #PersonID INT = 23;
DECLARE #PlaceID INT = 48;
DECLARE #ThingID INT = 29;
DECLARE #nSQL NVARCHAR(MAX);
SET #nSQL = N'set #Parameter2 = ' + CAST(#DynamicValue AS VARCHAR(MAX));
EXEC sp_executesql #nSQL,
N'#PersonID int, #PlaceID int, #ThingID int, #Parameter2 NVARCHAR(MAX) OUTPUT',
#PersonID = #PersonID, #PlaceID = #PlaceID, #ThingID = #ThingID, #Parameter2 = #DynamicValue OUTPUT;
SELECT #DynamicValue;

The only way I see:
DECLARE #DynamicValue VARCHAR(MAX) = '#PersonID';
DECLARE #PersonID INT = 23;
DECLARE #PlaceID INT = 48;
DECLARE #ThingID INT = 29;
SELECT #DynamicValue = CAST(CASE #DynamicValue
WHEN '#PersonID' THEN #PersonID
WHEN '#PlaceID' THEN #PlaceID
WHEN '#ThingID' THEN #ThingID END as VARCHAR(MAX))
SELECT #DynamicValue

EzLo's comment above that a variable declared outside of dynamic SQL can't be accessed made me rewrite your code in the following way, seems to work:
SET #nSQL = N'DECLARE #PersonID INT = ' + CAST(#PersonID as varchar)
+' DECLARE #PlaceID INT = ' + CAST(#PlaceID as varchar)
+' DECLARE #ThingID INT =' + CAST(#ThingID as varchar)
+' SELECT #Parameter2 = ' + CAST(#DynamicValue AS VARCHAR(MAX));

There is another way to do the same trick, but you still would have to list all your parameters:
DECLARE #DynamicValue VARCHAR(MAX) = '#PersonID';
DECLARE #PersonID INT = 23;
DECLARE #PlaceID INT = 48;
DECLARE #ThingID INT = 29;
DECLARE #DynamicValues TABLE (Parameter VARCHAR(MAX), Value INT)
INSERT INTO #DynamicValues VALUES
('#PersonID',#PersonID),
('#PlaceID',#PlaceID),
('#ThingID',#ThingID);
SELECT #DynamicValue = CAST(Value as VARCHAR(MAX))
FROM #DynamicValues WHERE Parameter = #DynamicValue
SELECT #DynamicValue

Related

How to store result of EXEC sys.sp_executesql

How can I store the result of exec into a variable?
Here's my attempt at storing the data in a variable:
DECLARE #oltp VARCHAR(50) SET #oltp = 'emp'
DECLARE #wh VARCHAR(25) SET #wh = '_wh'
DECLARE #DatabaseName SYSNAME = #oltp + #wh;
DECLARE #oltp_data_days NVARCHAR(500)
DECLARE #Params NVARCHAR(500)
DECLARE #vi int
SET #oltp_data_days = N'(SELECT datediff(DAY, MIN(business_date), GETDATE()) AS keep_days
FROM '+QUOTENAME(#DatabaseName)+'..sales
WHERE business_date > ''1/1/2000 00:00:00'')'
EXEC sp_executesql #oltp_data_days = #oltp_data_days
, #Params = N'#vi INT OUTPUT'
, #vi = #vi OUTPUT
I am getting results as Null.
Like this:
declare #sql nvarchar(max) = N'set #vi = (select 3 as keep_days)'
declare #vi int
exec sp_executesql #sql, N'#vi int output', #vi = #vi output
select #vi

Get value of SQL Var conformed on varchar text

I have the next script example:
DECLARE #lCode INT
DECLARE #lText VARCHAR(400)
DECLARE #lConditionName VARCHAR(40)
DECLARE #Aux VARCHAR(400)
SET #lCode = 1234;
SET #lConditionName = 'Code'
SET #Aux = '#l' + #lConditionName
SET #lText = 'SELECT * FROM Table WHERE Code = ' + #Aux
PRINT #lText
The result is:
SELECT * FROM Table WHERE Code = #lCode
How can i obtein the value of #Aux Var like this?
SELECT * FROM Table WHERE Code = 1234
DECLARE #lCode INT
DECLARE #lText NVARCHAR(400)
DECLARE #lConditionName NVARCHAR(40)
DECLARE #Aux NVARCHAR(400)
SET #lCode = 1234;
SET #lConditionName = N'Code'
SET #Aux = N'#l' + #lConditionName
SET #lText = N'SELECT * FROM Table WHERE Code = ' + #Aux
PRINT #lText
EXEC sp_executesql #lText, N'#lcode INT', #lcode
You can try this :
DECLARE #lCode INT
DECLARE #lText NVARCHAR(400)
DECLARE #lConditionName NVARCHAR(40)
DECLARE #Aux NVARCHAR(400)
SET #lCode = 1234;
SET #lConditionName = N'Code'
SET #Aux = N'#l' + #lConditionName
SET #lText = N'SELECT * FROM Table WHERE Code = ' + #Aux
set #lText = N'Print ' + #Aux
print #lText
EXEC sp_executesql #lText, N'#lcode INT', #lcode
Output
Print #lCode
1234

How to parse an array in sql server

I created a stored procedure that looks like this.
CREATE PROCEDURE [EXP_RfPickAfter] (
#SESSIONVALUE xml,
#WorkDSArray nvarchar(max),
#UserSignonDS nvarchar(max),
#Direction nvarchar(max),
#ImmediateCount nvarchar(max),
#CCWorkUnit nvarchar(max),
#PartialPick nvarchar(max),
#RETURNVALUE nvarchar(max) output
)
AS
SET NOCOUNT ON;
#workDSArray has this long string in it
924WORK0924841SEQUENCE8410841842EQUIPMENT_LOC842842843PARENT_LOGISTICS_
UNIT843843844REFERENCE_TYPE844Order844845INVENTORY_AT_
PD845845846FROMVER846None846847INTERNAL_NUM8476851842847848START_
DATE_TIME848848849INCHKDIG849849850TOTAL_VOLUME8500850851
TO_LOC851SHIP-1851852INTERNAL_NUM_TYPE852Shipment852853
WEIGHT_UM853LB853854COMPANY854SHOS854855QUANTITY_UM855CS855856OUTGOING_
PD_LOC856856857WORK_TYPE857LPNPick857858END_DATE_TIME858858859
ACTUALFROMWHS859L455859860LOT860860861WORK_ZONE1861861862
TOCONTAINERID8621862863INVER863863864TRACK_CONTAINERS864N864865
TO_LOC_INV_ATTRIBUTES_ID865865866CYCLE_COUNT866866867
LAUNCH_NUM86716949391867868ACTUALTOLOC868-jisavm3868869
FROM_CHECK_DIG869869870FROM_WHS870L455870871
WORK_GROUP871Picking871872INTERNAL_LINE_NUM187232612518872873
VOLUME_UM873873874ACTUALFROMLOC874NF-1-F-28-1874875
INTERNAL_REQ_NUM87520774185875876TO_WHS876L455876877
INTERNAL_LINE_NUM87732612518877878TREE_UNIT87826385537878879
INWRKZONE879879880PUTLOC880SHIP-1880881CONTAINER_ID88116489660881882
INTERNAL_CONTAINER_NUM88226385537882883FROMTRKCONT883Y883884
PARENT_CONTAINER_NUM8840884885CONVERTED_QTY_UM885CS885886
ACTUALTOWHS886L455886887OUTWRKZONE887887888
VERIFICATION_METH888None888889USER_DEF4889 L455-RS 2889890
REFERENCE_ID890XKJNNLJN890891LOGISTICS_UNIT89116489660891892
MESSAGE_ID892892893PICKLOC893NF-1-F-28-1893894
CURRENTLOC894F894895TREE_UNIT_ID89516489660895897
TOCONTAINERID089716489660897898TOTAL_WEIGHT8981898899
TOTAL_VALUE8990899900TO_CHECK_DIG900900901OUTCHECKDIG901901902
TO_QTY9020902903INTRKCONT903903904FROM_LOC_INV_ATTRIBUTES_ID904904905
INTERNAL_INSTRUCTION_NUM90520699485905906ITEM_DESC906MSF21D4MDE -
Refrigerator906907ITEM907SHOS-STOCK907908
COMPLETEDBYUSER908jisavm3908909
TRANSPORT_CONT_ID90916489660909910OUTTRKCONT910910911ACCOUNT911
Store #9449911912INCOMING_PD_LOC912912913INVENTORY_TRACKING913Y913914
LOCATION_CLASS914Shipping Dock914915FROM_QTY9151915916OUTVERMETH916916917
CONVERTED_QTY9171917918QUANTITY9181918919
PARENT_INSTR91920699484919920
FROM_LOC920NF-1-F-28-1920921WORK_ZONE921W-
Returns921922WORK_UNIT92216489660922923QTY
CONFIRMED9231923924925WORK9251925
I am trying to parse containerID and its value from this string and use it in a select statement in my stored procedure, but I am unsure how to parse only the containerID.
Any help would be appreciated
This is what I did to get the right ID I had to trigger off of something else. This is not ideal because I don't know if the string will change. If anybody knows a better way please post and thank you #ymuribbi you helped me out a ton. I edited this to show my full solution just in case someone else runs into this issue.
DECLARE #WorkDSArray nvarchar(max);
SET #WorkDSArray= '924WORK0924841SEQUENCE8410841842EQUIPMENT_LOC842842843PARENT_LOGISTICS_UNIT843843844REFERENCE_TYPE844Order844845INVENTORY_AT_PD845845846FROMVER846None846847INTERNAL_NUM8476851842847848START_DATE_TIME848848849INCHKDIG849849850TOTAL_VOLUME8500850851TO_LOC851SHIP-1851852INTERNAL_NUM_TYPE852Shipment852853WEIGHT_UM853LB853854COMPANY854SHOS854855QUANTITY_UM855CS855856OUTGOING_PD_LOC856856857WORK_TYPE857LPN Pick857858END_DATE_TIME858858859ACTUALFROMWHS859L455859860LOT860860861WORK_ZONE1861861862TOCONTAINERID8621862863INVER863863864TRACK_CONTAINERS864N864865TO_LOC_INV_ATTRIBUTES_ID865865866CYCLE_COUNT866866867LAUNCH_NUM86716949391867868ACTUALTOLOC868-jisavm3868869FROM_CHECK_DIG869869870FROM_WHS870L455870871WORK_GROUP871Picking871872INTERNAL_LINE_NUM187232612518872873VOLUME_UM873873874ACTUALFROMLOC874NF-1-F-28-1874875INTERNAL_REQ_NUM87520774185875876TO_WHS876L455876877INTERNAL_LINE_NUM87732612518877878TREE_UNIT87826385537878879INWRKZONE879879880PUTLOC880SHIP-1880881CONTAINER_ID88116489660881882INTERNAL_CONTAINER_NUM88226385537882883FROMTRKCONT883Y883884PARENT_CONTAINER_NUM8840884885CONVERTED_QTY_UM885CS885886ACTUALTOWHS886L455886887OUTWRKZONE887887888VERIFICATION_METH888None888889USER_DEF4889 L455-RS 2889890REFERENCE_ID890XKJNNLJN890891LOGISTICS_UNIT89116489660891892MESSAGE_ID892892893PICKLOC893NF-1-F-28-1893894CURRENTLOC894F894895TREE_UNIT_ID89516489660895897TOCONTAINERID089716489660897898TOTAL_WEIGHT8981898899TOTAL_VALUE8990899900TO_CHECK_DIG900900901OUTCHECKDIG901901902TO_QTY9020902903INTRKCONT903903904FROM_LOC_INV_ATTRIBUTES_ID904904905INTERNAL_INSTRUCTION_NUM90520699485905906ITEM_DESC906MSF21D4MDE - Refrigerator906907ITEM907SHOS-STOCK907908COMPLETEDBYUSER908jisavm3908909TRANSPORT_CONT_ID90916489660909910OUTTRKCONT910910911ACCOUNT911Store #9449911912INCOMING_PD_LOC912912913INVENTORY_TRACKING913Y913914LOCATION_CLASS914Shipping Dock914915FROM_QTY9151915916OUTVERMETH916916917CONVERTED_QTY9171917918QUANTITY9181918919PARENT_INSTR91920699484919920FROM_LOC920NF-1-F-28-1920921WORK_ZONE921W-Returns921922WORK_UNIT92216489660922923QTYCONFIRMED9231923924925WORK9251925'
DECLARE #ContainerID integer;
SET #ContainerID = CHARINDEX('TREE_UNIT_ID', #WorkDSArray);
DECLARE #ID nvarchar(max);
SET #ID = SUBSTRING(#WorkDSArray, #ContainerID,300)
SELECT #ID;
DECLARE #ActualContainerID nvarchar(max);
SET #ActualContainerID = SUBSTRING(#ID, 54, 9)
SET #ActualContainerID = REPLACE(#ActualContainerID, CHAR(31), '')
DECLARE #User integer
DECLARE #UserID nvarchar(max)
SET #User = CHARINDEX('COMPLETEDBYUSER', #WorkDSArray);
SET #UserID = SUBSTRING(#WorkDSArray, #User,27)
DECLARE #ActualUserID nvarchar(max);
SET #ActualUserID = SUBSTRING(#UserID, 20, 8)
SET #ActualUserID = REPLACE(#ActualUserID, CHAR(31), '')
DECLARE #Shipment nvarchar(max)
SET #Shipment = (SELECT CASE WHEN SH.COMPANY = 'SHOS' THEN '' ELSE SH.SHIPMENT_ID + '|' +
SH."ROUTE" + '|' +
SH."STOP" + '|' +
SH.COMPANY + '|' +
LEFT(SH.CUSTOMER_NAME,25) + '|' +
LEFT(SH.SHIP_TO_ADDRESS1,25) + '|' +
CASE WHEN SH.SHIP_TO_ADDRESS2 <> '' THEN SH.SHIP_TO_ADDRESS2 + '|'
ELSE '' END +
LEFT(SH.SHIP_TO_CITY,25) + '|' +
LEFT(SH.SHIP_TO_STATE,25) + '|' +
LEFT(SH.SHIP_TO_POSTAL_CODE,25) END
FROM SHIPMENT_HEADER SH
JOIN SHIPPING_CONTAINER SC
ON SC.INTERNAL_SHIPMENT_NUM = SH.INTERNAL_SHIPMENT_NUM
WHERE SC.CONTAINER_ID = #ActualContainerID)
DECLARE #ShipmentID nvarchar(max)
SET #ShipmentID = SUBSTRING(#Shipment,0,9)
--select top 1 device_name from dbo.DOCUMENT_ROUTING where document_type = 'HJBT_REC' and user_name = #user
INSERT INTO [jbh].[PRT_REQ_WRK]
([REQ_REF_TYP], [REQ_REF_I], [PRT_DVC_NM], [REQ_TMPL_NM], [REQ_VAL], [PRT_STT], [PRT_PRS_TYP], [PRT_Q], [CRT_S], [CRT_UID], [CRT_PGM_C], [LST_UPD_S], [LST_UPD_UID], [LST_UPD_PGM_C])
VALUES (
#ShipmentID, --[REQ_REF_TYP]
'123abc', --[REQ_REF_I]
'LB01885', --[PRT_DVC_NM]
'HJBT_Shipping_Label.lbl', --[REQ_TMPL_NM]
#Shipment, --[REQ_VAL]
0, --[PRT_STT]
'LABEL', --[PRT_PRS_TYP]
1, --[PRT_Q]
CURRENT_TIMESTAMP, --[CRT_S]
#ActualUserID, --[CRT_UID]
'WMSPrintService', --[CRT_PGM_C]
CURRENT_TIMESTAMP, --[LST_UPD_S]
'JISAVM3', --[LST_UPD_UID]
'WMSPrintService') --[LST_UPD_PGM_C]
As #hogan stated in his comment, you can use string operators for extraction with some while and if-else statements
-- I am editing my answer.
To retrieve the container ID you use a store procedure like this:
create proc getid (#string varchar(max)) as
declare #containerIdIndex int = (select charindex('CONTAINER_ID',#string))
declare #internalContainerIndex int = (select(Charindex('INTERNAL_CONTAINER', #string)))
declare #range int = #internalContainerindex-#containerIdindex+12
declare #start int = #containerIdIndex+12 --12 is to pass the 'Container_ID'
declare #containerId varchar(max)
set #containerId = substring(#string,#start,#range)
print #containerId

Store the result of a Dynamic Query in a variable

I know this question has been asked, and I already found some solutions in internet.. but I still can not make it work properly.
So.. I have to make a SELECT query and store the result in a variable (I DONT want a table variable).
My problem is that the name of the table is also a variable. The table name changes accordingly to a WHILE, here is my code:
DECLARE #numRecord INT;
DECLARE #maxMacNumber INT;
SET #maxMacNumber = 500;
DECLARE #mac INT;
SET #mac = 0;
DECLARE #res FLOAT;
DECLARE #ap INT;
SET #ap = 0;
DECLARE #apString VARCHAR(2);
DECLARE #numRecordString VARCHAR(20);
DECLARE #tablename VARCHAR(500);
DECLARE #sql NVARCHAR(500);
DECLARE #varDefinition NVARCHAR(200);
WHILE #mac <= #maxMacNumber
BEGIN
SET #numRecord = 6 + #mac * 390;
SET #ap = 0;
WHILE #ap < 2
BEGIN
SELECT #apString = CONVERT(VARCHAR,#ap);
SELECT #numRecordString = CONVERT(VARCHAR, #numRecord);
SELECT #rssiString = CONVERT(VARCHAR, #rssi);
SET #tablename = 'APDB.dbo.AP' + #apString;
SET #sql = 'SELECT RSSI FROM ' + #tablename + ' WHERE ID=' + #numRecordString;
SET #varDefinition = N'#res FLOAT OUTPUT';
EXEC sp_executesql #sql, #varDefinition, #res = #res OUTPUT;
PRINT #res;
-- HERE I WILL DO SOMETHING WITH #res
END;
END;
The problem is that it doesn't print anything when I do PRINT #res...
This is the relevant SQL code:
SET #sql = 'SELECT RSSI FROM ' + #tablename + ' WHERE ID=' + #numRecordString;
SET #varDefinition = N'#res FLOAT OUTPUT';
EXEC sp_executesql #sql, #varDefinition, #res = #res OUTPUT;
PRINT #res;
You are never setting #res in the SQL. Try this:
SET #sql = 'SELECT #res = RSSI FROM ' + #tablename + ' WHERE ID=' + #numRecordString;
SET #varDefinition = N'#res FLOAT OUTPUT';
EXEC sp_executesql #sql, #varDefinition, #res = #res OUTPUT;
PRINT #res;

Looking for multiples substrings within a SQL string

I have several occurrences of differences strings in the columns, like this example
'dsasdasdsd'+'ewewewew'+'45454545'+(avg('uuuuuuu'))
I need to split this string into several columns with the substrings that are between
aphostropes
like this:
Column 1 = dsasdasdsd
Column 2 = ewewewew
Column 3 = 45454545
Column 4 = uuuuuuu
The numbers of apperances are random, thefore the length of the original column is also not fixed (from 50 char to > 1000)
DECLARE #InStr VarChar(1000) = '''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))'''
DECLARE #intStart INT = 0
DECLARE #intEnd INT = 1
DECLARE #ColNo INT = 1
DECLARE #MyString VARCHAR(2000)
DECLARE #SelectString VARCHAR(8000) = 'SELECT '
WHILE(#intStart < LEN(#InStr) )
BEGIN
SELECT #intStart = CHARINDEX(CHAR(39), #InStr, 0) + 1
SELECT #intEnd = CHARINDEX(CHAR(39), #InStr, #intStart)
SELECT #SelectString = #SelectString + CHAR(39) + SUBSTRING(#InStr, #intStart, #intEnd - #intStart) + CHAR(39) + ' As [Column ' + CAST(#ColNo As Varchar) + '],'
SELECT #InStr = SUBSTRING(#InStr, #intEnd + 1, LEN(#InStr)-#intEnd )
SET #ColNo = #ColNo +1
END
SELECT #SelectString = LEFT(#SelectString, Len(#SelectString) -1)
EXEC (#SelectString)
I have been playing with this and this does run but unfortunately I don't have time right now to carry on with it but maybe you can improve on this?
HTH
You can try this:
create table tSqlStrings (sText nvarchar(1000))
insert tSqlStrings values('''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))')
create table tResults (
sColumn1 nvarchar(1000)
,sColumn2 nvarchar(1000)
,sColumn3 nvarchar(1000)
,sColumn4 nvarchar(1000)
)
and
DELETE tResults
DECLARE #sText nvarchar(1000) = (
SELECT
sText
FROM
tSqlStrings
)
DECLARE #lBegin int = CHARINDEX('''',#sText)
DECLARE #lEnd int = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
DECLARE #sText0 nvarchar(1000)
DECLARE #sColumn1 nvarchar(1000)
DECLARE #sColumn2 nvarchar(1000)
DECLARE #sColumn3 nvarchar(1000)
DECLARE #sColumn4 nvarchar(1000)
DECLARE #iCnt int = 1
while #iCnt<=4
--(0<len(#sText) and 0<#lBegin and 0<#lEnd)
BEGIN
SET #sText0 = substring(#sText,#lBegin+1,#lEnd-2)
IF #iCnt=1 begin SET #sColumn1=#sText0 end
IF #iCnt=2 begin SET #sColumn2=#sText0 end
IF #iCnt=3 begin SET #sColumn3=#sText0 end
IF #iCnt=4 begin SET #sColumn4=#sText0 end
set #sText = substring(#sText,#lBegin + #lEnd+2,len(#sText))
SET #lBegin = CHARINDEX('''',#sText)
SET #lEnd = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
SET #iCnt = #iCnt+1
END
INSERT
tResults (sColumn1,sColumn2,sColumn3,sColumn4)
VALUES (#sColumn1,#sColumn2,#sColumn3,#sColumn4)
SELECT * FROM tResults
on sql fiddle
You will be able to achieve this using CHARINDEX() and SUBSTRING()
Following example shows for splitting to 2 columns. When it has more columns, query will be get little more complicated. However, you can follow this to build your query.
SELECT OriginalColumn
, SUBSTRING(OriginalColumn, 1,CHARINDEX('x',OriginalColumn,1)-1) AS Column1
, SUBSTRING(OriginalColumn, CHARINDEX('x',OriginalColumn,1) + 1 ,CHARINDEX('x',OriginalColumn,CHARINDEX('x',OriginalColumn,1)-1)) AS Column2
FROM YourTable
I have used "x" as the delimiter in the example. Following is a sample result
try this:
declare #delim char
set #delim = ''''
declare #str nvarchar(max)
declare #substr nvarchar(max)
declare #newstr nvarchar(max)
declare #tmpTable table (partStrings nvarchar(max))
declare #count int
set #count = 0
select #str = <***Your String***>
while(charindex(#delim,#str) != 0)
begin
set #count = #count + 1
Select #substr = substring(#str,1,charindex(#delim,#str)-1)
if((#count % 2) = 0)
begin
insert into #tmpTable values(#substr)
end
Set #newstr = substring(#str,charindex(#delim,#str)+1,len(#str)-charindex(#delim,#str))
set #str = #newstr
end
select partStrings from #tmpTable