Incorrect syntax near 'REPLACE' - mysql

the following SQL statement shows solid results with PRINT but with EXEC, gives me Incorrect syntax near 'REPLACE'
USE EPDB
DECLARE #Table as nvarchar(100)
DECLARE #Column as nvarchar(100)
DECLARE #Select as nvarchar(375)
DECLARE #Where as nvarchar(275)
SET #Table = 'TableABC'
SET #Column = 'ColumnABC'`enter code here`
SET #Select = 'SELECT * FROM INFORMATION_SCHEMA.COLUMNS'
SET #Where = 'CRITERIA = ''VALUE'''
-- EXEC ('SELECT * FROM INFORMATION_SCHEMA.COLUMNSWHERETABLE_NAME = ' + #Table + '''')
PRINT #Select + ' WHERE ' + REPLACE(REPLACE(#Where,'CRITERIA','TABLE_NAME'),'VALUE',#Table)
EXEC (#Select + ' WHERE ' + REPLACE(REPLACE(#Where,'CRITERIA','TABLE_NAME'),'VALUE',#Table))
not sure what is going on here

Try this:
DECLARE #sSQL varchar(1000)
SET #sSQL = #Select + ' WHERE ' + REPLACE(REPLACE(#Where,'CRITERIA','TABLE_NAME'),'VALUE',#Table)
EXEC (#sSQL)
I believe EXEC() accepts either string variable or a string constant, but not combination.

Related

How to pass column name along with other parameters

I have below SPROC in which i am passing column name(value) along with other parameters(Place,Scenario).
ALTER PROCEDURE [dbo].[up_GetValue]
#Value varchar(20), #Place varchar(10),#Scenario varchar(20), #Number varchar(10)
AS BEGIN
SET NOCOUNT ON;
DECLARE #SQLquery AS NVARCHAR(MAX)
set #SQLquery = 'SELECT ' + #Value + ' from PDetail where Place = ' + #Place + ' and Scenario = ' + #Scenario + ' and Number = ' + #Number
exec sp_executesql #SQLquery
END
GO
when executing : exec [dbo].[up_GetValue] 'Service', 'HOME', 'Agent', '123697'
i am getting the below error msg
Invalid column name 'HOME'.
Invalid column name 'Agent'.
Do i need to add any thing in the sproc??
First: You tagged your question as mysql but I think your code is MSSQL.
Anyway, your problem is that you need to add quotes around each string valued parameter.
Like this:
alter PROCEDURE [dbo].[up_GetValue]
#Value varchar(20), #Place varchar(10),#Scenario varchar(20), #Number varchar(10)
AS BEGIN
SET NOCOUNT ON;
DECLARE #SQLquery AS NVARCHAR(MAX)
set #SQLquery = 'SELECT ' + QUOTENAME(#Value) + ' from PDetail where Place = ''' + #Place + ''' and Scenario = ''' + #Scenario + ''' and Number = ''' + #Number +''''
print #SQLquery
exec sp_executesql #SQLquery
END
GO
Update:
Use QUOTENAME to make sure it works.
QUOTENAME:
Returns a Unicode string with the delimiters added to make the input string a valid SQL Server delimited identifier.
You need to quote column names with ` (backtick) and string values with ".
set #SQLquery = 'SELECT `' + #Value + '` from PDetail where Place = "' + #Place + '" and Scenario = "' + #Scenario + '" and Number = ' + #Number
Try using a prepared statement instead of concatinating the string.
Example:
PREPARE stmt1 FROM 'SELECT ? from PDetail where Place = ? and Scenario = ? and Number = ?;
EXECUTE stmt1 USING #Value, #Place, #Scenario, #Number;

SQL Server Execute update result sets from dynamic query writer

This link is where I found part of an answer to my problem.
SQL replace all NULLs
Simon posted
"Be a boss. Write something like:
select 'update ' + table_name + ' set [' + column_name + '] = '''' where [' + column_name + '] is null'
from tempdb.information_schema.columns
where table_name = 'YourTableName'
It'll spit out a big ol' query for you.
You're welcome"
But I would like to know if there a way to use the results set in a parameter and execute all of the update statements.
I tried something like this
DECLARE #sql2 AS NVARCHAR(MAX) = N'
SELECT ''UPDATE '' + table_name + '' SET ['' + column_name + ''] = '''''''' WHERE ['' + column_name + ''] IS NULL''
FROM tempdb.information_schema.columns
WHERE table_name = ''##tempF'''
EXEC sp_executesql #stmt = #sql2;
DECLARE #sql3 AS NVARCHAR(MAX);
SET #sql3 = (SELECT #sql2);
EXEC sp_executesql #stmt = #sql3;
but it two result sets like listed below:
UPDATE ##tempF SET [claimid] = '' WHERE [claimid] IS NULL
UPDATE ##tempF SET [hdr_status] = '' WHERE [hdr_status] IS NULL
UPDATE ##tempF SET [memid] = '' WHERE [memid] IS NULL
Many thanks to you all.
Cheers!
Tim
Like this
--initialize variables
DECLARE #UpdateColumns varchar(max) = ''
DECLARE #IsNullColumns varchar(max) = ''
SELECT
#UpdateColumns = #UpdateColumns + ',[' + COLUMN_NAME + '] = ISNULL([' + COLUMN_NAME + '],'''')',
#IsNullColumns = #IsNullColumns + ' OR [' + COLUMN_NAME + '] IS NULL'
FROM tempdb.information_schema.columns
WHERE table_name = '##tempF'
This should fill in the two variables with the following values:
#UpdateColumns = ',[claimid] = ISNULL([claimid],''''),[hdr_status] = ISNULL([hdr_status],''''),[memid] = ISNULL([memid],'''')'
#IsNullColumns = ' OR [claimid] IS NULL OR [hdr_status] IS NULL OR [memid] IS NULL'
Then you need to assemble it all (remember to remove the first characters of each of the variables (the STUFF function is great for that):
DECLARE #qry varchar(max) = 'UPDATE ##tempF SET '
+ STUFF(#UpdateColumns,1,1,'') + ' WHERE '
+ STUFF(#IsNullColumns,1,4,'') --the 4 in here is to get rid of ' OR ' (4 chars)
EXEC(#qry)

Variable has unexpected NULL value in dynamic SQL

I have searched high and low, without finding an answer. So I hope that you guys n girls can help me on my way:
I cant figure out why #old_comment is NULL when I use it in "SET #new_comment...", but it returns a fine value when I use it in the outputparameter "SET #commentOldOUT..."
CREATE PROCEDURE [dbo].[SP_NY_KOMMENTAR]
#tabel NVARCHAR(100),
#id INT,
#comment NVARCHAR(1000) = NULL,
#commentOldOUT NVARCHAR(1000) = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #user NVARCHAR(30);
DECLARE #date NVARCHAR(10);
DECLARE #new_id VARCHAR(100);
DECLARE #new_comment NVARCHAR(MAX);
DECLARE #old_comment NVARCHAR(MAX);
DECLARE #old_comm NVARCHAR(MAX);
DECLARE #old NVARCHAR(MAX);
DECLARE #q2 NVARCHAR(MAX);
SET #new_id = (SELECT CAST(#id AS VARCHAR(100)));
SET #user = (SELECT ORIGINAL_LOGIN());
SET #date = (SELECT CONVERT(DATE,GETDATE()));
SET #old = 'SELECT comment FROM '+ #tabel +' WHERE id = ' + #ny_id;
EXEC sp_executesql
#query = #old,
#params = N'#old_comm NVARCHAR(MAX) OUTPUT',
#old_com = #old_comm OUTPUT;
SET #old_comment = (SELECT #old_comm);
SET #commentOldOUT = #old_comment;
SET #new_comment = COALESCE(#old_comment + CHAR(13),'') + '[' + #user + ' ' + #date + '] ' + #comment;
SET #q2 = N'UPDATE ' + #tabel + ' SET comment = ''' + #new_comment + ''' WHERE id = ' + #ny_id;
EXEC (#q2);
END
Sorry, I tried your query but for me it works fine! Have you tried to "debug" your query? You can see the value of every variable when in debug. (The green arrow in SQL Server 2008)
I'm guessing that you didn't pass a value explicitly for the #comment parameter? If so, the problem would be here:
SET #new_comment = COALESCE(#old_comment + CHAR(13),'') + '[' + #user + ' ' + #date + '] ' + #comment;
The parameter #comment has a default value of NULL and concatenating anything with NULL results in NULL. That would explain why #old_comment, #user and #date all have values, but when it put it all together then #new_comment is NULL. This would be a better default value:
#comment NVARCHAR(1000) = '',
And your code as written is a bit messy, I assume that #old_comment and #commentOldOUT are only for debugging purposes? I don't see why you don't use #old_comm directly.
Finally, if you're working with dynamic SQL then I strongly recommend adding a debugging parameter to print out your SQL strings easily. It's a very useful troubleshooting tool, especially if you don't have SSMS available.
Well I can now see that I did several things wrong, below is the new, and now working, stored procedure:
CREATE PROCEDURE [dbo].[SP_NY_KOMMENTAR]
#tabel NVARCHAR(100),
#id INT,
#comment NVARCHAR(1000) = NULL
AS
IF #comment IS NOT NULL
BEGIN
SET NOCOUNT ON;
DECLARE #user NVARCHAR(30);
DECLARE #date NVARCHAR(10);
DECLARE #SQLSelect nvarchar(500);
DECLARE #ParmSelect nvarchar(500);
DECLARE #old_comment NVARCHAR(MAX);
DECLARE #old_commentOUT NVARCHAR(MAX);
DECLARE #new_comment NVARCHAR(MAX);
DECLARE #SQLUpdate nvarchar(500);
DECLARE #ParmUpdate nvarchar(500);
SET #user = (SELECT ORIGINAL_LOGIN());
SET #date = (SELECT CONVERT(DATE,GETDATE()));
SET #SQLSelect = N'SELECT #old_commentOUT = kommentar FROM ' + QUOTENAME(#tabel) + ' WHERE id = #id';
SET #ParmSelect = N'#id INT, #old_commentOUT NVARCHAR(MAX) OUTPUT';
EXEC sp_executesql
#SQLSelect,
#ParmSelect,
#id = #id,
#old_commentOUT = #old_comment OUTPUT;
SET #old_comment = (SELECT #old_comment);
SET #new_comment = COALESCE(#old_comment + CHAR(13) + CHAR(10),'') + '[' + #user + ' ' + #date + '] ' + #comment;
SET #SQLUpdate = N'UPDATE ' + QUOTENAME(#tabel) + ' SET kommentar = #new_comment WHERE id = #id';
SET #ParmUpdate = N'#id INT, #new_comment NVARCHAR(MAX)';
EXEC sp_executesql
#SQLUpdate,
#ParmUpdate,
#id = #id,
#new_comment = #new_comment;
END
For example I weren't using parameterbinding correct, after that I tried to bind tabelnames as a parameter...

GUID in dynamic sql

I am trying to use a column of type uniqueidentifier in Dynamic SQL.
I have a table X, with column ID of type guid.
If I do:
declare #primarykeyvalue varchar(50)
set #primarykeyvalue = '648D2DD7-0EB1-4E29-A996-69456753C460'
select * from X where ID = #primarykeyvalue
This works, but if I try to do the same in dynamic SQL like:
DECLARE #sql NVARCHAR(1000)
SET #sql = 'select * from X where ID = ' + #primarykeyvalue
EXECUTE(#sql)
This gives an syntax error as Incorrect syntax near 'D2DD7'.
Any suggestions please?
Change your code to:
DECLARE #sql NVARCHAR(1000)
SET #sql = 'select * from X where ID = ''' + #primarykeyvalue + ''''
EXECUTE(#sql)
Maybe you should think about using sp_executesql:
DECLARE #sql NVARCHAR(1000)
SET #sql = 'select * from X where ID = #key'
EXECUTE sp_executesql #sql, N'#key nvarchar(50)', #key = #primarykeyvalue
This enables you to use parameters in your queries and gets rid of the nasty doubled
single quotes.
You need extra quotes around your GUID value:
DECLARE #sql NVARCHAR(1000)
SET #sql = 'select * from X where ID = ''' + #primarykeyvalue + ''''
EXECUTE(#sql)

Dynamic SQL concatenation

Having an issue concatenating the following statement.
Basically I want the length column to add inches after but it will not run. I am going to create a function out of this in the future but unable to get past this step. What gives?
declare #column varchar(255)
declare #sql varchar(5000)
declare #additional varchar(500)
set #column = 'length'
set #additional = 'inches'
select #sql = 'select distinct ps.p_c_id, '
select #sql = #sql + #column + ' '+#additional+ ' ' + ' as value'
select #sql = #sql
select #sql = #sql + ' from dbo.Product ps
inner join dbo.ProductAttributes psa on psa.p_s_id = ps.p_s_id
where ps.p_c_id is not null and ' + #column + ' is not null'
exec (#sql)
You are concatenating, what i'm assuming is an int or float value to a string ' inches'...have to cast the "length" value as a varchar...
just select your #sql next time to see the resulting syntax and it should jump out at you. here is changes that should work
BTW...look at implementing EXEC sp_executesql ...makes dynamic sql less suseptable to injection by using parameters, etc... look up in Books OnLine
Sorry...eating Crow...sp_executesql does not protect from injection just improves performance in general...see article MSDN SQL Injection
declare #column varchar(255)
declare #sql varchar(5000)
declare #additional varchar(500)
set #column = 'psa.length'
set #additional = 'inches'
select #sql = 'select distinct ps.p_c_id, '
select #sql = #sql + 'CAST(' + #column + ' AS varchar(10)) + ' + ''' '+#additional+ ''' ' + ' as value'
select #sql = #sql
select #sql = #sql + ' from dbo.Product ps
inner join dbo.ProductAttributes psa on psa.p_s_id = ps.p_s_id
where ps.p_c_id is not null and ' + #column + ' is not null'
--select #sql AS [ExecutableSQL]
exec(#sql)
Your output is;
select distinct ps.p_c_id, length inches as value from dbo.Product ps
inner join dbo.ProductAttributes psa on psa.p_s_id = ps.p_s_id
where ps.p_c_id is not null and length is not null
So it looks like a missing , between length inches assuming you want both;
select #sql = #sql + #column + ','+ #additional+ ' ' + ' as value'