SQL Server LIKE search with [ ] not matching as expected - sql-server

I'm trying to search the contents of a text column in a SQL Server DB. I do not have the ability to add a fulltext index to the column, so I'm trying to do so in a query:
SELECT t.DateBegin, t.Action, t.Detail, t.Status, t.ErrorText,
CASE WHEN t.ErrorText LIKE '%[IBM][CLI Driver][DB2/LINUXX8664]%' THEN 'IBM'
WHEN t.ErrorText LIKE '%WebApplicationContainerServer%' THEN 'WACS'
ELSE '' END AS ErrorType
FROM (
SELECT a.DateBegin, a.Action, a.Detail, a.Status,
CONVERT(varchar(max),
REPLACE(REPLACE(CAST(a.ExtInfo AS varchar(max)), CHAR(13), ' '), CHAR(10), ' ')
) as ErrorText
FROM bi4infoburst.dbo.IBT_RTS_ACTION a
WHERE a.DateBegin >= DATEADD(day, -7, GETDATE())
AND a.Status = 5
) t
ORDER BY t.DateBegin
My thought here is that if I converted it to a varchar then I could use the LIKE operator. But when I run this query, it always matches the first case regardless of what text or pattern I put in.
What am I doing wrong?

It is an issue with character escaping.
Square brackets have to be handled properly because otherwise are interpreted as special chars like % is; using square brackets you match any of the char inside the brackets and that's why the first CASE always matches.
The solution is to to declare an escape character in the statement to escape the brackets.
If used in a WHERE clause the syntax would be as follows:
WHERE t.ErrorText LIKE '%![IBM!]![CLI Driver!]![DB2/LINUXX8664!]%' ESCAPE '!'
I don't know if is possible and how to use it in a CASE statement...

Related

REPLACE function does not replace desired character string

