SQL syntax error - sql

Im using Microsoft SQL Server which I think is T-SQL or ANSI SQL.
I want to search a database with a string. The matches that fit the begging of the string should come first then sort alphabetically.
I.e. If the table contains FOO, BAR and RAP
a search for the string 'R' should yield:
RAP
BAR
In that order.
Here is my attempt:
SELECT Name
FROM MyTable
WHERE (Name LIKE '%' + #name + '%')
ORDER BY (IF(Name LIKE #name + '%',1,0))
The error message is: "must declare scalar variable #name"

declare #name varchar(10)
set #name='R'
SELECT Name
FROM (select 'foo' as name union select 'RAP' union select 'BAR') MyTable
WHERE (Name LIKE '%' + #name + '%')
ORDER BY charindex(#name ,name)

.
DECLARE #name VARCHAR(MAX);
SET #name = 'foo';
SELECT Name
FROM MyTable
WHERE Name LIKE '%' + #name + '%'
ORDER BY CASE WHEN Name LIKE #name + '%' THEN 1 ELSE 0 END;

Other solutions seem to miss the "sort alphabetically" part:
DECLARE #Search VARCHAR(MAX)
SET #Search = 'R'
SELECT 0, Name
FROM MyTable
WHERE Name LIKE #Search + '%'
UNION ALL
SELECT 1, Name
FROM MyTable
WHERE Name like '%_' + #Search + '%'
ORDER BY 1, 2

Seems that you missed variable declaration:
DECALRE #name varchar(50) -- adjust type and length of variable
SET #name = 'phrase' -- for MSSQL 2008 you can do it in one line

Related

Incorrect syntax near '%'. inside dynamic SQL

I just found out about dynamic SQL but when I add a wildcard like '%', I get this error:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '%'.
Here is the query:
declare #Filter varchar(50)
set #Filter = '2%'
exec ('select * from dbo.tbl_coa where acct_code like ' + #Filter)
Anyway to fix this or is it impossible with dynamic SQL?
You need to enclose #Filter in quotes:
exec ('select * from dbo.tbl_coa where acct_code like ''' + #Filter + '''')
Demo on SQLFiddle
Note it is better to put the needed quotes into the query that you execute so that if you do something like
set #Filter = (SELECT ... )
The query will still work without having to do something like
set #Filter = concat('''', (select '2%'), '''')
You are concating the string incorrectly.
You should fix it to set #Filter = '''2%''', check the result below.
Demo on db<>fiddle
declare #Filter varchar(50)
set #Filter = '''2%'''
print ('select * from dbo.tbl_coa where acct_code like ' + #Filter)
// Output: select * from dbo.tbl_coa where acct_code like '2%'
Full Demo on db<>fiddle
create table tbl_coa(
acct_code varchar(10)
)
insert into tbl_coa
values('21'),('20'),('30')
declare #Filter varchar(50)
set #Filter = '''2%'''
exec ('select * from dbo.tbl_coa where acct_code like ' + #Filter)
Output
acct_code
21
20

is there a way to point at a specific column in a table through DECLARE in the WHERE clause?

I'm trying to create a searchstring that is a bit dynamic, and i'm trying to work around a large CASE WHEN scenario, but before i resort to doing a CASE WHEN i'm trying my luck here.
I've tried to execute it in string format "exec('code')" where it works, but then i get another issue with getdate() that i wont go into details with.
DECLARE #ProductLines nvarchar(50) = 'usr_author'
DECLARE #searchProductlines nvarchar(50) = 'hc'
SELECT TOP 20
Productid as Produktid,
usr_Author AS Author,
Header AS Title,
usr_Publisher AS Publisher,
CustomerId AS Customerid, FROM Products
WHERE
(#ProductLines Like '%' + #searchProductlines + '%')
I've scraped away all other code that isn't relevant here. What i want to do is declare #ProductLines as the column 'usr_author' so i in the WHERE clause can use #ProductLines as an dynamic column picker in a drop down menu later.
however, this doesnt work. if i write usr_Author instead of #ProductLines, i get the results i need but then it's a static solution, rather than a dynamic solution. what is best practice in this situation?
You can only replace constant values using parameters. You cannot replace identifiers -- including column names, table names, and so on.
You can do this dynamically as:
DECLARE #col nvarchar(50) = 'usr_author'
DECLARE #search nvarchar(50) = 'hc'
DECLARE #sql NVARCHAR(MAX);
SET #sql = '
SELECT TOP 20
Productid as Produktid,
usr_Author AS Author,
Header AS Title,
usr_Publisher AS Publisher,
CustomerId AS Customerid
FROM Products
WHERE #col Like ''%'' + #search + ''%''
';
SET #sql = REPLACE(#sql, '#col', #col);
EXEC sp_executesql #sql,
N'#search nvarchar(50)',
#search=#search;
By declaring this string, you're now comparing it as a string, not a column. Try a more dynamic SQL approach:
DECLARE #ProductLines nvarchar(50) = 'usr_author'
DECLARE #searchProductlines nvarchar(50) = 'hc'
DECLARE #sql1 nvarchar(500);
select #sql1 = 'SELECT TOP 20 Productid as Produktid, usr_Author AS Author, Header AS Title, usr_Publisher AS Publisher, CustomerId AS Customerid into #temptab1 FROM Products WHERE (' + #ProductLines + 'Like ''%' + #searchProductlines + '%'')'
exec( #sql1 )
select *
from #temptab1
Disclaimer: Not injection proof in the slightest, just a concept
create procedure dbo.uspSearch(
#searchProductId int = 0,
#searchAuthor nvarchar(50) = '',
#searchHeader nvarchar(50) = '',
#searchPublisher nvarchar(50) = '',
#searchCustomerId int = 0
) as
begin
set nocount on;
select top 20
Productid as Produktid,
usr_Author AS Author,
Header AS Title,
usr_Publisher AS Publisher,
CustomerId AS Customerid
from Products
where Productid = case when #searchProductId > 0 then #searchProductId else Productid end
and usr_Author like case when #searchAuthor <> '' then '%' + #searchAuthor + '%' else usr_Author end
and Header like case when #searchHeader <> '' then '%' + #searchHeader + '%' else Header end
and usr_Publisher like case when #searchPublisher <> '' then '%' + #searchPublisher + '%' else usr_Publisher end
and CustomerId = case when #searchCustomerId > 0 then #searchCustomerId else CustomerId end;
end;
go;
declare #searchProductId int = '1'
declare #searchAuthor nvarchar(50) = 'hc'
declare #searchHeader nvarchar(50) = 'test'
declare #searchPublisher nvarchar(50) = 'test'
declare #searchCustomerId int = '1';
exec dbo.uspSearch #searchProductId, #searchAuthor, #searchHeader, #searchPublisher, #searchCustomerId;
Besides the fact, that the whole approach has a certain smell, the best answer will be: Use dynamically created SQL (if you really have / want to stick to this). There are answers already...
Just for fun, there is a fully generic approach using XML like here:
I want to use a statement like this:
SELECT *
FROM sys.objects
WHERE [name]='sysrowsets';
...With generically defined parameters
DECLARE #ColumnName VARCHAR(100)='name';
DECLARE #SearchValue VARCHAR(100)='sysrowsets';
SELECT
(
SELECT *
FROM sys.objects
FOR XML PATH('o'),TYPE
).query('/*[*[local-name()=sql:variable("#ColumnName") and text()[1]=sql:variable("#SearchValue")]]')
The result is the same row as above, but as XML (which can be transformed into a tabular set again).
<o>
<name>sysrowsets</name>
<object_id>5</object_id>
<schema_id>4</schema_id>
<parent_object_id>0</parent_object_id>
<type>S </type>
<type_desc>SYSTEM_TABLE</type_desc>
<create_date>2012-09-02T23:08:12.370</create_date>
<modify_date>2012-09-02T23:08:15.340</modify_date>
<is_ms_shipped>1</is_ms_shipped>
<is_published>0</is_published>
<is_schema_published>0</is_schema_published>
</o>
As mentioned above, this is not the recommended approach, it will be very slow. I just felt the need to say something against the impossible statements :-)
UPDATE: Tabular result and still generic...
You can use something like this, just to articulate a predicate against a unique value (in this case object_id)
SELECT o.*
FROM sys.objects o
WHERE o.object_id=
(
SELECT *
FROM sys.objects
FOR XML PATH('o'),TYPE
).query('/*[*[local-name()=sql:variable("#ColumnName")
and text()[1]=sql:variable("#SearchValue")]]')
.value('(/o/object_id/text())[1]','bigint');

How to use dynamic filter in sql procedure?

I want use Dynamic filter in sql Procedure
,like this
Select * from Table Where #Filter
Can I Write Like That Or Was Diffrent Ways to Use
I must Use this Syntax because I Want Remove Select in Application and Use Procedure.
CREATE PROCEDURE SP_DynamicFilter
(
-- Optional Filters for Dynamic Search
#COLUMN1 INT = NULL,
#COLUMN2 NVARCHAR(50) = NULL,
#COLUMN3 NVARCHAR(50) = NULL,
#COLUMN4 NVARCHAR(50) = NULL
)
AS
BEGIN
SELECT *
FROM TableName
WHERE
(#COLUMN1 IS NULL OR Column1 = #COLUMN1)
AND (#COLUMN2 IS NULL OR Column2 LIKE '%' + #COLUMN2 + '%')
AND (#COLUMN3 IS NULL OR Column3 LIKE '%' + #COLUMN3 + '%')
AND (#COLUMN4 IS NULL OR Column4 LIKE '%' + #COLUMN4 + '%')
END
CREATE PROCEDURE spProcedurName
#Filter datatype
AS
BEGIN
SELECT *
FROM Table
WHERE columnName= #Filter
END
You can paramater like that.
#Query='
Select * from table' + #Filter
exec #Query

Queries using LIKE wildcards in sql server

I want to perform a small SQL server search in my ASP.NET web project. My database is not big so I think it's better not to use full-text-search.
I want to perform a simple search like this:
select * from mytable where columnA LIKE '%something%'
I can use = in the following way:
select * from mytable where columnA='"+myVariable+"'
but how can I use a variable instead of %something% in the LIKE phrase?
Is this correct:
LIKE '"+%myVariable%+"'?
Use:
where columnA LIKE '%' + myVariable + '%'
WHERE
columnName LIKE '%' + myVarCharVariable +'%'
Try this query:
select * from tablename where colname like '%' + #varname + '%'
Hope it helps.
I just tried this and found you can do as below:
SELECT * FROM whatever WHERE column LIKE '%'+#var+'%'
DECLARE #myVariable varchar(MAX)
SET #myVariable = 'WhatYouAreLookingFor'
SELECT * FROM mytable
WHERE columnA LIKE '%' + #myVariable + '%'
In case someone else stumbles into this post like I did. On SSMS 2012 with a SQL 2012 Server back end I was able to use code as follows without issues.
Declare #MyVariable
Set #MyVariable = '%DesiredString%'
Select *
From Table_A
Where Field_A like #MyVariable
Then each time you want to change the Desired String just change it at the Set statement.
I know this post was made prior to 2012 that is why I am mentioning it in case someone with a newer setup looks up this post.
Well you could do something like:
var query = "SELECT * FROM MyTable WHERE columnA LIKE '%" + myVariable + "%'";
If you are worried about sql injection, try something like this instead. It's more complex, but it works and should satisfy security requirements. Let's say someone passed a value into your stored procedure using a parameter called "#searchstring".
DECLARE #searchString nvarchar(100) = 'test',
#SQL nvarchar(max),
#foundSearchHit bit,
#paramdef nvarchar(max) = '#foundSearchHit bit OUTPUT'
SET #searchstring = '%' + #searchString + '%'
SET #SQL = '
SELECT TOP 1 #foundSearchHit = 1
FROM sys.databases WHERE [name] like ' +
QUOTENAME(#searchString,'''')
EXEC sp_executeSQL #SQL, #paramdef, #foundSearchHit = #foundSearchHit OUTPUT
SELECT #foundSearchHit
That should do the trick.

How to adjust SQL LIKE function?

I want to make this kind of query:
create procedure something
#name varchar(13)
as
begin
select *
from WORKER
where NAME LIKE "%#name%"
end
For input #name=ho, I want output every row that contains NAME which sounds ho,
for example HOuse, soHO, broHOw...
Select * from WORKER where Name Like '%' + #name + '%'
create procedure something
#name varchar(13)
as
begin
select * from WORKER
where NAME LIKE '%' + #name + '%'
end