SQL Pattern matching not giving the correct output - sql-server

I am trying to find a certain set of characters in a column from a datatable. I have tried the pattern that seems more logical to me (right below) but it doesn't seem to be doing the job. What I wish to achieve is a pattern where I have something like '["5"]', basically with: square brackets, quotation marks, any integer number, quotation marks, square brackets. The output I am getting is just empty, and I can't seem to undersand why. Besides this, I would like to update the records that do not follow this pattern to follow it. Does anyone have a solution for this?
To give you some context, here is the test table:
I want to achive only the last three records.
Here is what I have tried:
SELECT ToJsonTestValue
FROM Test
WHERE ToJsonTestValue LIKE '["%"]'
and
UPDATE dbo.Test
SET ToJsonTestValue = '["'+ToJsonTestValue+'"]'
WHERE ToJsonTestValue LIKE '#';

You have a couple of problem here. Firstly you have the square brackets, which needs escaping. Then you also use % which is a multi character wildcard, however, it appears that you want a single character. It also appears that that character can only be an integer, so you might want to be more specific. Either of these should give you the result you want:
--Using single character wildcard:
SELECT *
FROM (VALUES('["1"]'),('["["1"]"]'))V(S)
WHERE V.S LIKE '[[]"_"[\]]' ESCAPE '\';
--Specifically requiring int:
SELECT *
FROM (VALUES('["1"]'),('["["1"]"]'))V(S)
WHERE V.S LIKE '[[]"[0-9]"[\]]' ESCAPE '\';

Related

Regular expression in snowflake

I have a requirement where the string from a column has a value "/Date(-34905600000)/". The value within brackets could be in any one of the following patters
"/Date(-34905600000)/"
"/Date(1407283200000)/"
"/Date(1636654411000+0000)/"
I need to extract all inside the parenthesis for examples 1 and 2 including the "-" if any. For the 3rd example, it should be only the numbers inside the parenthesis before "+" ie 1636654411000.
I tried the following and not getting the results as the output is coming along with the parenthesis.
select REGEXP_substr("/Date(-34905600000)/", '\\([[:alnum:]\-]+\\)')
from table A;
select REGEXP_substr("/Date(-34905600000)/", '\\((.*?)\\)') from table
A;
select REGEXP_substr("/Date(-34905600000)/", '[0-9]+') from table A;
Using regexp_replace() instead you could do:
regexp_replace(colA, '(\\/Date\\()([-0-9]*)(.*)', '\\2')
That splits the string into three substitution groups and then only keeps the second. I often end up doing regexp_replace() with substitution groups like this when regexp_substr() fails me.
if you want the REGEXP_SUBSTR to sub-matches you need to use the 'e' <regex_parameters> option, and then you can use 1 as the to match your first grouping, thus:
SELECT column1,
REGEXP_substr(column1, 'Date\\(([-+]?[0-9]+)',1,1,'e')
FROM VALUES
('"/Date(-34905600000)/"'),
('"/Date(1407283200000)/"'),
('"/Date(1636654411000+0000)/"');
gives:
COLUMN1
REGEXP_SUBSTR(COLUMN1, 'DATE\(([-+]?[0-9]+)',1,1,'E')
"/Date(-34905600000)/"
-34905600000
"/Date(1407283200000)/"
1407283200000
"/Date(1636654411000+0000)/"
1636654411000
I am quite sure the regexp is greedy by default, but otherwise you can force the match to the timezone or paren with
'Date\\(([-+]?[0-9]+)[-+\\)]'

Excel - Generate INSERT Statements and Handle Single Quote

I have the following formula in an Excel spreadsheet:
="INSERT INTO #dreams VALUES('"&B3&"','"&C3&"','"&D3&"','"&E3&"','"&F3&"','"&G3&"','"&H3&"','"&I3&"')"
Works fine, basically, unless I have data like this in, for example, in D3.
US INVESTMENTS' GRADE CORPORATE BOND FUND (QUALIFIED)
In this case, the INSERT statement looks like this:
INSERT INTO #dreams VALUES('2019039','550678','US INVESTMENTS' GRADE CORPORATE BOND FUND (QUALIFIED)','F','5f','Hirofumi Nakamura','ACBD1','N')
That single quote will be interpreted as a delimeter. I need to have US INVESTEMENTS''
That is, substitute two single quotes for the one single quote.
I have tried various things, but can't get it to work.
EDIT: Would something similar to this work?
="INSERT INTO #dreams VALUES('"&B3&"','"&C3&"',=SUBSTITUTE(D2,"'","''"),'"&E3&"','"&F3&"','"&G3&"','"&H3&"','"&I3&"')"
Wrap each of the column references with SUBSTITUTE and replace ' with ''. For example SUBSTITUTE(B3,"'","''").
Using what #Rory said, this works:
="INSERT INTO #dreams VALUES('"&B3&"','"&C3&"','"&SUBSTITUTE(D3,"'","''")&"','"&E3&"','"&F3&"','"&G3&"','"&H3&"','"&I3&"')"

