POSTGRES 🐘- combine LIKE with exception(E') literal - postgresql

I'm trying to match a certain text that includes a single quote (i.e. 'company's report...')
normally I would have used the E' literal + ' or double single quotes.
but when it gets to using the LIKE '%' operator, things got complicated.
what is the best approach to match a text with a single quote?

You can escape single quote with another single quote. Example:
WHERE column LIKE 'RSNboim''s'
From https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS
To include a single-quote character within a string constant, write two adjacent single quotes, e.g., 'Dianne''s horse'. Note that this is not the same as a double-quote character (").

You can use Dollar-quoted String Constants at Lexical Structure
Your condition should be something like below;
select * from atable
where afield like $$Dianne's %$$

Related

Postgres escape double quotes

I am working with a malformed database which seems to have double quotes as part of the column names.
Example:
|"Market" |
|---------|
|Japan |
|UK |
|USA |
And I want to select like below
SELECT "\"Market\"" FROM mytable; /* Does not work */
How does one select such a thing?
The documentation says
[A] delimited identifier or quoted identifier […] is formed by enclosing an arbitrary sequence of characters in double-quotes ("). […]
Quoted identifiers can contain any character, except the character with code zero. (To include a double quote, write two double quotes.)
So you'll want to use
SELECT """Market""" AS "Market" FROM mytable;
An alternative would be
A variant of quoted identifiers allows including escaped Unicode characters identified by their code points. This variant starts with U& (upper or lower case U followed by ampersand) immediately before the opening double quote, without any spaces in between, for example U&"foo". […] Inside the quotes, Unicode characters can be specified in escaped form by writing a backslash followed by the four-digit hexadecimal code point number or alternatively a backslash followed by a plus sign followed by a six-digit hexadecimal code point number.
which in your case would mean
SELECT U&"\0022Market\0022" AS "Market" FROM mytable;
SELECT U&"\+000022Market\+000022" AS "Market" FROM mytable;
Disclaimer: your database may not actually have double quotes as part of the name itself. As mentioned in the comments, this might just be the way in which the tool you are using does display a column named Market (not market) since
Quoting an identifier also makes it case-sensitive
So all you might need could be
SELECT "Market" FROM mytable;

How to replace a chain of the same characters of unkown length from a string to a unique occurrence or it?

I have the following string in my DB, in a column we will name 'info', in a table we can call 'conversation':
Hello, I''''''''''''''''m Brian and I''''m looking for the kitchen
I would like to know if it's possible to replace the '''''' to a single occurrence of itself in PostgreSQL.
So:
Hello, I'm Brian and I'm looking for the kitchen
You can use regexp_replace for that:
select regexp_replace(info, '''+', '''', 'g')
from conversation;
The regular expression looks a bit weird due to the escaping of the single quotes, but it essentially is: '+ which means "at least one single quoted followed by any number of single quotes" and the replacement values (third parameter) is just one single quote.
Online example: https://rextester.com/HGWDZ41975

How to replace a single quote character with two single quote characters

I want to replace all instances of a string quote (') with two single quotes ('') in a string.
Lets say e'QmfgLu/]sf]/sd is a string and I want to replace ' with ''.
The result must be e''OmfgLu/]
I tried this query:
update customer set name=REGEXP_REPLACE(name, E'\'', '''');
also
update customer set name=REPLACE(name, E'\'', '''');
This query is not properly working. What is the suitable way to write the query?
You may replace a single occurrence of single quotes with 2 quotes using this regexp.
update customer set name=REGEXP_REPLACE(name, $$([^'])'([^'])$$, $$\1''\2$$ ,'g');
$$([^'])'([^'])$$ - represents a sequence of any character other than a single quote followed by a quote and then a non-quote character.
I'm using the dollar quoting to avoid confusing quotes.
Demo
EDIT
As #edruid pointed out, to handle case for quotes at the start and end of string, use:
REGEXP_REPLACE(name, $$([^']|^)'(?!')$$, $$\1''$$ ,'g')
This uses a negative lookahead for matching a single quote - (?!')
Demo2
In postgres the way to have a single quote in a string is to type '' (' is used as the escape character) so your replace would be
update customer set name=REGEXP_REPLACE(name, E'''', '''''', 'g');
(skip the final 'g' if you only want to replace the first ')
or without resorting to regexp:
update customer set name=REPLACE(name, '''', '''''');

Why does my LIKE statement fail with '\\_' for matching?

I have a database entry that has entries that look like this:
id | name | code_set_id
I have this particular entry that I need to find:
674272310 | raphodo/qrc_resources.py | 782732
In my rails app (2.3.8), I have a statement that evaluates to this:
SELECT * from fyles WHERE code_set_id = 782732 AND name LIKE 'raphodo/qrc\\_resources.py%';
From reading up on escaping, the above query is correct. This is supposed to correctly double escape the underscore. However this query does not find the record in the database. These queries will:
SELECT * from fyles WHERE code_set_id = 782732 AND name LIKE 'raphodo/qrc\_resources.py%';
SELECT * from fyles WHERE code_set_id = 782732 AND name LIKE 'raphodo/qrc_resources.py%';
Am I missing something here? Why is the first SQL statement not finding the correct entry?
A single backslash in the RHS of a LIKE escapes the following character:
9.7.1. LIKE
[...]
To match a literal underscore or percent sign without matching other characters, the respective character in pattern must be preceded by the escape character. The default escape character is the backslash but a different one can be selected by using the ESCAPE clause. To match the escape character itself, write two escape characters.
So this is a literal underscore in a LIKE pattern:
\_
and this is a single backslash followed by an "any character" pattern:
\\_
You want LIKE to see this:
raphodo/qrc\_resources.py%
PostgreSQL used to interpret C-stye backslash escapes in strings by default but no longer, now you have to use E'...' to use backslash escapes in string literals (unless you've changed the configuration options). The String Constants with C-style Escapes section of the manual covers this but the simple version is that these two:
name LIKE E'raphodo/qrc\\_resources.py%'
name LIKE 'raphodo/qrc\_resources.py%'
do the same thing as of PostgreSQL 9.1.
Presumably your Rails 2.3.8 app (or whatever is preparing your LIKE patterns) is assuming an older version of PostgreSQL than the one you're actually using. You'll need to adjust things to not double your backslashes (or prefix the pattern string literals with Es).

Removing escaped quotes in SQLite3

All,
I am trying to clean up data in a SQLite database, that contains tons of escaped single and double quotes.
Example: \"Text\" has \'junk\' like this all over the place.
When I do a SELECT to see if the REPLACE function has the correct pattern, the REPLACE is not working:
-- replace escaped single quotes
SELECT id,subject,body,replace(body,"\\'","'") as `clean-body`
FROM article
WHERE id=1118
Thanks for looking
There is no need to escape the backslash. Try this in place of your original call to replace:
replace(body,"\'","'")