LIKE operator and % wildcard when string contains underscore - sql

I have a table in SQL Server that stores codes. Depending on the nomenclature, some begin with 'DB_' and others with 'DBL_'. I need a way to filter the ones that start with 'DB_', since when I try to do it, it returns all the results.
CREATE TABLE CODES(Id integer PRIMARY KEY, Name Varchar(20));
INSERT INTO CODES VALUES(1,'DBL_85_RC001');
INSERT INTO CODES VALUES(2,'DBL_85_RC002');
INSERT INTO CODES VALUES(3,'DBL_85_RC003');
INSERT INTO CODES VALUES(4,'DB_20_SE_RC010');
INSERT INTO CODES VALUES(5,'DB_20_SE_RC011');
SELECT * FROM CODES where Name like 'DB_%';
The result that returns:
1|DBL_85_RC001
2|DBL_85_RC002
3|DBL_85_RC003
4|DB_20_SE_RC010
5|DB_20_SE_RC011
Expected result:
4|DB_20_SE_RC010
5|DB_20_SE_RC011

_ is a wildcard for a single character in a LIKE expression. Thus both 'DB_' and 'DBL' are LIKE 'DB_'. If you want a literal underscore you need to put it in brackets ([]):
SELECT *
FROM CODES
WHERE [Name] LIKE 'DB[_]%';

The underscore is a wildcard in SQL Server. You can escape it:
where name like 'DB$_%' escape '$'
You could also use left():
where left(name, 3) = 'DB_'
However, this is not index- and optimizer friendly.

Related

Include wildcards in sql server in the values themselves - not when searching with LIKE

Is there a way to include wildcards in sql server in the values themselves - not when searching with LIKE?
I have a database that users search on. They search for model numbers that contain different wildcard characters but do not know that these wildcard characters exist.
For example, a model number may be 123*abc in the database, but the user will search for 1234abc because that's what they see for their model number on their unit at home.
I'm looking for a way to allow users to search without knowledge of wildcards but have a systematic way to include model numbers with wildcard characters in the database.
What you could do is add a PERSISTED computed column to your table with valid pattern expression for SQL Server. You stated that * should be any letter or numerical character, and comma delimited values in parenthesis can be any one of those characters. Provided that commas don't appear in your main data, nor parenthesis, then this should work:
USE Sandbox;
GO
CREATE TABLE SomeTable (SomeString varchar(15));
GO
INSERT INTO SomeTable
VALUES('123abc'),
('abc*987'),
('def(q,p,r,1)555');
GO
ALTER TABLE SomeTable ADD SomeString_Exp AS REPLACE(REPLACE(REPLACE(REPLACE(SomeString,'*','[0-9A-z]'),'(','['),')',']'),',','') PERSISTED; --What you're interested in
SELECT *
FROM SomeTable;
GO
DECLARE #String varchar(15) = 'defp555';
SELECT *
FROM SomeTable
WHERE #String LIKE SomeString_Exp; --And how to search
GO
DROP TABLE SomeTable;
If * is any character, and noy any alphanumeric then you could shorten the whole thing to (and provided your on SQL Server 2017):
ALTER TABLE SomeTable ADD SomeString_Exp AS REPLACE(TRANSLATE(SomeString,'*()','_[]'),',','') PERSISTED;
I'm thinking either:
where #model_number like replace(model_number, '*', '%')
or
where #model_number like replace(model_number, '*', '_')
Depending on whether '*' means any string (first example) or exactly one character (second example).

Escaping wildcards in LIKE

How do I escape wildcards (_ and %) when using a SQL LIKE operator in Oracle?
I came to a silly issue today. I need to search for the presence of an underscore _ on a varchar column using LIKE. It doesn't work -- as expected -- since underscores are wildcards according to SQL. Here's my (simpified) code:
create table property (
name varchar(20),
value varchar(50)
);
insert into property (name, value) values ('port', '8120');
insert into property (name, value) values ('max_width', '90');
insert into property (name, value) values ('taxrate%', '5.20');
I tried the following queries in PostgreSQL and they return the rows I want:
select * from property where name like '%\_%'; -- should return: max_width
select * from property where name like '%\%%'; -- should return: taxrate%
Unfortunately it doesn't work in Oracle 12c. Is there a "standard" way of escaping wildcards? Or at least something that works in Oracle?
You can use the escape syntax
You can include the actual characters % or _ in the pattern by using the ESCAPE clause, which identifies the escape character. If the escape character precedes the character % or _ in the pattern, then Oracle interprets this character literally in the pattern rather than as a special pattern-matching character.
So you can do:
select * from property where name like '%\_%' escape '\';
NAME VALUE
-------------------- --------------------------------------------------
max_width 90
select * from property where name like '%\%%' escape '\';
NAME VALUE
-------------------- --------------------------------------------------
taxrate% 5.20

How to check a database column for special sign

