Adding an apostrophe into a dynamic SQL - sql

I would like to ask how can I add an apostrophe into a dynamic SQL. I need to return an SQL statement in one of the columns which has to have apostrophes in itself.
I have the following statement:
SET #SQL_String = N'INSERT INTO #ReturnTable
(
TableName,
ColName,
SQL_Statement,
Value
)
VALUES
(
''' + #TableName + ''',
''' + #ColName + ''',
''' +
'SELECT ' +
#ColName +
' FROM ' +
#TableSchema + '.' + #TableName +
' WHERE ' +
#ColName + ' = ' + CAST(#GuidArgument AS NVARCHAR(50)) + ';' +''',
(
SELECT
' + #ColName + '
FROM
' + #TableSchema + '.' + #TableName +
' WHERE '
+ #ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) +
'''))';
Executing with:
EXECUTE #RC = [dbo].[GetLocationOfGuidPre] 'F2CAB996-F00F-43B8-A67A-0000721A829D'
I need to put a whole first CAST into a pair of '.
I've tried:
Putting whole CAST statement into a separeted variable like: DECLARE #Test NVARCHAR(50);
SET #Test = CAST(#GuidArgument AS NVARCHAR(50));
SET #Test = 'CAST(#GuidArgument AS NVARCHAR(50))';
SET #Test = '''CAST(#GuidArgument AS NVARCHAR(50))''';
Addidng two more apostrophes:
' WHERE ' + #ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + ''';'

Please use CHAR(39) instead of typing ' in your dynamic code directly.
Example:
declare #my_dynamic_sql nvarchar(max) = 'print char(39);';
exec(#my_dynamic_sql);

Related

Dynamic SQL - Insert a variables via INSERT INTO x SELECT statement

I would like to ask how can I insert a variables into a table using INSERT INTO x SELECT statement via dynamic SQL.
I have following table:
|-------------------|-----------------|--------------|-----------------|
| TableName | ColName | Value | SQL_Statement |
|-------------------|-----------------|--------------|-----------------|
I get a content for Value column by this query:
INSERT INTO #ReturnTable(Value) SELECT TreeHolder FROM prm.Schm_Root WHERE ParentTreeHolderId = 'DD040D31-4591-4658-A02E-A6ED00AB64F2';
But I need to fill whole table. Please consider that other values are variables, not SQL queries.
SELECT #TableSchema = TableSchema FROM #TableNames WHERE Id = #Counter;
SELECT #TableName = TableName FROM #TableNames WHERE Id = #Counter;
SELECT #ColName = ColName FROM #TableNames WHERE Id = #Counter;
SET #SQL_Statement = 'SELECT ' + #ColName + ' FROM ' + #TableSchema + '.' + #TableName + ' WHERE ' + #ColName + ' = ' + '''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''' + ';';
Now I have this query that fills a table:
SET #SQL_String = N'INSERT INTO #ReturnTable SELECT
''' + #TableName + ''',
''' + #ColName + ''',
''' + #SQL_Statement + ''',
'' + Value + '',
(SELECT ' +
#ColName + '
FROM ' +
#TableSchema + '.' + #TableName + '
WHERE ' +
#ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + '
'')';
EXECUTE sp_executesql #SQL_String
PRINT #SQL_String;
The thing I need is to rewrite this query from INSERT INTO ? VALUE to INSERT INTO ? SELECT format.
If I understand correctly, you want to insert SQL execute syntax string and it results in ReturnTable table.
I would let subquery SQL execute syntax save in a variable. because the will be more clear what you need to do.
Declare a new variable #SQL_excuteStatement variable to save your execute syntax.
the #SQL_Statement to carry the original SQL string.
set #SQL_Statement = 'SELECT ' + #ColName +
' FROM ' + #TableSchema + '.' + #TableName +
' WHERE ' + #ColName + ' = '+'''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''';
and use select ... from table instead of subquery in select
There is a sample for you.
DECLARE #SQL_String NVARCHAR(MAX)
DECLARE #TableSchema NVARCHAR(MAX)
DECLARE #TableName NVARCHAR(MAX)
DECLARE #ColName NVARCHAR(MAX)
DECLARE #Counter int = 1
DECLARE #SQL_Statement NVARCHAR(MAX)
DECLARE #GuidArgument INT = 1
CREATE TABLE TableNames(
ID INT,
TableSchema NVARCHAR(100),
TableName NVARCHAR(100),
ColName NVARCHAR(100)
);
CREATE TABLE ReturnTable(
TableName NVARCHAR(100),
ColName NVARCHAR(100),
SQL_Statement NVARCHAR(max),
value nvarchar(max)
);
INSERT INTO TableNames VALUES (1,'dbo','T','val');
CREATE TABLE T(val INT);
INSERT INTO T VALUES (1)
SELECT #TableSchema = TableSchema FROM TableNames WHERE Id = #Counter;
SELECT #TableName = TableName FROM TableNames WHERE Id = #Counter;
SELECT #ColName = ColName FROM TableNames WHERE Id = #Counter;
set #SQL_Statement = 'SELECT ' + #ColName +
' FROM ' + #TableSchema + '.' + #TableName +
' WHERE ' + #ColName + ' = '+ '''''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''''';
SET #SQL_String = N'INSERT INTO ReturnTable (TableName,ColName,SQL_Statement,value)
SELECT '''+ #TableName + ''','''+ #ColName + ''','''+ #SQL_Statement + '''' + ',' + QUOTENAME(#ColName) +
' FROM ' + QUOTENAME(#TableSchema) + '.' + QUOTENAME(#TableName) + '' +
' WHERE ' + #ColName + ' = ''' + CAST(#GuidArgument AS NVARCHAR(50)) + '''';
EXECUTE sp_executesql #SQL_String
sqlfiddle
Note
I would suggest you use clear column after insert into
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;

Comparing string with an UNIQUEIDENTIFIER?

I have written the following procedure:
ALTER PROCEDURE [dbo].[GetLocationOfGuidPre]
#GuidArgument UNIQUEIDENTIFIER
.
.
.
SET #SQL_String = 'INSERT INTO #Guids(FoundGuid) SELECT ' + #ColName + ' FROM ' + #TableSchema + '.' + #TableName + ' WHERE ' + #ColName + ' = ' + #GuidArgument;
When I try to execute it, I get this error:
The data types nvarchar and uniqueidentifier are incompatible in the add operator.
How can I compare a string value with UNIQUEIDENTIFIER?
Have you tried passing it as a parameter?
SET #SQL_String = 'INSERT INTO #Guids(FoundGuid) SELECT ' + #ColName + ' FROM ' + #TableSchema + '.' + #TableName + ' WHERE ' + #ColName + ' = #GuidArgument';
EXEC sp_executesql #SQL_string,
N'#GuidArgument UNIQUEIDENTIFIER',
#GuidArgument = #GuidArgument;
I guess the reason for this error is pretty clear: it says + ' = ' + #GuidArgument; does not work, since you try to add an unique ID to a varchar... just try to cast your #GuidArgumentas varchar and it should work.

Update column by looping through rows

I have four columns in a table ID, Longitude, Latitude, and SpatialData. I have the first three columns filled out for every row, but I need to enter in the SpatialData for each row. I can currently manually update the SpatialData column by using the below query:
update GioMap set SpatialData = 'Point(-74.009506 40.70602)' Where ID =1
From here I have to keep manually updating the Longitude, Latitude and ID for every row. I am using this code to try to loop through all of the rows and update the table that way:
DECLARE #LoopC INT = 1, #MaxOID INT,
#Long nVarchar(32), #Lat nVarchar(32),#Col1 nVarchar(11)
SET #MaxOID = (select count(*) from GioMap)
Set #Col1 = 'SpatialData'
WHILE(#LoopC <= #MaxOID)
BEGIN
SET #Long = (Select Longitude FROM GioMap where ID = #LoopC)
SET #Lat = (Select Latitude FROM GioMap where ID = #LoopC)
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
EXEC sp_executesql #sql
SET #LoopC = #LoopC + 1
END
When I run this code I keep getting this error message:
Msg 245, Level 16, State 1, Line 13
Conversion failed when converting the nvarchar value 'update [ISSHXI1].[dbo].[GioMap] set SpatialDat = 'Point(-74.0095 40.706)' Where ID = ' to data type int.
I don't understand why it would be trying to convert it to an int?
You could do something like this:
UPDATE GioMap SET SpatialData = 'Point(' + cast(Longitude as varchar) + ' ' + cast(Latitude as varchar) + ')'
I think the way you are doing it is bad, but that's not technically what you asked.
It is trying to convert it to an int because you are adding a varchar to an int. You need to change this:
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' +
'''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' +
#LoopC)
to this
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' +
'''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' +
Cast(#LoopC as varchar))
The point statement paramaters need to be seperated by a comma.
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
Instead of:
#Long + ' ' + #Lat + ')
try
#Long + ',' + #Lat + ')
To see what is being executed you can try adding a print statement:
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
print #sql
EXEC sp_executesql #sql
Also why do you parans around strings you are assigning? Its confusing in TSQL. While it works it is jarring and unusual.
Instead of:
SET #MaxOID = (select count(*) from GioMap)
try
SET #MaxOID = 'select count(*) from GioMap'
Later in the code you do both parens and quotes. The great, great majority of TSQL developers just use single quotes.
Ben

update special character columns dynamically for all columns of a table?

I want to replace special characters by normal characters in all columns dynamically for all columns of a table.But it works only for a column which is hardcoded
alter proc dbo.specialcharacterreplacer
#tblname varchar(1000),
#column_name varchar(1000)
as
begin
declare #Sql VARCHAR(MAX)
set #Sql = '
UPDATE ' + #tblname + ' SET ' + #column_name+ ' = REPLACE('+#column_name + ', ' + '''ó'''+ ', '+'''o'''+')
UPDATE ' + #tblname + ' SET ' + #column_name+ ' = REPLACE('+#column_name + ', ' + '''ò'''+ ', '+'''o'''+')
UPDATE ' + #tblname + ' SET ' + #column_name+ ' = REPLACE('+#column_name + ', ' + '''ö'''+ ', '+'''o'''+')
UPDATE ' + #tblname + ' SET ' + #column_name+ ' = REPLACE('+#column_name + ', ' + '''ð'''+ ', '+'''o'''+')
exec (#sql)
end
go
EXEC dbo.specialcharacterreplacer #tblname = 'dirtyyyysource', #column_name ='select *from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = '#tblname''
how to make columns dynamic?
This was the central code to get your update statement for all columns of a given table dynamically. Be aware of TABLE_SCHEMA and the column's type. You might use some additions in the WHERE part... (in my example you'd try to replace the INT column as well...)
And you might have a look here: https://stackoverflow.com/a/32048968/5089204
There you'll find one of my former answers to a similar question and shows an approach how to create a function which will replace several special characters in one go.
CREATE TABLE dbo.TestTable(ID INT,Test1 VARCHAR(100), Test2 VARCHAR(100));
GO
declare #tblname varchar(1000)='TestTable';
declare #tblschema varchar(1000)='dbo';
DECLARE #SqlCmd VARCHAR(MAX)= 'UPDATE ' + #tblname + ' SET ' +
(
STUFF(
(
SELECT ',' + COLUMN_NAME + ' = REPLACE(' + COLUMN_NAME + ', ' + '''ó'', ''o'''+')'+ CHAR(10) --might need to use CHAR(13)+CHAR(10)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA=#tblschema AND TABLE_NAME = #tblname
FOR XML PATH('')
),1,1,'') + ';'
);
SELECT #SqlCmd;
GO
DROP TABLE dbo.TestTable;
GO
The result:
UPDATE TestTable SET ID = REPLACE(ID, 'ó', 'o')
,Test1 = REPLACE(Test1, 'ó', 'o')
,Test2 = REPLACE(Test2, 'ó', 'o')
;

Correct escaping for Where clause in dynamic procedure

I am pretty new to dynamic procedure and am trying to use something like the below in a Where clause there.
I have covered the rest of the procedure but have an issue with the below.
What would the correct escaping (quotes) look like in this case to cover the variable inputs? Also, I am not sure how to handle the part "R.#searchCategory" as here I need to add the "R.".
SQL Query :
WHERE ' + #selection + ' = ''closed'' AND (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'')
AND
(
(
' + #searchCategory + ' <> ''dateRec'' AND R.' + #searchCategory + ' LIKE ''%' + #searchTerm + '%''
)
OR
(
' + #searchCategory + ' = ''dateRec'' AND CAST(R.dateRec AS DATE) LIKE ''%' + #searchTerm + '%''
)
)
Make your life easier and use REPLACE and QUOTENAME
SET #sql = ...
'WHERE #selection = ''closed'' ' +
' AND (R.logStatus LIKE ''%Completed%'' ' +
' OR R.logStatus LIKE ''%Closed%'') ' +
' AND ( ' +
' (#searchCategoryText <> ''dateRec'' ' +
' AND R.#searchCategoryColumn LIKE ''%'' + #searchTerm + ''%'' ' +
' ) ' +
' OR ' +
' (#searchCategoryText = ''dateRec'' ' +
' AND CAST(R.dateRec AS DATE) LIKE ''%'' + #searchTerm + ''%'' ' +
' ) ' +
' ) ';
SET #sql = REPLACE(#sql, '#selection', QUOTENAME(#selection, ''''));
SET #sql = REPLACE(#sql, '#searchCategoryText', QUOTENAME(#searchcategory, ''''));
SET #sql = REPLACE(#sql, '#searchCategoryColumn', QUOTENAME(#searchcategory));
SET #sql = REPLACE(#sql, '#searchTerm', QUOTENAME(#searchTerm, ''''));
you have to separate out each whenever you add your variable like
WHERE ' + #selection +'= ''closed'' AND (R.logStatus LIKE ''%Completed%'' OR R.logStatus LIKE ''%Closed%'')
AND
(
(
' + #searchCategory +' <> ''dateRec'' AND R.' + #selection +'#searchCategory LIKE ''%' + ' + #searchTerm+'%''
)
OR
(
' + #searchCategory +'= ''dateRec'' AND CAST(R.dateRec AS DATE) = ' + #searchTerm +'
)
)
Still you got error then make direct query on which you make dynamic latter. i.e.
declare #searchCategory nvarchar(100) = 'abc'
select * from table where colname = #searchCategory
Run this and check the result properly come, now you just add into string here and your query ready to execute , simple.