Stored Procedure Dynamic SQL stored result in variable - sql-server-2008

I have A stored procedure written
DECLARE #AreaID AS INT
DECLARE #DayPrior AS INT
DECLARE #TableName AS VARCHAR(50)
DECLARE #StoreQuery AS NVARCHAR(MAX)
DECLARE #SQL_ExtractDlSql AS NVARCHAR(MAX)
DECLARE #ParameterDefinition AS NVARCHAR(2000)
SET #AreaID = 1
SET #DayPrior = 1
SET #TableName = 'Tbl_Lube'
SET #SQL_ExtractDlSql = 'SELECT Download_SQL From
HDDDataPackage.dbo.tbl_HDD_DataDownloadSetting
Where AreaId=#AreaID AND TableName=#TableName'
SET #ParameterDefinition = '#AreaID INT,#DayPrior INT,#TableName VARCHAR(50)'
EXECUTE sp_executesql #SQL_ExtractDlSql,
#ParameterDefinition,
#AreaID,
#DayPrior,
#TableName
PRINT #SQL_ExtractDlSql
I above Stored procedure, I get What I wanted on print, but instead of doing that, I wanted the selected data stores as a variable.
Then what I done is I declared a variable #StoreSql and made some modified into the SQL statement show below:
Variable Declaration:
DECLARE #StoreSql AS NVARCHAR(MAX)
Modified the Code:
SET #SQL_ExtractDlSql = 'SELECT #StoreSql = Download_SQL From
HDDDataPackage.dbo.tbl_HDD_DataDownloadSetting
Where AreaId=#AreaID AND TableName=#TableName'
I executed the code, I get error Must declare the scalar variable "#StoreSql".
I have totally no idea how to deal with this.Any one can help.Beside,I am new to sqlserver,new to stored procedures.
Please don't hesitate to point out my any mistake,any..such as logic or etc. I learn from mistake.
Regards
LiangCk

The dynamic SQL string cannot reference variables from the outer scope. You need to declare it as an output parameter
SET #ParameterDefinition = '#AreaID INT,
#DayPrior INT,
#TableName VARCHAR(50),
#StoreSql NVARCHAR(MAX) OUTPUT'
EXECUTE sp_executesql #SQL_ExtractDlSql,
#ParameterDefinition,
#AreaID,
#DayPrior,
#TableName,
#StoreSql OUTPUT

Related

Store json query output in variable / use variable in ole automation api post?

I have a ole automation query that sends json data to an rest api. This works great when you hardcode the json data in the query.
I am trying to use the output from a for json query instead.
So my basic goal is to store the json from the query output in a usable variable
I have tried this
but null always gets assigned to the variable
```
declare #JsonOutput xml
EXEC SP_EXECUTESQL #SqlText, N'#JsonOutput xml OUTPUT', #JsonOutput = #JsonOutput OUTPUT
```
the above output does return the json but the #JsonOutput variable never gets set with the JSON data and is unusable..
..................
Update:
I found a work around but was still wondering if there was a better way. I'm loading the json into a temp table then selecting it and stores it in a usable variable and it posts successfully. It does however seem to restrict the amount of json I can put in the temp table field.
'''
set nocount on;
drop table #b
;WITH x(a) as
(
select JSON_QUERY(rtrim(JSON_MODIFY('[]', 'append $', authorIds))) AS authorIds,[bases], [isCircular], [name], 'ts_SOThWL5L' [schemaId], [registryId], [namingStrategy]
FROM [dbo].[vw_bulkDNAPostCreate]
where myid between 600 and 630
FOR JSON PATH, ROOT('dnaSequences')
)
SELECT a INTO #b FROM x
select a from #b
DECLARE #IntVariable INT;
DECLARE #SQLString NVARCHAR(500);
DECLARE #ParmDefinition NVARCHAR(500);
DECLARE #JSON varchar(max);
set #SQLString = N'select #JSONOUT = a from #b'
SET #ParmDefinition = N'#JSONOUT varchar(max) OUTPUT';
EXECUTE sp_executesql #SQLString, #ParmDefinition,#JSONOUT=#JSON OUTPUT;
--SELECT #JSON;
declare #url nvarchar(222) = N'https://TestApiEndpoint..net'
declare #authHeader nvarchar(222) = N'Basic tokenadskjfldasjfs'
Declare #Body as varchar(max) = #JSON
EXEC [dbo].[MyAPIPostProc]
#authHeader = #authHeader,
#Body = #JSON,
#url = #url
'''

