The following code sends error.
#resp2 is INT, it's the result of a sum preiously done. So now I want to update some row in another table using a dinamic statement.
SET #SQL = 'update TelepromTableNamesInfo set [Resp] = '+#RESP2+'
where nombre = ''' + #TableWBraq + ''''
EXEC (#SQL)
First thing I've tried is '''+#resp2+''' But I don't want it be
' variable value '
since it's an INT value and there's no need for ''
The error makes sence. I can't put some INT value into a string. I'd use cast or convert but how can I do it inside the statement?
Or maybe I'm approaching the update from the wrong perspective?
Thanks.
EDIT
Solved.
'+ cast(#RESP2 as nvarchar(7))+'
It was easier than I thought, thanks.
SET #SQL = 'update TelepromTableNamesInfo set [Resp] = '+ CAST(#RESP2 AS VARCHAR(50)) +'
where nombre = ''' + #TableWBraq + ''''
EXEC (#SQL)
May be single quote is creating the problem. Please give a try the following:
SET #SQL = 'update TelepromTableNamesInfo set [Resp] = '+#RESP2+
'where nombre = '"' + #TableWBraq + '"'
EXEC (#SQL)
Related
I created the below stored procedure in sql server that requires 3 parameters: Date, URL, & Table Name:
ALTER PROCEDURE [stg].[usp_Delete_Data]
(#DateLookBack date,
#siteUrl nvarchar(100),
#tableName SYSNAME)
AS
BEGIN
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'DELETE FROM ' + CONCAT('[stg].[',#tableName,']') +
'WHERE date = ' + FORMAT(#DateLookBack, 'yyyyMMdd') +
'AND siteUrl = ' + #siteUrl
EXEC sp_executesql #Sql
END
When I pass in a url, like 'https://stackoverflow.com', I get an error message:
Incorrect syntax near 'https:'
How do I format the url string so that it can pass into the query successfully?
I'd strongly advise against this method. Having so many tables of the same structure that it requires a single procedure where the table name is dynamic is a code smell in itself.
If you must use dynamic sql though, at least use parameters as much as possible and only inject your table name, i.e.
SET #sql = CONCAT(N'DELETE FROM [stg].' QUOTENAME(#tableName),
' WHERE Date = #Date AND SiteUrl = #SiteUrl;');
EXECUTE sp_executesql #sql, N'#Date date, #SiteUrl nvarchar(100)', #date, #SiteUrl;
To find such issue, all you need is to PRINT the query before you use it! You could examine the query which is executed, if you printed it first.
Replace the commend Exec sp_executesql #Sql with the command PRINT #Sql and examine the query you get.
In your case, after you do it, then when you execute the procedure using the following command, then I can see all the issues.
EXECUTE dbo.[usp_Delete_Data]
#DateLookBack = '2022-02-27' ,#siteUrl = 'https://stackoverflow.com' , #tableName = 'c'
GO
The printed text which we get is: DELETE FROM [stg].[c]WHERE date = 20220227and siteUrl = https://stackoverflow.com
Now we can go over the errors (yes there are multiple errors here) one by one
(1) Notice that the 'WHERE date = ' missing a space before the "where" which might combine the word "where" with the table name that comes before it. You need to add space like ' WHERE date = '
same with the part after the and siteUrl - missing space before the and
(2) Notice this part: siteUrl = https://stackoverflow.com. in the query you are building you do not have quotation marks around the text of the URL => this lead to the error message.
instead of 'and siteUrl = ' + #siteUrl it should be: 'and siteUrl = ''' + #siteUrl + ''''
(3) same issue you have with the date - you do not have quotation marks around the text of the date
instead of ' WHERE date = ' + format(#DateLookBack,'yyyyMMdd') it should be ' WHERE date = ''' + format(#DateLookBack,'yyyyMMdd') + ''''
So, after adding these fixes, you get the following SP (I use PRING instead of execute but you can change this back)
CREATE OR ALTER PROCEDURE [usp_Delete_Data] (
#DateLookBack date,#siteUrl nvarchar(100), #tableName SYSNAME
) AS BEGIN
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'DELETE FROM ' + CONCAT('[stg].[',#tableName,']')
--+ ' WHERE date = ' + format(#DateLookBack,'yyyyMMdd')
+ ' WHERE date = ''' + format(#DateLookBack,'yyyyMMdd') + ''''
+ ' and siteUrl = ''' + #siteUrl + ''''
--+ 'and siteUrl = ' + #siteUrl
PRINT #Sql
--Exec sp_executesql #Sql
END
and now if I execute the same query
EXECUTE dbo.[usp_Delete_Data]
#DateLookBack = '2022-02-27' ,#siteUrl = 'https://stackoverflow.com' , #tableName = 'c'
GO
It will print something that looks like:
DELETE FROM [stg].[c] WHERE date = '20220227'and siteUrl = 'https://stackoverflow.com'
BUT! NOW WE CAN GO TO THE MOST PROBLEMATIC ISSUE! Your procedure is open to SQL Injection! You should NOT use such code.
You should use parameters whenever you can when you use sp_executesql and not combine text text. Read the documentation of sp_executesql on how to use parameters as input: https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql
Really wrecking my head here and as with many sql mess up I know it is probably something silly and stupid but I just cant seem to get it to work.
I have a stored procedure which is this..
ALTER PROCEDURE [dbo].[RETURN_DATA](#TABLE_param VARCHAR(7),#COUNTRY_param VARCHAR(2),#FILEDATE_param int,#TTKT_param VARCHAR(6))
AS
BEGIN
SET NOCOUNT ON;
SELECT #SQL = 'Select * from ' + #TABLE_param + ' WHERE COUNTRY = ' + #COUNTRY_param + ' AND MONTH(Fil_Dte) = ' + cast(#FILEDATE_param as varchar(20)) + ' AND TRNN = '+ #TKTT_param
EXECUTE(#SQL)
END
I'm using it in a vb.net windows form app so applying the parameters there. But trying to run it in SSMS with this
exec RETURN_DATA #COUNTRY_param='GB',#FILEDATE_param=4,#TABLE_param='table30',#TTKT_param='000000'
Returns the error
Invalid column name 'GB'. which i find strange as I never called for a column called GB but called for rows with GB in the column COUNTRY in my where clause?
I know this hopefully is a simple fix so any help would be greatly appreciated and also even if you think theres a better way to go about writing the SP!
Thanks in advance guys.
I'd recommend parameterising the SQL which will guard against SQL injection and you don't have to worry about escaping quotes as below
ALTER PROCEDURE [dbo].[RETURN_DATA](#TABLE_param VARCHAR(7),#COUNTRY_param VARCHAR(2),#FILEDATE_param int,#TTKT_param VARCHAR(6))
AS
BEGIN
SET NOCOUNT ON;
SELECT #SQL = 'Select * from ' + #TABLE_param + ' WHERE COUNTRY = ''' + #COUNTRY_param + ''' AND MONTH(Fil_Dte) = ' + cast(#FILEDATE_param as varchar(20)) + ' AND TRNN = '''+ #TKTT_param +''''
EXECUTE(#SQL)
END
Use sp_executesql to run dynamic sql
DECLARE #SQL NVARCHAR (4000);
SET #SQL = '
Select *
from ' + QUOTENAME(#TABLE_param) + '
WHERE COUNTRY = #COUNTRY_param
AND MONTH(Fil_Dte) = #FILEDATE_param
AND TRNN = #TTKT_param
';
EXEC sp_executesql #SQL,
N'#COUNTRY_param VARCHAR(2), #FILEDATE_param int, #TTKT_param VARCHAR(6)',
#COUNTRY_param, #FILEDATE_param, #TTKT_param;
sp_executesql
Below is the query causing error:
EXECUTE (' UPDATE facetswrk.dbo.ODS_SUBSC_PREM_REPORT ' + ' SET ' + #lcrcolumn_name + ' = ' + #lcrcolumn_total)
Your syntax is ok, probably you have wrong valye for column name, or you need to cast #lcrcolumn_tot as nvarchar.
Give us the value for the variable, pr check by yourself with the flowing statement:
declare #lcrcolumn_name nvarchar(50) = 'blabla',
#lcrcolumn_tot nvarchar(50) = 10
declare #sql nvarchar(4000);
set #sql = ' UPDATE facetswrk.dbo.ODS_SUBSC_PREM_REPORT SET ' + #lcrcolumn_name + ' = ' + #lcrcolumn_tot
print #sql
execute(#sql)
Best is to print the dynamic sql before you execute it to understand what is causing the error, you may have some data value in #lcrcolumn_name and #lcrcolumn_total which may be creating the problem.
I simple want to update the price with for example here 3, but this with a stored procedure.
I already tried it with normal syntax:
update tblPrijs
set PrijsVerkoop = PrijsVerkoop + 1
where PrijsId = '6';
and this works fine.
But my stored procedure always returns :
updatetblPrijssetPrijsVerkoop=PrijsVerkoop+3.00wherePrijsId=11
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.
and I don't know what I did wrong..
The stored procedure:
alter PROCEDURE updatePrice
-- Add the parameters for the stored procedure here
#table nvarchar(50),
#field nvarchar(50),
#increase nvarchar(50),
#id nvarchar(50),
#value nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #sql as nvarchar(400);
-- Insert statements for procedure here
set #sql = 'update' + #table + 'set' + #field + '=' + #field + '+' + #increase +
'where' + #id + '=' + #value
print #sql /* drukt het resultaat van concat af */
exec(#sql)
END
GO
This is what I write in my query:
updatePrice'tblPrijs', 'PrijsVerkoop','3.00', 'PrijsId','11'
sorry for the dutch names of fields and tables...
I think it is something small and obvious that is wrong but I just can't see it..
This is in SQL Server 2012
Thank you in advance!
You need to add some spaces in there.
This:
set #sql = 'update' + #table + 'set' +#field + '=' ...
if you add the following parameters:
#table = SomeTable
#field = SomeField
will result in this sql:
updateSomeTablesetSomeField=
Surely that's not what you intended.
I'm assuming by the print #sql statement that you wanted to print your sql statement before executing it. What did it show?
Here's something to try:
set #sql = 'update ' + #table + ' set ' + #field + ' = ' + #field + ' + ' + #increase + ' where ' + #id + ' = ' + #value
I added spaces inside each string, at the start and at the end. Some of those spaces are not strictly needed, but they won't change the outcome either.
I want create function, which use table name as parameter. As I search I need use dynamic sql. I try such code:
CREATE FUNCTION get_column_id
(
#TableName VARCHAR(30),
#ColumnName VARCHAR(30),
)
RETURNS int
AS
BEGIN
IF EXISTS
(
DECLARE #SQL VARCHAR(50)
SET #sql = 'SELECT' + #ColumnName + 'FROM' + #TableName + 'WHERE #ColumnName = #ColumnNameValue';
EXEC(#sql)
)
BEGIN
But get errors. Is where any way to procceed this?
I try use dynamic sql in such way
DECLARE #SQL VARCHAR(50)
SET #SQL = 'SELECT' + #ColumnName + 'FROM' + #Table + 'WHERE #ColumnName = #ColumnNameValue'
EXEC(#SQL)
DECLARE #TableName table (Name VARCHAR(30))
INSERT INTO #TableName VALUES (#SQL)
IF EXISTS
(SELECT Name FROM #TableName WHERE Name = #ColumnNameValue)
But get Invalid use of a side-effecting operator 'EXECUTE STRING' within a function.
Does anyone knows how bypass this constraint?
The error is the concatenation of string which lacks space in between,
SET #sql = 'SELECT ' + #ColumnName + ' FROM ' + #TableName + ' WHERE ' + #ColumnName + ' = ' + #ColumnNameValue;
-- ^ SPACE HERE ^ ^ ^ and here
if for instance the data type of the column is string, you need to wrap the value with single quotes,
SET #sql = 'SELECT ' + #ColumnName + ' FROM ' + #TableName + ' WHERE ' + #ColumnName + ' = ''' + #ColumnNameValue + '''';
UPDATE 1
You also need to declare the parameter #ColumnNameValue, eg
CREATE FUNCTION get_column_id
(
#TableName VARCHAR(30),
#ColumnName VARCHAR(30),
#ColumnNameValue VARCHAR(30)
)
A UDF (user defined function) in Sql Server must be deterministic. Beside your syntax errors you won't be able to accomplish your task.
if you check this article on MSDN:
http://msdn.microsoft.com/en-us/library/ms178091.aspx
You can see the citation below:
Deterministic functions always return the same result any time they are called
with a specific set of input values and given the same state of the database.
Nondeterministic functions may return different results each time they are
called with a specific set of input values even if the database state that
they access remains the same.