How to use parameters in SQL Server? - sql

Beginner here! I just started working with SQL Server in Azure functions (in Typescript). I am trying to update a row in the database using declared variables but I am failing to do so with VARCHAR types. Interesting is that in the database tool it is working fine but once I try to run the query inside the Azure function, I get an http me 500 error
RequestError: Incorrect syntax near 'kg'
(working with weight as a string).
At the moment, my code looks like this:
const trainingId: number = parseInt(req.params.training_id);
const exerciseId: number = parseInt(req.params.exercise_id);
const weight: string = req.body.weight;
await mssql.query(
`DECLARE #sql NVARCHAR(4000);
DECLARE #training_id INT;
DECLARE #exercise_id INT;
DECLARE #weight VARCHAR(255);
set #sql = N'
UPDATE Exercises SET weight = #weight WHERE training_id = #training_id AND exercise_id = #exercise_id'
SET #training_id = ${trainingId};
SET #exercise_id = ${exerciseId};
SET #weight = ${weight};
exec sp_executesql #sql, N'#training_id INT, #exercise_id INT, #weight VARCHAR(255)',
#training_id, #exercise_id, #weight`
I have also tried the syntax where I insert the weight variable into the query like this:
SET weight ' + #weight + '
and did not work either.
I have also tried to use this approach here: How to pass parameter to mssql query in node js
But it did not work for me either. So how can I actually pass the parameters correctly? I am trying to avoid SQL injection.
Thank you so much for any advice!

With SET #weight = ${weight}; you are injecting values into a query that you use to execute another query. Why not use that UPDATE query directly after you use mssql.input(...) to set the parameter values (as per your link)?
As I understand it, it should be something like:
const trainingId: number = parseInt(req.params.training_id);
const exerciseId: number = parseInt(req.params.exercise_id);
const weight: string = req.body.weight;
// set up parameters
mssql.input('training_id', Sql.Int, trainingId);
mssql.input('exercise_id', Sql.Int, exerciseId);
mssql.input('weight ', Sql.VarChar, weight);
// execute just the UPDATE query, using the parameters
await mssql.query('UPDATE Exercises SET weight = #weight WHERE training_id = #training_id AND exercise_id = #exercise_id');

Perfect! I was doing it wrong the whole time as I was not linking the new Request to the mssql. What works for me now is:
const request: mssql.Request = new mssql.Request();
request.input('training_id', mssql.Int, trainingId);
request.input('exercise_id', mssql.Int, exerciseId);
request.input('weight ', mssql.VarChar, weight);
const result = await request.query('UPDATE Exercises SET weight = #weight WHERE training_id = #training_id AND exercise_id = #exercise_id');
Thanks a lot for the help!

Related

Export 'sp_execute_external_script' value to SQL variable for use

I am trying to write a stored procedure that is using the SQL sp_execute_external_script procedure. I am able to have the script run in my SSMS window. I want to save the value to an OUTPUT variable that I can use later in the stored procedure.
Here is what I have working:
EXECUTE sp_execute_external_script #language=N'R'
,#script = N'OutputDataSet <- as.data.frame(qgamma(p=(.05/2),shape=315,scale=1)); '
I am using SQL Server 2019.
I tried this, but the variable does not populate:
DECLARE #UpDiv float
EXECUTE sp_execute_external_script #language=N'R'
,#script = N'OutputDataSet <- as.data.frame(qgamma(p=(.05/2),shape=315,scale=1)); '
,#params = N'#UpDiv float OUTPUT'
,#UpDiv = #UpDiv OUTPUT
SELECT #UpDiv
Edit: From suggestions, I made a small change to send to UpDiv, but now my issue is with how do I get the "data.frame" result to an SQL variable? What variable do I use? I am having to learn R on the fly here. Can I maybe convert in the R result before passing back to SQL?
...
DECLARE #UpDiv float;
EXECUTE sp_execute_external_script #language=N'R'
,#script = N'UpDiv <- sum(1.01, 2.02, 3.03, 4.04, 5.05) '
,#params = N'#UpDiv float OUTPUT'
,#UpDiv = #UpDiv OUTPUT;
SELECT #UpDiv;

How to retrieve multiple rows from a SQL Server stored procedure using Pyodbc in Jupyter Notebook

I have a stored procedure in SQL Server which takes 3 input parameters and can produce multiple rows as output. In fact, it is returning 20 rows in my current case. For instance, if I manually execute the stored procedure from SSMS, I get the following code and partial output, respectively:
Code:
DECLARE #return_value int
EXEC #return_value = [Coverage-Source].[ReadCoverageMapping]
#client = N'Capital BlueCross',
#lineOfBusiness = N'Commercial',
#distributionChannel = N'Retail'
SELECT 'Return Value' = #return_value
GO
Output:
ID Attribute Value CoverageName
-----------------------------------------
1 Copay Yes Retail Base
2 Copay No Retail
. . . .
. . . .
Return Value
20
Now, while I try to read the stored procedure from jupyter notebook using pyodbc, I get an error
Procedure or function ReadCoverageMapping has too many arguments specified
I want output something like this:
ID Attribute Value CoverageName
------------------------------------------
1 Copay Yes Retail Base
2 Copay No Retail
. . . .
. . . .
I tried this code:
client = 'Capital BlueCross'
lineOfBusiness = 'Commercial'
distributionChannel = 'Retail'
cnxn = pyodbc.connect(r'Driver={SQL
Server};Server=MyServer;Database=COV_SRCE_TEST;Trusted_Connection=yes;')
sql = """\
DECLARE #out nvarchar(max);
EXEC [cov_srce_test].[coverage-source].ReadCoverageMapping #client = ?, #lineOfBusiness = ?,
#distributionChannel = ?, #param_out = #out OUTPUT;
SELECT #out AS the_output;
"""
values = (client, lineOfBusiness, distributionChannel)
cnxn.execute(sql, values)
rows = cnxn.fetchall()
while rows:
print(rows)
if cnxn.nextset():
rows = cnxn.fetchall()
else:
rows = None
Is there any way to achieve this? I tried using multiple ways, but couldn't find a solution.
Those batches are different. Looks like it should be:
sql = """\
DECLARE #return_value int
EXEC #return_value = [Coverage-Source].[ReadCoverageMapping]
#client = ?,
#lineOfBusiness = ?,
#distributionChannel = ?
SELECT 'Return Value' = #return_value
"""
which will output two resultsets, one from the stored procedure, and a second one for the Return value which you can probably omit.

Combining current date code with stored procedure ti use in PowerBi

To get the required table I have to input the value "201801" into the stored procedure query. I want to place the following code:
SELECT CONVERT(nvarchar(6), GETDATE(), 112)
In the following Sp:
USE [MDAmanager]
GO
DECLARE #return_value int
EXEC #return_value = [dbo].[sqSupplierBalances]
#Period = 201801,
#SupplierString = 'select SupplierID from Suppliers ',
#SelectionString = 'select * from vSupplierBalances order by
ControlOfficeName, PortfolioName, OwnerEntityName, RegionName,
PropertyName, PropertyManagerName, Custom1Name, Custom2Name,
ServiceTypeDescription, AnalysisCode, SupplierName',
#WithCommitments = NULL,
#UserID = NULL,
#ExcludeInDispute = NULL,
#IncludeSupplierPropertyReference = NULL
SELECT 'Return Value' = #return_value
GO
Is it possible to assign a value to the first code example and replace the "201801" in the second code example with that variable. I have been trying this but not getting it right.
Update: So I realize M query functions and SQL server functions are different. I don't how to go about answering my own question but I figured I'd give the answer here anyway.
I replaced the initial date code with:
Perdiod0 = (Date.Year(DateTime.LocalNow()) * 100) +
Date.Month(DateTime.LocalNow())
And then just replaced the 201801 with:
'" & Text.From(Period0) & "'
Seems to work now

SQL - Trying to add variable into string

I have a store procedure where I pass a path to the file like:
EXEC spMyPathFile
#PFile = 'C:\TFiles\Paths\Test_1.1_Version.txt'
What I'd like to do it loop through and be able to pass a number of versions of the file like 1.1 and 1.2 etc using:
DECLARE #intLp INT
DECLARE #a varchar(2)
SET #intLp = 1 WHILE (#intLp <2)
BEGIN IF #intLp = 1 BEGIN
SET #a = '1.1'
END
ELSE IF #intLp = 2
BEGIN
SET #a = '1.2'
END
EXEC spMyPathFile
#PFile = 'C:\TFiles\Paths\Test_'+#a+'_Version.txt'
SET #intLp = #intLp + 1
END
For some reason I get "Incorrect syntax near '+'." which is just before the #a. I'm obviously not joining my variable to my string properly.
Could someone give me an example of how this should look?
Change
EXEC spMyPathFile
#PFile = 'C:\TFiles\Paths\Test_'+#a+'_Version.txt'
to
declare #FileName varchar(100) = 'C:\TFiles\Paths\Test_' + #a + '_Version.txt'
EXEC spMyPathFile
#PFile = #FileName
Edit:
From MSDN - Specify Parameters
The parameter values supplied with a procedure call must be constants or a variable; a function name cannot be used as a parameter value. Variables can be user-defined or system variables such as ##spid.

visual studio query, with a control parameter

I'm trying to get the following query to work however im not sure exactly how to declare the variable control in the query. The Cause is the control parameter
SELECT COUNT(*)
FROM dist_reason
WHERE (cause_group_cd = '%'Cause'%')
Cheers!
If you are using C# (since it seems you want to call this from code), you would do so as follows:
string sqlStatement;
sqlStatement = string.format("SELECT COUNT(*) FROM dist_reason WHERE (cause_group_cd = '%{0}%')", Cause);
If you were doing this in SQL only, you would declare a variable and it would look like #Cause. For example:
DECLARE #Cause NVARCHAR(50)
SET #Test = 'Test'
SELECT COUNT(*)
FROM dist_reason
WHERE (cause_group_cd = '%' + #Cause + '%')