Cast a #param in SQL Server stored procedure? - sql

I have a SQL Server stored procedure that takes a #columnName parameter, and I am using it in building the query:
AND #columnName LIKE '%' + #userInput + '%'
If I replace the #columnName with a static value it works, like this:
AND userName LIKE '%' + #userInput + '%'
I believe this is because the #columnName is treated as string, because when running the stored procedure, it is being passed as string like that:
EXEC app.findUsers 'UserName', 'sa'
Is it possible to do it without using a dynamic query string?

You need to use SQL Dynamic to do this.
DECLARE #SQL VARCHAR(8000)
SET #SQL = 'SELECT Column FROM Table WHERE [' + #columnName + '] LIKE ''%' + #userInput + '%'''
PRINT #SQL
EXEC(#SQL)

Related

MSSQL searching unicode characthers using LIKE operator

I have a stored procedure where I pass a parameter that is unicode and looks like following:
מוכר שמן קוקוס בכחל מיני ואריציות
Now the problem here is that when I enter something in my form to search for this value in m table like fllowing:
IF LEN(#SearchValue) > 0
BEGIN
SET #WhereQuery = #WhereQuery +
'(Type=' + CAST(#type AS NVARCHAR(10)) + ' and UserId=' + CAST(#userid AS NVARCHAR(10)) + ') and'
+ '(convert(nvarchar(max),SentWord) like ''%' + #SearchValue + '%'' or '
+ 'convert(nvarchar(max),Comment) like ''%' + #SearchValue + '%'')'
END
Where #SearchValue is defined as nvarchar(200) in SQL server and table columns that hold the specific value are:
SentWord and Comment and both are unicode defined as nvarchar(600).
What am I doing wrong here? Why cant MSSQL search by hebrew characthers ? Can someone help me out?
As #Jeroen stated , possible fix would be to add N after LIKE operator like following:
IF LEN(#SearchValue) > 0
BEGIN
SET #WhereQuery = #WhereQuery +
'(Type=' + CAST(#type AS NVARCHAR(10)) + ' and UserId=' + CAST(#userid AS NVARCHAR(10)) + ') and'
+ '(convert(nvarchar(max),SentWord) like N''%' + #SearchValue + '%'' or '
+ 'convert(nvarchar(max),Comment) like N''%' + #SearchValue + '%'')'
END
But it still doesn't works...
Don't concatenate your strings like that!!! It's an injection nightmare!
Next, your declaring your literal unicode string as a varchar, not an nvarchar. if you try SELECT 'מוכר שמן קוקוס בכחל מיני ואריציות'; notice the return value is '???? ??? ????? ???? ???? ????????'. You need to prefix it with N, thus: SELECT N'מוכר שמן קוקוס בכחל מיני ואריציות';.
Now, the important is parametrising that SQL... Unfortunately I don't have enough of the SQL to actually do this in full for you, so here's a different example instead:
DECLARE #SQL nvarchar(MAX);
DECLARE #string nvarchar(20) = N'Test';
SET #SQL = 'SELECT * FROM MyTable WHERE MyColumn = #dString;'; --Notice the variable in the dynamic SQL
PRINT #SQL;
EXEC sp_executesql #SQL, N'dString nvarchar(20)',#dString = #string; --Notice the variable declaration and assignment.

SQL dynamic query with empty check

SET #sql = 'Declare ChildTableMigrator CURSOR FOR select ['+#FieldName+'] , ['+#FieldName+'Alias] from [' + #SourceTable + '].[dbo].[Port] where [' + #SourceTable + '].[dbo].[Port].[' + #FieldName + '] IS NOT NULL AND [' + #SourceTable + '].[dbo].[Port].[' + #FieldName + '] !='''
PRINT #sql
exec sp_executesql #sql
Hi,
How to check NULL and EMPTY with a sql dynamic query ? , as per EMPTY check
#FieldName + '] !='''
it thorws the error
Unclosed quotation mark after the character string ''.
How to overcome this ?
You need to replace
#FieldName + '] !='''
with
#FieldName + '] !='''''.
Quotation marks need to be escaped when used inside a string. In your original statement, you escaped only one quotation mark resulting in a string with only one quotation mark.
But you could do even better by using parametrized sql
#FieldName + '] !=#EmptyField
exec sp_executesql #sql, N'#EmptyField VARCHAR(32)', ''
use if() judge .for example
set #sql="Declare ChildTableMigrator CURSOR FOR select "
if(#FieldName!=null)
begin
set #sql=#sql+"['"+#FieldName+"']";
end
.....
PRINT #sql
exec sp_executesql #sql

How to use LIKE in a t-sql dynamic statement in a stored procedure?

I'm trying to use the LIKE keyword with the % wildcards wrapping the parameter, but I'm not sure how to get the % characters into the statement without breaking it. Right now I have:
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE %#search%'
I get a SqlException error in my .net app that says "Incorrect syntax near '#search' when I run it. The error goes away if I remove the % characters surrounding the #search parameter.
The % characters have to be in the search string...
SET #search = '%' + #search + '%'
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE #search'
Note that the following would also work, but introduces potential for a SQL injection vulnerability...
-- DON'T do this!
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE ''%' + #search + '%'''
SET #SQLQuery = 'SELECT * from [tblApps] WHERE [firstName] LIKE ''%'' + #search + ''%'''
exec sp_executesql #query=#SQLQuery, #params=N'#search nvarchar(96)', #search=#search
The only difference from this version as compared to the others is that the dynamic execution of the sql is in fact parameterized which mitigates sql injection a bit.
SET #search = '%' + #search
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE ' + #search + '%'
This worked for me!
SET #search = '''%' + #search + '%'''
SET #SQLQuery = 'SELECT * FROM [tblApps] WHERE [firstName] LIKE' + #search
EXEC sp_executesql #SQLQuery
declare #Cmd nvarchar(2000)
declare #eName varchar(10)
set #eName='a'
set #Cmd= 'select * from customer1 where name LIKE '''+'%' +#eName+ '%' + ''''
print #Cmd
EXECUTE sp_executesql #Cmd

SQL Server: How to perform Rtrim on all varchar columns of a table

I have over 30 columns in my table (sql server 2008). Columns type are varchar(x). I know that in every column there is two extra spaces at the end of column value. How to use rtrim function for all columns and save this modification into this existing table?
Edit: is there a way to do it using stored procedure or cursor where I don't have to manually declare all columns?
For a generic approach, you can use a script like this to generate the statement for you, for a given table (useful if you have many columns!):
DECLARE #SQL VARCHAR(MAX)
DECLARE #TableName NVARCHAR(128)
SET #TableName = 'YourTableName'
SELECT #SQL = COALESCE(#SQL + ',[', '[') +
COLUMN_NAME + ']=RTRIM([' + COLUMN_NAME + '])'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #TableName
AND DATA_TYPE = 'varchar'
SET #SQL = 'UPDATE [' + #TableName + '] SET ' + #SQL
PRINT #SQL
That will just print the SQL statement out. You can either then copy + run the statement, or just EXECUTE(#SQL). This is untested, so just try it out on a test table first :)
UPDATE xxx
SET col1 = RTRIM(col1),
col2 = RTRIM(col2),
col3 = RTRIM(col3),
...
We can have stored procedure to trim specific table under specific schema. If we have different schema names other than default dbo schema, it is better to use this SP by passing schema name and table name. This performs both LTRIM and RTRIM. This SP would check char, nchar, varchar, nvarchar columns.
CREATE PROCEDURE [dbo].[TrimAllColumnsOfTable] #SchemaName Varchar(100),#TableName Varchar(100)
AS
BEGIN
DECLARE #SQL VARCHAR(MAX)
SELECT #SQL = COALESCE(#SQL + ',[', '[') +
COLUMN_NAME + ']=LTRIM(RTRIM([' + COLUMN_NAME + ']))'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = #SchemaName AND TABLE_NAME = #TableName AND DATA_TYPE Like '%char%'
SET #SQL = 'UPDATE [' + #SchemaName + '].[' + #TableName + '] SET ' + #SQL
EXEC (#SQL)
END
USAGE: [TrimAllColumnsOfTable] 'SchemaName','TableName'
It is perfect... But remember to put also the where clause:
COLUMNPROPERTY(OBJECT_ID(TABLE_SCHEMA+'.'+TABLE_NAME),COLUMN_NAME,'IsComputed') = 0
Ohterwise you will get an error if the table has a computed column of "%char%" type!
The accepted answer works well. I ran into an issue with a temp table being named the same name. You can add
and TABLE_SCHEMA = 'dbo'
And that will get rid of collision on table names.

LIKE in dynamic queries

I want to use the like keyword in a dynamic parameterized query. I want to protect my query from SQL injections so I don't want to pass the value, instead I want to pass my criteria while executing the query,
Is there a way I can do this?
SELECT
ComposeMail.ID,
ComposeMail.DateTime,
ComposeMail.Subject,
ComposeMail.CreatedBy,
ComposeMail.ReceiverStatus,
Users.Name,
ROW_NUMBER() OVER(ORDER BY '+ #p_SortExpression +') AS Indexing
FROM
ComposeMail
INNER JOIN
Users
ON
ComposeMail.CreatedBy = Users.ID
WHERE
(ToReceipientID=#p)
AND (
ReceiverStatus=3
OR ReceiverStatus=4
)
AND (
(Subject Like ''%' + #p3 + '%'')
OR (Body Like ''%' + #p3 + '%'')
OR (Name Like ''%' + #p3 + '%'')
)
This is my dynamic query string. I don't want to pass the value here.
To prevent against injection in a dynamic query you always want to do something like this (instead of doing ' + #var + ' in your example)
DECLARE #query nvarchar(2000),
#paramList nvarchar(2000)
SET #query = 'SELECT * FROM dbo.Orders WHERE custLastName LIKE ''%'' + #custLastName + ''%'''
SET #paramList = '#custLastName varchar(30)'
EXEC SP_EXECUTESQL #query, #paramList, #custLastName
edit: example updated to use LIKE
WHERE (LastName LIKE N'%' + #Family + N'%') OR
(RegNo LIKE N'%' + #Codemeli + N'%')
like in dynamic sql query