Comparing string with an UNIQUEIDENTIFIER? - sql

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.

Related

Adding an apostrophe into a dynamic 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);

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.

How do I script my table to generate INSERT INTO commands?

I have a lookup table with about 10 records, I know I can script the structure to a text file, but how can I script the data to insert into commands?
Ten records, and it's urgent?
Just type it out manually. Should be pretty easy to cut-n-paste.
Assuming SQL Server...
SQL Management Studio will generate an insert script. Right-click your database and select Tasks-Export data
This depends pretty much on the tools you are using...
The quick and dirty way is to run a select into a string and tell sql enterprise manager to give you text (not grid) as the output
SELECT 'INSERT INTO TABLES (fields here) VALUES (' + field1 + ', '....
Do something like this:
select "insert into my_targ_table(my_field_1, my_field_2, ..., my_field_n) values(" || x.my_field_1_col || ", " || x.my_field_2_col || ");"
from my_source_table x
Then just run the script you've generated.
This code works with all tables
DECLARE #TblName varchar(128)
DECLARE #WhereClause varchar(255)
DECLARE #cmd1 varchar(7000)
DECLARE #cmd2 varchar(7000)
SET #TblName = '<tablename>' --Name of your table
SET #WhereClause = ' ' --where clause ex columnA = 1
SET #cmd1 = 'SELECT '' INSERT INTO ' + #TblName + ' ( '
SET #cmd2 = ' + '' VALUES ( '' + '
create table #tableDef (id int identity (1,1), ColType int, ColName varchar(128))
--Fetch column names and datatypes
insert #tableDef (ColType, ColName)
select case when DATA_TYPE like '%char%' then 1
when DATA_TYPE like '%datetime%' then 2
else 0 end ,
COLUMN_NAME
from information_schema.columns
where TABLE_NAME = #TblName
order by ORDINAL_POSITION
SELECT #cmd1 = #cmd1 + ColName + ',',
#cmd2 = #cmd2
+ ' CASE WHEN ' + ColName + ' IS NULL '
+ ' THEN ''NULL'' '
+ ' ELSE '
+ case ColType
when 1 then ''''''''' + ' + ColName + ' + '''''''''
when 2 then ''''''''' + ' + 'CONVERT(VARCHAR(20),' + ColName + ')' + ' + '''''''''
else 'CONVERT(VARCHAR(20),' + ColName + ')' end
+ ' END + '','' + '
from #tableDef
order by id
select #cmd1 = left(#cmd1,len(#cmd1)-1) + ' ) '' '
select #cmd2 = left(#cmd2,len(#cmd2)-8) + '+'')'' FROM ' + #tblName + #WhereClause
select '/*' + #cmd1 + #cmd2 + '*/'
exec (#cmd1 + #cmd2)
drop table #tableDef