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
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;
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.
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
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.
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 + '%')