I want to check a column for a special sign with regular expression, but not all special sign. I want all sign that are not letter, number and not ,+.-& (blank) .I try this
where column like '%[^((a-z)(A-Z)(0-9)(,\+\.\-)(\&)( ))]%'
same like this
where column like '%[^0-9a-zA-Z ,\-+\.\& ]%'
But if I try this Statement, I get strings with - and speziell blank.
result1: 't-est regex'
result2: ' TestJ. '
Have you any idea why?
Thx for the help.
The LIKE operator isn't exactly using the regex syntax.
It's way more simplified.
But some things are still possible.
This LIKE would get what you want:
where [column] like '%[^A-Za-z0-9 &.,+-]%'
Note that the class negation ^ does work.
And it's best to put a - at the end of a class. So it's not mistaken to be used for a range of characters.
There's no concept for capture groups in a LIKE, so the ( and ) were removed.
But if you also want the LIKE to ignore the brackets, just add them to the character class.
(even in regex you don't have capture groups inside a character class anyway)
The LIKE operation is case-insensitive when the COLLATION of the character field is case-insensitive.
Which seems to be the default on most databases.
So most of the times, a LIKE '%[A-Z]%' and LIKE '%[A-Za-z]%' would behave the same.
Example snippet:
-- using a Case-Sensitive collation for the varchar.
declare #T table (id int identity(1,1), col varchar(30) COLLATE Latin1_General_CS_AS);
insert into #T (col) values
('abc123'),
('ABC & 123'),
('abc123 &.,+-'),
('abc-123 #');
select * from #T where col like '%[^A-Za-z0-9 &.,+-]%';
Returns:
id col
-- ---------
4 abc-123 #

SQL Validating a string variable

Using SQL Scripts, I need to validate Comma Separate value. How should i validate the String Variable ?
Validation should be both Right / Left Trim for each value and there should not be any special characters such as Comma or Period for the last value.
create table #test
(col varchar(100))
insert into #test values
('1,2'),
('1,2,'),
('1,'),
('1,2,3,4,5')
select * from #test
In the above query, for the second value - Expected Result is 1,2
In the above query, for the Third value - Expected Result is 1
You can update your table to fix "offensive" values.
update #test
set col = substring(col, 1, len(col) - 1)
where col not like '%[0-9]'
This will remove last character where value doesn't end by a digit.
You can use a check constraint. You seem to want something like this:
alter table t add constraint chk_name as
(name like '%,%' and
name not like '%,%,%' and
name not like '%[^a-zA-Z,]%'
)
SQL Server doesn't have support for regular expressions. This implements the rules:
Name has to have a comma
Name does not have two commas
Name consists only of alphabetic characters and a comma
You may find that you need slightly more flexibility, but this handles the cases in your question.

Why does using an Underscore character in a LIKE filter give me all the results?

I wrote the below SQL query with a LIKE condition:
SELECT * FROM Manager
WHERE managerid LIKE '_%'
AND managername LIKE '%_%'
In the LIKE I want to search for any underscores %_%, but I know that my columns' data has no underscore characters.
Why does the query give me all the records from the table?
Sample data:
create table Manager(
id int
,managerid varchar(3)
,managername varchar(50)
);
insert into Manager(id,managerid,managername)values(1,'A1','Mangesh');
insert into Manager(id,managerid,managername)values(2,'A2','Sagar');
insert into Manager(id,managerid,managername)values(3,'C3','Ahmad');
insert into Manager(id,managerid,managername)values(4,'A4','Mango');
insert into Manager(id,managerid,managername)values(5,'B5','Sandesh');
Sql-Fiddle
Modify your WHERE condition like this:
WHERE mycolumn LIKE '%\_%' ESCAPE '\'
This is one of the ways in which Oracle supports escape characters. Here you define the escape character with the escape keyword. For details see this link on Oracle Docs.
The '_' and '%' are wildcards in a LIKE operated statement in SQL.
The _ character looks for a presence of (any) one single character. If you search by columnName LIKE '_abc', it will give you result with rows having 'aabc', 'xabc', '1abc', '#abc' but NOT 'abc', 'abcc', 'xabcd' and so on.
The '%' character is used for matching 0 or more number of characters. That means, if you search by columnName LIKE '%abc', it will give you result with having 'abc', 'aabc', 'xyzabc' and so on, but no 'xyzabcd', 'xabcdd' and any other string that does not end with 'abc'.
In your case you have searched by '%_%'. This will give all the rows with that column having one or more characters, that means any characters, as its value. This is why you are getting all the rows even though there is no _ in your column values.
The underscore is the wildcard in a LIKE query for one arbitrary character.
Hence LIKE %_% means "give me all records with at least one arbitrary character in this column".
You have to escape the wildcard character, in sql-server with [] around:
SELECT m.*
FROM Manager m
WHERE m.managerid LIKE '[_]%'
AND m.managername LIKE '%[_]%'
See: LIKE (Transact-SQL)
Demo
As you want to specifically search for a wildcard character you need to escape that
This is done by adding the ESCAPE clause to your LIKE expression. The character that is specified with the ESCAPE clause will "invalidate" the following wildcard character.
You can use any character you like (just not a wildcard character). Most people use a \ because that is what many programming languages also use
So your query would result in:
select *
from Manager
where managerid LIKE '\_%' escape '\'
and managername like '%\_%' escape '\';
But you can just as well use any other character:
select *
from Manager
where managerid LIKE '#_%' escape '#'
and managername like '%#_%' escape '#';
Here is an SQLFiddle example: http://sqlfiddle.com/#!6/63e88/4
Underscore is a wildcard for something.
for example
'A_%' will look for all match that Start whit 'A' and have minimum 1 extra character after that
In case people are searching how to do it in BigQuery:
An underscore "_" matches a single character or byte.
You can escape "\", "_", or "%" using two backslashes. For example, "\%". If you are using raw strings, only a single backslash is required. For example, r"\%".
WHERE mycolumn LIKE '%\\_%'
Source: https://cloud.google.com/bigquery/docs/reference/standard-sql/operators
You can write the query as below:
SELECT * FROM Manager
WHERE managerid LIKE '\_%' escape '\'
AND managername LIKE '%\_%' escape '\';
it will solve your problem.