Escape special characters for Oracle and SQL Server in the same query

I have following query:
SELECT *
FROM PRODUCTS
WHERE REDUCTION LIKE '50%'
I'm required to use the LIKE clause. This query needs to run on both Oracle and SQL Server.
Now there is an issue because I want to match all products with a reduction of 50%. But the data might contain a reduction of 50.50%. Because '%' is a special character it matches both of them.
I want to escape all special characters, like the % in my query so that I only get the products with 50% reduction.
Is there an uniform solution to escape special characters on a dynamical way for both Oracle and SQL server?
Using a backslash is not a solution, because we don't know in practice what the input will be.
The ESCAPE clause works in Oracle and SQL Server.
As for your input, you need to replace the all occurrences of % with \% (preferably before passing the value to RDBMs). You can do this inside a query as well since, fortunately, Oracle REPLACE and SQL Server REPLACE functions have similar signature:
CREATE TABLE tests(test VARCHAR(100));
INSERT INTO tests VALUES('%WINDIR%\SYSTEM32');
SELECT *
FROM tests
WHERE test LIKE REPLACE(REPLACE('%WINDIR%\SYSTEM32', '\', '\\'), '%', '\%') ESCAPE '\'
The ESCAPE clause identifies the backslash (\) as the escape character
SELECT *
FROM PRODUCTS
WHERE REDUCTION LIKE '50\%'
You'll need something like the first answer above, but you don't need to use a \ as the escape. You can choose whatever you want using the ESCAPE clause.
But if:
users are allowed to enter wildcards;
and you need to use LIKE;
and you don't want them treated like wildcards;
then you have to escape them somehow.
Perhaps you can reserve some char you know the user will not need and make that the escape char.
As far as I can tell in Oracle you only need to escape the percent (%) and the underbar (_).
In SQL Server you also have to consider brackets.
A good thing is that overescaping does not look like it will cause problems, so even though you don't need to espace brackets in Oracle, doing so is ok.

finding exact strings with sql like statement

I have the following statement
SELECT *
FROM Delivery_Note this_
WHERE mycol like '%[126]%'
I've noticed this also returns rows that contain [123]. What is the best way to find exact matching in a string.
edit
I appreciate this is not an efficient query. There a few other reasons for this approach.
Brackets specify a range when used with LIKE. You can use the ESCAPE keyword.
WHERE mycol LIKE '%\[126\]%' ESCAPE '\';
Of course if you are trying to match an exact string, you don't need LIKE, or you can drop the % characters and LIKE will behave like = (this makes it flexible to pass in wildcards or exact matches to a parameter).

SQL Server Escape an Underscore

How do I escape the underscore character?
I am writing something like the following where clause and want to be able to find actual entries with _d at the end.
Where Username Like '%_d'
T-SQL Reference for LIKE:
You can use the wildcard pattern matching characters as literal characters. To use a wildcard character as a literal character, enclose the wildcard character in brackets. The following table shows several examples of using the LIKE keyword and the [ ] wildcard characters.
For your case:
... LIKE '%[_]d'
Obviously #Lasse solution is right, but there's another way to solve your problem: T-SQL operator LIKE defines the optional ESCAPE clause, that lets you declare a character which will escape the next character into the pattern.
For your case, the following WHERE clauses are equivalent:
WHERE username LIKE '%[_]d'; -- #Lasse solution
WHERE username LIKE '%$_d' ESCAPE '$';
WHERE username LIKE '%^_d' ESCAPE '^';
These solutions totally make sense. Unfortunately, neither worked for me as expected. Instead of trying to hassle with it, I went with a work around:
select *
from information_schema.columns
where replace(table_name,'_','!') not like '%!%'
order by table_name
I had a similar issue using like pattern '%_%' did not work - as the question indicates :-)
Using '%\_%' did not work either as this first \ is interpreted "before the like".
Using '%\\_%' works. The \\ (double backslash) is first converted to single \ (backslash) and then used in the like pattern.
Adding [ ] did the job for me
like '%[\\_]%'
This worked for me, just use the escape
'%\_%'
None of these worked for me in SSIS v18.0, so I would up doing something like this:
WHERE CHARINDEX('_', thingyoursearching) < 1..where I am trying to ignore strings with an underscore in them. If you want to find things that have an underscore, just flip it around:
WHERE CHARINDEX('_', thingyoursearching) > 0
Adding to Gerardo Lima's answer, I was having problems when trying to use backslash as my escape character for the ESCAPE clause. This caused issues:
SELECT * FROM table WHERE email LIKE '%#%\_%' ESCAPE '\'
It was resolved by switching to an exclamation point. This worked:
SELECT * FROM table WHERE email LIKE '%#%!_%' ESCAPE '!'

Resources