I want to replace all occurrences of a particular single character string (eg.:'^'or ',') when creating a view that is based on a single table. But id does not replace the desired single character in all the the data rows. I know it when I query the newly created view. All fields have varchar datatype.
This is a specific a example where the desire string does not get replaced MAINTENANCE¿ENHANCED
I tried the following and none worked.
SELECT REPLACE('MAINTENANCE¿ENHANCED',',','')
SELECT REPLACE('MAINTENANCE¿ENHANCED',char(33),'')
SELECT REPLACE(N'MAINTENANCE¿ENHANCED',',','')
SELECT REPLACE('MAINTENANCE¿ENHANCED',N',','')
SELECT REPLACE(CAST('MAINTENANCE¿ENHANCED' as NVARCHAR(50)),N',','')
SELECT REPLACE(CAST('MAINTENANCE¿ENHANCED' as VARCHAR(50)),N',','')
SELECT REPLACE(TRY_CAST('MAINTENANCE¿ENHANCED' as VARCHAR(50)),N',','')
SELECT REPLACE(CONVERT(VARCHAR(50),'MAINTENANCE¿ENHANCED'), N',','')
Also I performed simple test I copied the comma from the string from where I need it to be replaced (see my code below)
if ',' = '‚' print 1 -- DOES NOT return TRUE. 1st comma is the one I typed in the second argument of the REPLACE function, the 2nd comma is the one copied from the string above.
if ',' = ',' print 1 -- RETURNs TRUE. Both of the commas that I typed in the second argument of the REPLACE function.
Apparently the issue is with my comma in the data source which is being treated as equally. Though the functions below shows that both are varchar. ( https://blog.sqlauthority.com/2013/12/15/sql-server-how-to-identify-datatypes-and-properties-of-variable )
**-- comma from the string**
DECLARE #myVar VARCHAR(100)
SET #myVar = '‚'
SELECT SQL_VARIANT_PROPERTY(#myVar,'BaseType') BaseType,
SQL_VARIANT_PROPERTY(#myVar,'Precision') Precisions,
SQL_VARIANT_PROPERTY(#myVar,'Scale') Scale,
SQL_VARIANT_PROPERTY(#myVar,'TotalBytes') TotalBytes,
SQL_VARIANT_PROPERTY(#myVar,'Collation') Collation,
SQL_VARIANT_PROPERTY(#myVar,'MaxLength') MaxLengths
--**regular comma**
SET #myVar = ','
SELECT SQL_VARIANT_PROPERTY(#myVar,'BaseType') BaseType,
SQL_VARIANT_PROPERTY(#myVar,'Precision') Precisions,
SQL_VARIANT_PROPERTY(#myVar,'Scale') Scale,
SQL_VARIANT_PROPERTY(#myVar,'TotalBytes') TotalBytes,
SQL_VARIANT_PROPERTY(#myVar,'Collation') Collation,
SQL_VARIANT_PROPERTY(#myVar,'MaxLength') MaxLengths
Partially this can be resolved using this code below
select Stuff('MAINTENANCE¿ENHANCED', PatIndex('%[^a-z0-9]%', 'MAINTENANCE¿ENHANCED'), 1, '')
OUTPUT
-- the comma is replaced. That is what is expected.
MAINTENANCEÿENHANCED
But it does not work in I have more than 1 comma regardless if I copy it from the data source or type it in myself.
('‚MAINTENANCE¿ENHANCED')
select Stuff('‚MAINTENANCE¿ENHANCED', PatIndex('%[^a-z0-9]%', '‚MAINTENANCE¿ENHANCED'), 1, '')
select REPLACE(Stuff('‚MAINTENANCE¿ENHANCED', PatIndex('%[^a-z0-9]%', '‚MAINTENANCE¿ENHANCED'), 1, ''),',','')
OUTPUT
-- the comma is back again. The is the Issues. Only one (first) comma is replaced.
AINTENANCE¿ENHANCED
P.S.
Please refer to my answer below where I resolved all the above described issues except that I need to figure out how to preserver from removal special characters like question marks, parenthetic, etc.
PARTIALLY this can be resolved using this code below that I got from here
use MyDB;
go
drop function if exists [dbo].[RemoveNonAlphaCharacters]
go
Create Function [dbo].[RemoveNonAlphaCharacters](#Temp VarChar(1000))
Returns VarChar(1000)
AS
Begin
Declare #KeepValues as varchar(50)
Set #KeepValues = '%[^ a-z0-9]%'
While PatIndex(#KeepValues, #Temp) > 0
Set #Temp = Stuff(#Temp, PatIndex(#KeepValues, #Temp), 1, '')
Return #Temp
End
SELECT MyDB.dbo.RemoveNonAlphaCharacters(', (/!:\£&^?-:;|\)?%$"é觰àçò*MAIN,2TENANCE¿ENHANCED 123 asds %[ ..')
I got this from
How to strip all non-alphabetic characters from string in SQL Server?
OUTPUT
éèàçòMAIN2TENANCEÃÂENHANCED 123 asds
The issues here that it removes all non-alphabetic string characters such as &^?-:;|)? ]% ;:_|!"
I could not fugure out how to pass regular expression to preserver all (except for comma which needs to be replaced) characters in the printable section of the ASCII table (see example above and follow the links below)
https://www.rexegg.com/regex-quickstart.html
http://www.asciitable.com/

Select Query is not working with in Clause

Sql query is not working if we pass value In clause converted from 'Canada,Portugal' to 'Canada','Portugal'
if pass hardcode value In clause 'Canada','Portugal' it works
declare #GeographicalLocation varchar(max)
set #GeographicalLocation ='Canada,Portugal'
set #GeographicalLocation = REPLACE(#GeographicalLocation, ',', ''',''')
set #GeographicalLocation = ''''+#GeographicalLocation+'''';
select ContinentName from [ContinentList] where ContinentId in
(select ContinentId from [CountryList] where [CountryName]
in(#GeographicalLocation)and BaseId is Null)
Because, at the end your where clause looks like:
where [CountryName] in ('''Canada'',''Portugal''')
This string in where caluse should be two separate strings, but it's only one! It should look like this:
where [CountryName] in ('Canada','Portugal')
So, for this situation I'd use something like
where charindex([CountryName], #GeographicalLocation) > 0
In this approach, you don't need to append extra ' to your string variable.
And I'd recommend using case sensitive collation.

SQL Server 2016 How to use a simple Regular Expression in T-SQL?

I have a column with the name of a person in the following format: "LAST NAME, FIRST NAME"
Only Upper Cases Allowed
Space after comma optional
I would like to use a regular expression like: [A-Z]+,[ ]?[A-Z]+ but I do not know how to do this in T-SQL. In Oracle, I would use REGEXP_LIKE, is there something similar for SQL Server 2016?
I need something like the following:
UPDATE table
SET is_correct_format = 'YES'
WHERE REGEXP_LIKE(table.name,'[A-Z]+,[ ]?[A-Z]+');
First, case sensitivity depends on the collation of the DB, though with LIKE you can specify case comparisons. With that... here is some Boolean logic to take care of the cases you stated. Though, you may need to add additional clauses if you discover some bogus input.
declare #table table (Person varchar(64), is_correct_format varchar(3) default 'NO')
insert into #table (Person)
values
('LowerCase, Here'),
('CORRECTLY, FORMATTED'),
('CORRECTLY,FORMATTEDTWO'),
('ONLY FIRST UPPER, LowerLast'),
('WEGOT, FormaNUMB3RStted'),
('NoComma Formatted'),
('CORRECTLY, TWOCOMMA, A'),
(',COMMA FIRST'),
('COMMA LAST,'),
('SPACE BEFORE COMMA , GOOD'),
(' SPACE AT BEGINNING, GOOD')
update #table
set is_correct_format = 'YES'
where
Person not like '%[^A-Z, ]%' --check for non characters, excluding comma and spaces
and len(replace(Person,' ','')) = len(replace(replace(Person,' ',''),',','')) + 1 --make sure there is only one comma
and charindex(',',Person) <> 1 --make sure the comma isn't at the beginning
and charindex(',',Person) <> len(Person) --make sure the comma isn't at the end
and substring(Person,charindex(',',Person) - 1,1) <> ' ' --make sure there isn't a space before comma
and left(Person,1) <> ' ' --check preceeding spaces
and UPPER(Person) = Person collate Latin1_General_CS_AS --check collation for CI default (only upper cases)
select * from #table
The tsql equivalent could look like this. I'm not vouching for the efficiency of this solution.
declare #table as table(name varchar(20), is_Correct_format varchar(5))
insert into #table(name) Values
('Smith, Jon')
,('se7en, six')
,('Billy bob')
UPDATE #table
SET is_correct_format = 'YES'
WHERE
replace(name, ', ', ',x')
like (replicate('[a-z]', charindex(',', name) - 1)
+ ','
+ replicate('[a-z]', len(name) - charindex(',', name)) )
select * from #table
The optional space is hard to solve, so since it's next to a legal character I'm just replacing with another legal character when it's there.
TSQL does not provide the kind of 'repeating pattern' of * or + in regex, so you have to count the characters and construct the pattern that many times in your search pattern.
I split the string at the comma, counted the alphas before and after, and built a search pattern to match.
Clunky, but doable.

SQL - How can I use a Select based on the parameter

I've got a sql statement in a SQL Server stored procedure using a where clause like this:
Select (fields)
From Table
Where Testname like #SearchLetter + '%'
I need to do check the parameter #SearchLetter and if it's "#", I need to make the parameter choose records that the field Testname starts with a numeric field (0-9)
I've tried several things (ifs/selects, etc.) but I can't seem to get what I need.
anyone know how I can do this?
Try
where Testname like case #SearchLetter
when '#' then '[0-9]' + '%'
else #Searchletter + '%' end
You can use
Where Testname like REPLACE(#SearchLetter, '#', '[0-9]') + '%'
Assuming that the string is always one character (or that you always want this substitution to occur wherever the hash falls) Otherwise use a CASE statement to check for exact equality.
Where Testname like
CASE WHEN #SearchLetter = '#'
THEN '[0-9]'
ELSE #SearchLetter
END + '%'
The simplest way is
where left(#SearchLetter, 1) between '0' and '9

Error with SELECT CASE with regular expression

I wrote the following query in T-SQL for SQL Server
SELECT
CASE
WHEN ADDR_LINE_1 REGEXP '^[0-9]'
THEN SUBSTRING(ADDR_LINE_1,1,CHARINDEX(' ',ADDR_LINE_1))
ELSE NULL
END AS HOUSE_NUMBER
FROM CUSTOMER
What I want is that if the column ADDR_LINE_1 starts with a number, I want to extract the HOUSE_NUMBER from it. But right now my query gives a parse error. If I replace the word REGEXP with LIKE, the parse error goes away, but I always get NULL for HOUSE_NUMBER. What is the correct syntax for my query?
You could use ISNUMERIC and LEFT like this.
SELECT
CASE WHEN ISNUMERIC(LEFT(ADDR_LINE_1, 1)) = 1
THEN SUBSTRING(ADDR_LINE_1, 1, CHARINDEX(' ', ADDR_LINE_1))
ELSE NULL
END AS HOUSE_NUMBER
FROM CUSTOMER
How about using the LIKE
SELECT
CASE
WHEN ADDR_LINE_1 Like '%[0-9]%'
THEN SUBSTRING(ADDR_LINE_1,1,CHARINDEX(' ',ADDR_LINE_1))
ELSE NULL
END AS HOUSE_NUMBER
FROM CUSTOMER

Resources