How to use numeric int in exec sp_executesql

Is there any way i can use numeric integer in sp_executesql ?
declare #total_test int
declare #test int
set #sql=N'select #test=count (*) from '+#db+'..'+#table
exec sp_executesql #sql
set #total_test +=#test
The problem is that he will not accept any numeric integet,
i cant even set #sql=N'select count (*)...'
Any ideas? Thanks for your help.
You will need to use the OUTPUT clause with your variable. Also on a side note you must use QUOTENAME() function when concatenating object names to your dynamic sql string, protects you against possible sql injection attack.
declare #total_test int;
declare #test int;
SET #total_test = 0;
set #sql=N'select #test=count (*) from '+ QUOTENAME(#db)+'..'+ QUOTENAME(#table)
EXECUTE sp_executesql #sql
,N'#test int OUTPUT'
,#test OUTPUT
set #total_test +=#test

What's wrong with the stored procedure

I have a table called Std_Components which acts like an index for list of components with associated tables. The column AssociatedTable holds the name of table that actually contains the component data.
Please check images below -
Here is table data for Std_SteeringPumps
I am trying to create a stored procedure that will copy Std_Components table as well as all associated tables with new name. For ex. Lets say if i provided 001 as a parameter to this stored procedure i should be able create new tables like C001_Components, C001_SteeringPumps and so on.
This is what I have done so far:
ALTER PROCEDURE [dbo].[sgi_sp_CreateTablesForNewCompany]
-- Add the parameters for the stored procedure here
#CompanyId varchar(5)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- declare variables
declare #qry as varchar(2000)
declare #compTblName as varchar(100)
set #compTblName = 'C'+#companyId +'_Components'
-- Check if table already exists
IF object_id(#compTblName) is not null
return
-- Create main component index table by copying standard component table --
set #qry = 'Select * into '+#compTblName+' From Std_Components;';
--print #qry
--execute (#qry)
set #qry =#qry + 'Update C'+#companyId +'_Components Set AssociatedTable=''C'+#companyId +'''+substring(AssociatedTable,4,200);';
--print #qry
--exec #qry
-- Create all child tables --
Select * Into #TempTbl From dbo.Std_Components
Declare #Id int
While (Select Count(*) From #TempTbl) > 0
Begin
declare #rowTableName as varchar(50)
declare #compNewTbl as varchar(50)
Select Top 1 #rowTableName=AssociatedTable, #Id = Id From #TempTbl
set #compNewTbl = 'C'+#companyId + substring(#rowTableName,4,200);
set #qry = #qry + 'Select * into '+#compNewTbl+' From ' + #rowTableName + ';'
--print #qry
--exec #qry
Delete #TempTbl Where Id = #Id
End
print #qry
exec #qry
END
Here is the output of the print statement for the query it generates -
Select * into C001_Components From Std_Components;
Update C001_Components Set AssociatedTable='C001'+substring(AssociatedTable,4,200);
Select * into C001_SteeringPumps From Std_SteeringPumps;
But when the stored procedure is executed, I get the following error -
Msg 203, Level 16, State 2, Procedure sgi_sp_CreateTablesForNewCompany, Line 56
The name 'Select * into C001_Components From Std_Components;Update C001_Components Set AssociatedTable='C001'+substring(AssociatedTable,4,200);Select * into C001_SteeringPumps From Std_SteeringPumps;' is not a valid identifier.
Can anybody help me out resolve this issue.
Thanks for sharing your time and wisdom.
The error you're getting is because the EXEC statement (the last line of the stored procedure) needs to have brackets around the #qry variable so that it becomes
exec(#qry)
Without the brackets it's treating the entire SQL string as stored procedure name.
The non valid indentifier is around the AssociatedTable part
Set AssociatedTable='C001'+substring(AssociatedTable,4,200); will not run as there is no scope for AssociatedTable to substring - the string needs to contain the name of the table completely to be able to be executed
Instead of
exec #qry;
You need
exec sp_executesql #qry;
You'll also need to change the type of #qry to NVARCHAR. Note that because of the dynamic sql, the proc is prone to SQL Injection and other escaping issues (i.e. ensure that #CompanyId is validated)

Want to get selected value

declare #qry as varchar(max)
declare #db as varchar(25)
declare #item as varchar(25)
declare #U_Parentcode as varchar(25)
set #U_Parentcode ='CDM51306520'
set #db ='Marda_Test'
set #qry ='select #item =itemcode from ' + #db + '.[dbo].[OITM] where ItemCode=''' + #U_Parentcode +''''
execute (#qry)
print #item
am getting error like 'Must declare the scalar variable "#item".'
The dynamic sql executes in a different context from the context of your code, so basically there isn't an #item variable declared over there.
You need to use sp_executeSql which contains a mechanism to map your variables to variables within the block. The syntax is a but obtuse, but it's obvious when you get used to it.
declare #qry as nvarchar(max)
declare #db as varchar(25)
declare #outsideItem as varchar(25)
declare #U_Parentcode as varchar(25)
set #U_Parentcode ='CDM51306520'
set #db ='Marda_Test'
set #qry ='select #insideItem =itemcode from ' + #db + '.[dbo].[OITM] where ItemCode=''' + #U_Parentcode +''''
execute sp_executesql #qry, N'#insideItem varchar(25) output', #insideItem = #outsideItem output
print #item
The first parameter is the query, same as with exec().
The second parameter is a declaration of all parameters used in the query, in your case #insideItem.
The third (and any subsequent) parameter is a mapping that says which inside parameter should be mapped to which outside parameter.
The output clause (used both on the variable declaration and on the mapping) is a designator that that parameter is used as an output value of the query.
Your declare statements are not included in #qry content.
In addition, why are you even bothering with execute ?
Why not just use a normal query. Parameterize your connection string so that you connect to the correct database and just run a normal query.

Initializing table name to be used in a stored procedure in SQL Server

I am trying to create a stored procedure to achieve the following in the stored procedure
DECLARE #TBLNAME VARCHAR(128)
SET #TBLNAME = SELECT PAR_VALUE FROM DBO.PARAMETERS WHERE PAR_NAME='SALES_ORDERS_TABLE';
The PAR_VALUE column in the PARAMETERS table contains the name of the table of the Sales Order table.
I now want to use this table name in the stored procedure, and count the number of rows in this table.
DECLARE #SQL NVARCHAR(4000)
# SQL = SELECT COUNT(*) FROM '[#TBLNAME]'
However, when I try to run this, there are multiple errors.
Can you please help me by guiding on how to do this?
I just now tried this code:
CREATE PROCEDURE JCOUNT_SO
AS
DECLARE #TBLNAME NVARCHAR(512)
SELECT #TBLNAME=(SELECT PAR_VALUE FROM DBO.PARAMETERS WHERE PAR_NAME='SALES_ORDERS_TABLE')
DECLARE #SQL NVARCHAR(4000)
SELECT #SQL='SELECT COUNT(*) AS #_OF_RECORDS INTO SO_COUNT
FROM' '+QUOTENAME(#TBLNAME)''
EXEC SP_EXECUTESQL #SQL;
Error Message: Invalid Object Name: 'TEST.DBO.SO_MASTER'
Please help on this code.
Please read defination of sp_executesql for reference. Procedure below returns value as an output parameter from dynamic query rather than inserting into a table. You can manipulate query as per your requirement.
CREATE PROCEDURE JCOUNT_SO
AS
DECLARE #TBLNAME nvarchar(512)
--Obtain table name. Top 1 is used to pick first record rather than last record in case query returns more than one record.
SELECT TOP 1 #TBLNAME = PAR_VALUE FROM DBO.PARAMETERS WHERE PAR_NAME='SALES_ORDERS_TABLE'
DECLARE #SQL NVARCHAR(4000)
DECLARE #Count int
SET #SQL ='SELECT #Count = COUNT(*) FROM ' + #TBLNAME
--Define parameters to be passed i.e. #Count is being passed as output parameter
EXEC SP_EXECUTESQL #SQL, N'#Count int OUTPUT', #Count output
select #Count
end
Notes from MSDN
Query i.e. #SQL can contain parameters having the same form as a variable name and each parameter included in #SQLmust have a corresponding entry in both the #params parameter definition list and the parameter values list
1 point I can say is ... it should be SET #SQL = SELECT ...
and one more thing is you can try converting the result to NVARCHAR.
use SELECT Convert(NVARCHAR(4000),Count(*)) FROM ...