Pass a parameter to a parameterized query? - sql

I need to get a query from a database table that contains a parameter. Then use that query to update another table but I need to be able to pass another parameter to that update statement.
declare #locnum int
set #locnum = 032
declare #tempPersonID int
set #tempPersonID = 10008
declare #passwordQuery varchar(max)
set #passwordQuery = (select passwordQuery from location where locationNum = #locnum)
select #passwordQuery
update tempPerson
set [password] = #passwordQuery
where tempPersonID = #tempPersonID
select *
from tempPerson
select #passwordQuery returns (select left(firstname,1) + left(lastname,1) + custom as [password] from tempPerson where tempPersonID = #tempPersonID). I need to able to use the #tempPersomID parameter in this query and the where statement.

Firstly, as you are updating the record that you are selecting the information from you only need the following as your #passwordQuery:
left(firstname,1) + left(lastname,1) + [custom]
Then the following code takes your code and adapts it for dynamic SQL:
declare #locnum int = 032, #tempPersonID int = 10008, #passwordQuery varchar(max), #sql nvarchar(max), #params nvarchar(max);
select #passwordQuery = passwordQuery from [location] where locationNum = #locnum;
-- select #passwordQuery
set #sql = 'update tempPerson set [password] = ' + #passwordQuery
+ ' where tempPersonID = #tempPersonID';
set #params = '#tempPersonID int';
execute sp_executesql #sql, #params, #tempPersonID = #tempPersonID;
select *
from tempPerson

