How to make a quote insensitive search in SQL Server?
For example those city names should be considered equal:
Muggio'
Muggio
I know how to make a simple accent-insensitive search but I found nothing about quote-insensitive searches.
There is a collation or a tidy function I can use? Or I should preprocess the city name in my code?
DECLARE #t TABLE(v VARCHAR(20))
INSERT INTO #t VALUES
('abc'''),
('abc')
DECLARE #f VARCHAR(20) = 'abc'''
SELECT * FROM #t WHERE v LIKE '%' + REPLACE(#f, '''', '') + '%'
Output:
abc'
abc
In SQL Server, what is the best way to identify all rows in a table where a certain column contains the TAB character (CHAR(9))
Is it as simple as
SELECT * FROM MyTable WHERE Field1 LIKE '%' + CHAR(9) + '%'
RTRIM CHAR columns. like this:
SELECT *
FROM MyTable
WHERE (RTRIM(Field1) LIKE '%' + CHAR(9) + '%')
Previous query fails, with: "missing expression" message,
In Oracle, this is the correct syntax
select *
from MyTable
where Field1 '%' || CHR(9) || '%';
Other solution can be:
Select *
from MyTable
where instr(Field1, CHR(9)) <> 0;
Cheers!
I'm trying to pass an NVARCHAR parameter to my store procedure. The stored procedure is supposed to find all suppliers that match the specified criteria. The only problem I have is that I am trying to pass criteria that contains Hebrew.
ALTER PROCEDURE [dbo].[FindSupplier]
-- Add the parameters for the stored procedure here
#search_criteria nvarchar(100) = ''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #hebrew as bit = 0
IF #search_criteria LIKE '%[אבגדהוזחטיחכךילמנפףערקשת]%'
BEGIN
SET #hebrew = 1
END
IF #hebrew = 0
BEGIN
SELECT comn020.t_suno 'Supplier Code'
, hebcom020.t_nama 'Supplier Name1'
, hebcom020.t_namb 'Supplier Name2'
FROM com020 WITH (NOLOCK)
INNER JOIN hebcom020 WITH (NOLOCK)
ON hebcom020.t_suno = com020.t_suno
WHERE (LTRIM(RTRIM(com020.t_suno)) LIKE N'%' + #search_criteria + '%')
OR (SOUNDEX(LTRIM(RTRIM(com020.t_suno))) LIKE N'%' + SOUNDEX(#search_criteria) + '%')
OR (LTRIM(RTRIM(hebcom020.t_nama)) LIKE N'%' + #search_criteria + '%')
OR (SOUNDEX(LTRIM(RTRIM(hebcom020.t_nama))) LIKE N'%' + SOUNDEX(#search_criteria) + '%')
OR (LTRIM(RTRIM(hebcom020.t_namb)) LIKE N'%' + #search_criteria + '%')
OR (SOUNDEX(LTRIM(RTRIM(hebcom020.t_namb))) LIKE N'%' + SOUNDEX(#search_criteria) + '%')
END
ELSE /* hebrew */
BEGIN
SELECT com020.t_suno 'Supplier Code'
, hebcom020.t_nama 'Supplier Name1'
, hebcom020.t_namb 'Supplier Name2'
FROM com020 WITH (NOLOCK)
INNER hebcom020 WITH (NOLOCK)
ON hebcom020.t_suno = com020.t_suno
WHERE hebcom020.t_nama Collate Hebrew_CI_AI LIKE N'%' + #search_criteria + '%' Collate Hebrew_CI_AI
OR (LTRIM(RTRIM(hebcom020.t_namb)) LIKE N'%' + #search_criteria + '%')
END
END
When I'm trying to pass something like exec FindSupplier 'ב' the SQL server recognizes char 'ב' as '?'
Your help will be highly appreciated
UPD: exec FindSupplier N'ב' worked
UPD2: In Visual Studio need to run sp with following string
="exec FindSupplier N'" & Parameters!search_criteria.Value & "'"
The problem is simply that the string literal used in the LIKE condition is not prefixed with an N to indicate that it is a Unicode string. The following example shows the difference:
DECLARE #search_criteria NVARCHAR(100) = N'ב';
IF #search_criteria LIKE '%[אבגדהוזחטיחכךילמנפףערקשת]%'
BEGIN
PRINT 'WithOUT "N"-prefix';
END;
IF #search_criteria LIKE N'%[אבגדהוזחטיחכךילמנפףערקשת]%'
BEGIN
PRINT 'WITH "N"-prefix';
END;
Returns:
WITH "N"-prefix
To more easily understand why there is this difference in behavior, consider the following:
-- when the DB has a default collation of Latin1_General_100_CI_AS_SC (code page 1252)
SELECT '%[אבגדהוזחטיחכךילמנפףערקשת]%'
-- %[????????????????????????]%
-- when the DB has a default collation of Hebrew_100_CI_AS_SC (code page 1255)
SELECT '%[אבגדהוזחטיחכךילמנפףערקשת]%'
-- %[אבגדהוזחטיחכךילמנפףערקשת]%
The string literals are parsed in the code page used by the default collation of the current database. If the code page can support these characters, then not prefixing with the upper-case "N" will work. But, if those characters do not exist in that code page, then they are converted into "?"s.
I have a search functionality in my application which searches a string value of a particular column. The search text is passed as a parameter to the procedure. Now I have to search in another column which is an integer from another table. The input param is one but now I have to search in both the columns and return the result according to that.
//Query:
#SearchText VARCHAR(8000) = ''
SELECT DISTINCT Id, TransactionId, wfdFieldValue
where (wfdFieldValue LIKE '%' + #SearchText + '%' OR #SearchText = '')
In the above query I have to include the TransactionId in the where condition. So that if the user searched using the TransactionId or the Fieldvalue the query will return the result.
Note: The TransactionId is an Integer DataType.
If I understand you correctly, you'll want a hit in either column to make the row show up in search results. In that case, you'll need a simple OR;
SELECT DISTINCT Id, TransactionId, wfdFieldValue
FROM bop
WHERE #SearchText='' OR
wfdFieldValue LIKE '%' + #SearchText + '%' OR
TransactionId LIKE '%' + #SearchText + '%'
(You can just use LIKE on the integer column right away without manually converting.)
Of note though, this kind of wildcard search with a leading % does not use indexes in an optimal way, performance of this query will most likely not be great as the table grows.
SELECT DISTINCT Id, TransactionId, wfdFieldValue
where wfdFieldValue LIKE '%' + #SearchText + '%'
OR #SearchText = ''
OR CAST(TransactionId AS VARCHAR(50)) LIKE '%' + #SearchText + '%'
A cast should solve it, but I would first think about possible design improvements.
Is there a method to use contain rather than equal in case statement?
For example, I am checking a database table has an entry
lactulose, Lasix (furosemide), oxazepam, propranolol, rabeprazole, sertraline,
Can I use
CASE When dbo.Table.Column = 'lactulose' Then 'BP Medication' ELSE '' END AS 'BP Medication'
This did not work.
CASE WHEN ', ' + dbo.Table.Column +',' LIKE '%, lactulose,%'
THEN 'BP Medication' ELSE '' END AS [BP Medication]
The leading ', ' and trailing ',' are added so that you can handle the match regardless of where it is in the string (first entry, last entry, or anywhere in between).
That said, why are you storing data you want to search on as a comma-separated string? This violates all kinds of forms and best practices. You should consider normalizing your schema.
In addition: don't use 'single quotes' as identifier delimiters; this syntax is deprecated. Use [square brackets] (preferred) or "double quotes" if you must. See "string literals as column aliases" here: http://msdn.microsoft.com/en-us/library/bb510662%28SQL.100%29.aspx
EDIT If you have multiple values, you can do this (you can't short-hand this with the other CASE syntax variant or by using something like IN()):
CASE
WHEN ', ' + dbo.Table.Column +',' LIKE '%, lactulose,%'
WHEN ', ' + dbo.Table.Column +',' LIKE '%, amlodipine,%'
THEN 'BP Medication' ELSE '' END AS [BP Medication]
If you have more values, it might be worthwhile to use a split function, e.g.
USE tempdb;
GO
CREATE FUNCTION dbo.SplitStrings(#List NVARCHAR(MAX))
RETURNS TABLE
AS
RETURN ( SELECT DISTINCT Item FROM
( SELECT Item = x.i.value('(./text())[1]', 'nvarchar(max)')
FROM ( SELECT [XML] = CONVERT(XML, '<i>'
+ REPLACE(#List,',', '</i><i>') + '</i>').query('.')
) AS a CROSS APPLY [XML].nodes('i') AS x(i) ) AS y
WHERE Item IS NOT NULL
);
GO
CREATE TABLE dbo.[Table](ID INT, [Column] VARCHAR(255));
GO
INSERT dbo.[Table] VALUES
(1,'lactulose, Lasix (furosemide), oxazepam, propranolol, rabeprazole, sertraline,'),
(2,'lactulite, Lasix (furosemide), lactulose, propranolol, rabeprazole, sertraline,'),
(3,'lactulite, Lasix (furosemide), oxazepam, propranolol, rabeprazole, sertraline,'),
(4,'lactulite, Lasix (furosemide), lactulose, amlodipine, rabeprazole, sertraline,');
SELECT t.ID
FROM dbo.[Table] AS t
INNER JOIN dbo.SplitStrings('lactulose,amlodipine') AS s
ON ', ' + t.[Column] + ',' LIKE '%, ' + s.Item + ',%'
GROUP BY t.ID;
GO
Results:
ID
----
1
2
4
Pseudo code, something like:
CASE
When CHARINDEX('lactulose', dbo.Table.Column) > 0 Then 'BP Medication'
ELSE ''
END AS 'Medication Type'
This does not care where the keyword is found in the list and avoids depending on formatting of spaces and commas.