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.
Related
DECLARE #SQLSTRING VARCHAR(1500);
DECLARE #TABLENAME1 VARCHAR(30)='NOV19_COMBINE'
---------------TABLE CREATION WITH FILE NAME--------------------------
SET #SQLSTRING = 'SELECT
CONVERT(VARCHAR('+ cast((select max(len(EMAIL)) from '+#TABLENAME1+' ) as VARCHAR(50))+'), EMAIL ) AS EMAIL,
IDENTITY (INT,1,1) AS RECORDID
INTO FOI_'+#TABLENAME1+'_CONV
FROM '+#TABLENAME1+' A'
PRINT #SQLSTRING
Error:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near '+#TABLENAME1+'.
You have an issue here:
CONVERT(VARCHAR('+ cast((select max(len(EMAIL)) from ' + #TABLENAME1 + ' ) as VARCHAR(50))+')
where you are trying to select from a table defined in #TABLENAME1. That also needs to be part of your dynamic SQL.
However you have another issue with your convert(varchar( code in that you cannot use a variable as as the length to varchar(). I suggest using varchar(max) because that only uses the storage required.
I have also made your dynamic SQL safe from injection with the use of QUOTENAME which I recommend you use in future.
Fixed version:
DECLARE #SQLSTRING VARCHAR(1500);
DECLARE #TABLENAME1 VARCHAR(30) = 'NOV19_COMBINE'
---------------TABLE CREATION WITH FILE NAME--------------------------
SET #SQLSTRING = 'SELECT CONVERT(VARCHAR(max), EMAIL) AS EMAIL, IDENTITY (INT,1,1) AS RECORDID INTO '
+ QUOTENAME('FOI_' + #TABLENAME1 + '_CONV') + ' FROM '
+ QUOTENAME(#TABLENAME1) + ' A'
PRINT #SQLSTRING
There is no reason I can think of to do it this way, but as an academic exercise, if one really needed the exact length of the EMAIL column then one would use the following query:
declare #SQLSTRING nvarchar(max), #TABLENAME1 VARCHAR(30) = 'NOV19_COMBINE', #EMAILLENGTH int
SET #SQLSTRING = 'SELECT #Length = max(len(EMAIL)) from ' + QUOTENAME(#TABLENAME1)
EXECUTE sp_executesql #SQLSTRING, N'#Length int OUTPUT', #Length = #EMAILLENGTH OUTPUT
SET #SQLSTRING = 'SELECT CONVERT(VARCHAR(' + convert(varchar(4),#EMAILLENGTH) + '), EMAIL) AS EMAIL'
+ ', IDENTITY (INT,1,1) AS RECORDID'
+ ' INTO ' + QUOTENAME('FOI_' + #TABLENAME1 + '_CONV')
+ ' FROM ' + QUOTENAME(#TABLENAME1) + ' A'
PRINT #SQLSTRING
This requires 2 sections of dynamic SQL, the first to find the length of the EMAIL column, which is then used to built the dynamic SQL for the actual query.
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
Some of you may think I am doing the worst thing ever to a stored procedure but it's just a experiment at this time, this is what I am doing,
CREATE procedure [dbo].[Flags_Update]
(
#UserID nvarchar(255),
#CategoryID INT,
#ProductID INT,
#PropertyName nvarchar(255),
#PropertyValue nvarchar(max)
)
AS
DECLARE #sql nvarchar(500);
SET #sql = 'UPDATE Flags SET ' + #PropertyName + ' = ' + #PropertyValue + ' WHERE Flags Flags.CategoryID =' + #CategoryID + ' AND Flags.ProductID ='+ #ProductID;
EXEC(#sql);
IF (##ROWCOUNT=0)
BEGIN
SET #sql = 'INSERT INTO Flags(UserID, CategoryID, ProductID, '+ #PropertyName + ') VALUES(' + #UserID + ', ' + #CategoryID + ', ' + #ProductID + ', ' + #PropertyValue + ')';
EXEC(#sql);
END
GO
When executing I am getting this error,
Conversion failed when converting the nvarchar value 'UPDATE Flags SET
IsRelased = 1 WHERE Flags Flags.CategoryID =' to data type int.
I know the error is coming up because in procedure propertyName is nvarchar(255) when column type is INT, how can I overcome this error ?
Please note that some property column will be nvarchar and some will be INT
EDIT
I did a clever thing and decided to have each property column have nvarchar(255) as datatype but I am still getting this error.
EDIT 2
Casting as suggested by Martin below but getting this error now,
An expression of non-boolean type specified in a context where a
condition is expected, near 'Flags'
This is occurring because some of your parameters in the SET #sql statement are INT values.
Try CASTing (or CONVERTing) the INT fields to NVARCHARs. You will need to do this throughout your code where you concatenate text and numbers.
SET #sql = 'UPDATE Flags SET ' + #PropertyName + ' = ' + #PropertyValue + ' WHERE Flags Flags.CategoryID =' + CAST(#CategoryID AS NVARCHAR) + ' AND Flags.ProductID ='+ CAST(#ProductID AS NVARCHAR);
Note that I have changed + #CategoryID + to + CAST(#CategoryID AS NVARCHAR) +, and so on.
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.
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)