You Can Execute Dynamic SQL Statements with parameter using either the EXEC or sp_ExecuteSQL Statements.
In your Case, The sp_ExecuteSQLseems more suitable. The Syntax for the same is as below
sp_executesql [ #stmt = ] statement
[
{ , [ #params = ] N'#parameter_name data_type [ OUT | OUTPUT ][ ,...n ]' }
{ , [ #param1 = ] 'value1' [ ,...n ] }
]
So Your Entire Script can be re-written as below :
DECLARE #locnum INT
#tempPersonID INT,
#passwordQuery VARCHAR(MAX),
#params VARCHAR(500),
#ParamOut VARCHAR(500)
SELECT
#locnum = 032,
#tempPersonID = 10008,
#params = N'#tempPersonID INT,#MyPwd VARCHAR(500) OUTPUT'
SELECT
#passwordQuery = 'SET #MyPwd = ('+passwordQuery+')'
FROM Location
WHERE LocationNum = #locnum
sp_ExecuteSQL(#passwordQuery,#params,#tempPersonID,#MyPwd = #ParamOut OUTPUT )
UPDATE tempPerson
SET
[password] = #ParamOut
WHERE tempPersonID = #tempPersonID
select *
from tempPerson

Related

SQL Server output param truncated where it is too long

I have 4 stored procedures.
The following is used to be invoked by C#:
ALTER PROCEDURE [dbo].[sp_retrieveResourceShell]
AS
BEGIN
SET NOCOUNT ON
DECLARE #result NVARCHAR(MAX)
EXEC [dbo].[sp_retrieveResTree]
#pid = NULL,
#ret = #result OUTPUT
***select*** #result
END
These are internal stored procedures:
ALTER PROCEDURE [dbo].[sp_retrieveResTree]
(#pid UNIQUEIDENTIFIER,
#ret NVARCHAR(MAX) OUTPUT)
AS
BEGIN
DECLARE #mdlId UNIQUEIDENTIFIER,
#mdlGroup NVARCHAR(MAX)
DECLARE mdlCursor CURSOR FOR
......
DECLARE #subRet NVARCHAR(MAX),
#viewRet NVARCHAR(MAX)
EXEC [dbo].[sp_retrieveResTree]
#pid = #mdlId,
#ret = #subRet OUTPUT
EXEC dbo.sp_retrieveResView
#mdlId = #mdlId,
#ret = #viewRet OUTPUT
SET #mdlGroup = #mdlGroup + FORMATMESSAGE('{"Id":"%s","Name":"%s","Subs":%s,"Views":%s},'...)
.......
SET #ret = FORMATMESSAGE('[%s]',#mdlGroup)
END
ALTER PROCEDURE [dbo].[sp_retrieveResView]
(#mdlId UNIQUEIDENTIFIER,
#ret NVARCHAR(MAX) OUTPUT)
AS
BEGIN
SET #ret = FORMATMESSAGE('[%s]',#viewGroup)
END
When I invoke sp_retrieveResourceShell like this:
DECLARE #return_value int
EXEC #return_value = [dbo].[sp_retrieveResourceShell]
SELECT 'Return Value' = #return_value
I can get a truncated string with ellipsis at the string tail.
how to get the full string without ellipsis?
update
Changed formatmessage function to string concatenation likes
SET #mdlGroup = #mdlGroup + '{"Id":"' + CAST(#mdlId AS CHAR(36))+ '","Name":"' + #mdlName + '","Subs":' + #subRet + ',"Views":' + #viewRet +'},'
when using string concatenation , likes
SET #ret = N'[' + #mdlGroup + N']'
and refernce to [n]varchar(max) + [n]varchar(max)
i got the right full string . Thanks to #MartinSmith at the same time .

Won't able to Pass the Table name Dynamically using sp_execute_external_script using R Script

I create this query, This will work fine On SQL Server
When am using this query in inside sp_execute_external_script using R Script
I won't able to pass '+#TableName+' please check and Suggest some Solution
// This code Work fine in SQL
Declare #TableName nvarchar(max)
Declare #Plant nvarchar(max) ='XXX'
Declare #Tub nvarchar(max) ='YYY'
Set #TableNameByModelName = 'Ref_curve' -- Need This from UI
exec (N'SELECT
p.[Plant]
,P.[Tub]
,r.[Power]
FROM [dbo].[Analysis_Curve] as P
INNER join [P_Analysis].dbo.'+#TableName+' AS r on r.Speed = P.Speed
where P.Plant= '''+#Plant+'''
AND P.Tub = '''+#Tub+'''')
// This code is Using R script Need Suggestion here
Alter procedure [dbo].[Pass_Dynamic_TableName]
( #Plant1 nvarchar(50),
#Tub1 nvarchar(50)
)
As
Begin
Declare #TableName NVARCHAR(200);
Set #TableName = 'Ref_curve'
EXEC sp_execute_external_script
#language =N'R',
#script=N'df <- as.data.frame(InputDataSet);
OutputDataSet <-df'
,#input_data_1 =N'SELECT
p.[Plant]
,P.[Tub]
,r.[Power]
FROM [dbo].[Analysis_Curve] as P
INNER join [P_Analysis].dbo.#TableName AS r on r.Speed = P.Speed
where P.Plant= #Plant22
AND P.Tub = #Tub22'
,#params = N'#Plant22 varchar(50) OUTPUT, #Tub22 varchar(50) OUTPUT'
,#Plant22 = #Plant1
,#Tub22 =#Tub1
WITH RESULT SETS Undefined;
END
Could you try this.
Alter procedure [dbo].[Pass_Dynamic_TableName]
( #Plant1 nvarchar(50),
#Tub1 nvarchar(50)
)
As
Begin
Declare #TableName NVARCHAR(200);
Set #TableName = 'Ref_curve'
DECLARE #input_script NVARCHAR(MAX) =N'SELECT
p.[Plant]
,P.[Tub]
,r.[Power]
FROM [dbo].[Analysis_Curve] as P
INNER join [P_Analysis].dbo.' + QUOTENAME(#TableName) + ' AS r on r.Speed = P.Speed
where P.Plant= #Plant22
AND P.Tub = #Tub22'
EXEC sp_execute_external_script
#language =N'R',
#script=N'df <- as.data.frame(InputDataSet);
OutputDataSet <-df'
,#input_data_1 = #input_script
,#params = N'#Plant22 varchar(50), #Tub22 varchar(50) '
,#Plant22 = #Plant1
,#Tub22 =#Tub1
WITH RESULT SETS Undefined;
END

Create mulitple csv automatically from different select statements & save in a given path

I have a stored procedure to return csv output in a path after the query executes. But it only works for a single csv.
I want a script to generate multiple csv together from multiple SQL statements and store in a path.
My input is here
---------------------------------------------
--- Generating output csv by stored procedure
---------------------------------------------
DECLARE #sql NVARCHAR(MAX) = 'SELECT * from #TMP_Lazyone_All_Final'
DECLARE #file_path NVARCHAR(4000) = N'D:\a\Lazyone_ComplexProducts_Final.csv' -- Change filename path
DECLARE #Status INT = 1
EXECUTE spa_util_GetCsv #DBFetch = #sql,
#Header = 1,
#PCWrite = #file_path,
#HeaderQuote = 0,
#Status = #Status OUTPUT
You can use a while loop to achieve what you need:
DECLARE #i int = 0
DECLARE #t TABLE (
id int,
querys nvarchar(max),
filename nvarchar(max)
)
DECLARE #sql NVARCHAR(MAX),
#file_path NVARCHAR(4000) = N'D:\a\',
#Status INT = 1
INSERT INTO #t VALUES
(0, 'first query', #file_path+'first'+'.csv'),
(1, 'second query',#file_path+ 'second'+'.csv')
--etc
WHILE #i < (SELECT COUNT(*) FROM #t)
BEGIN
SELECT #sql = querys,
#file_path = filename
FROM #t
WHERE id = #i
EXECUTE spa_util_GetCsv #DBFetch = #sql,
#Header = 1,
#PCWrite = #file_path,
#HeaderQuote = 0,
#Status = #Status OUTPUT
SET #i=#i+1
END
This can be achieved using Shell Script as below.
$categories = Invoke-SqlCmd -ServerInstance SERVERINSTANCENAME -Database DATABASENAME -Query "use yourDBName;select categories from yourtable;"
foreach($category in $categories){
$categoryName = $category.name
$attachmentFilePath = "D:\$categoryName.csv"
$QueryFmt = "Select * from yourtable where categories=$categoryName"
Invoke-Sqlcmd -ServerInstance SERVERINSTANCENAME -Database DATABASENAME -Query $QueryFmt | Export-CSV $attachmentFilePath
}

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

Define a SQL variable with Database Name

With this T-SQL query I define a variable #InDate with some date.
SET
#InDate = (SELECT MIN(bt.CreateDate) AS [INDATE]
FROM
mydatabase.dbo.BuyTransaction bt
LEFT JOIN
mydatabase.dbo.TransactionExtraFields tef ON bt.TransDocument = tef.TransDocument
AND bt.TransSerial = tef.TransSerial
AND bt.TransDocNumber = tef.TransDocNumber
AND ExtraFieldID = 1
WHERE
bt.TransDocument = 'FRM' AND tef.TextAnswer = #NumPI
AND bt.TransStatus = 0)
But now I need to change the Database name by another variable. I try something like that to make a string in a variable which will be executed
SET #InDate = '(SELECT MIN(bt.CreateDate) AS [INDATE]
FROM mydatabase.dbo.BuyTransaction bt
LEFT JOIN mydatabase.dbo.TransactionExtraFields tef ON bt.TransDocument = tef.TransDocument AND bt.TransSerial = tef.TransSerial AND bt.TransDocNumber = tef.TransDocNumber AND ExtraFieldID = 1
WHERE bt.TransDocument = ''FRM'' AND tef.TextAnswer = '''+#NumPI+''' AND bt.TransStatus = 0)'
EXECUTE #InDate
But my problem is how can I get the execute result into a variable again. Something like SET #InDate2 = EXECUTE #InDate is not working...
Any idea?
Use sp_executesql. I think the syntax in your case is something like:
declare #InDate date;
declare #sql nvarchar(max);
set #sql = N'SELECT #InDate = MIN(bt.CreateDate)
FROM mydatabase.dbo.BuyTransaction bt
LEFT JOIN mydatabase.dbo.TransactionExtraFields tef ON bt.TransDocument = tef.TransDocument AND bt.TransSerial = tef.TransSerial AND bt.TransDocNumber = tef.TransDocNumber AND ExtraFieldID = 1
WHERE bt.TransDocument = ''FRM'' AND tef.TextAnswer = '''+#NumPI+''' AND bt.TransStatus = 0';
exec sp_executesql #sql, N'#InDate date output', #InDate = #InDate output;
You can also make #NumPI a parameter as well.
The documentation for sp_executesql is here.
I have done this type of issue.
Please check the sample code. Its working for me. Please change according.
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #IntVariable INT
DECLARE #Lastlname varchar(30) = 'col10 ' -- this variable use for input in sp
SET #SQLString = N'SELECT #LastlnameOUT = '+#Lastlname+'
FROM TempStoreExcelData '
SET #ParmDefinition = N'#level tinyint,
#LastlnameOUT varchar(30) OUTPUT'
SET #IntVariable = 35
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#level = #IntVariable,
#LastlnameOUT=#Lastlname OUTPUT
SELECT #output = #Lastlname
select #output