Regexp for replacing quotes in database insert statements - regex

I'm converting a sqlite3 database to mysql.
I have a nice command file for sed that changes AUTOINCREMEMT and the other things needed, but I'm stuck on the last one: double quotes.
sqlite3 dump format:
CREATE TABLE "products" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"name" varchar(255),
"desc" varchar(255) );
INSERT INTO "products" VALUES(1,'Flux Capacitor',
'This is the "real" thing.\nPromise!')
For the first statement, I can replace all double quotes with backticks and mysql will be happy.
However, my product information has double quotes in the data. How can I exclude these from being replaced? I was trying to replace only those double quotes with a placeholder, then I could replace all the other double quotes, then I could change the placeholder back, but my regex-fu isn't up to par.
This was as far as I got:
/"[^"]*"/s
... to match the double quoted texts, but I couldn't figure out how to qualify that only double quotes inside single quotes should be matched.

I would change MySQL to accept double-quotes as identifier delimiters. This is standard SQL behavior, and you can make MySQL behave that way with a SQL mode:
mysql> SET SQL_MODE = ANSI;
Or more specifically:
mysql> SET SQL_MODE = ANSI_QUOTES;
Then MySQL should understand your data dump.
See "Server SQL Modes" for more information.

Well I know how to easily solve it in PHP with preg_replace_callback():
<?php
$sql = file_get_contents('sqlite3 dump.txt');
function callback($match) { return str_replace('"', '`', $match[0]); }
$sql = preg_replace_callback('/CREATE TABLE .*?;/s', callback, $sql);
echo preg_replace_callback('/INSERT INTO .*? VALUES/s', callback, $sql);
?>
Unless you can "SET SQL_MODE = ANSI_QUOTES" as Bill Karwin said.

I can replace all double quotes with backticks and mysql will be happy.
Happy for now, but it wouldn't have solved the whole problem, so could easily fall over in the future. Apostrophe and backslash also work differently in MySQL.
my product information has double quotes in the data. How can I exclude these from being replaced?
You can't reliably. SQL syntax is actually quite complex, and cannot in the general case be parsed by regex hacking.
Bill's suggestion with changing SQL_MODE to fit the existing syntax is a much better approach. I run MySQL in ANSI mode all the time, as I dislike having to tailor my apps to one particular database's foibles.

Related

Select field with Hyphen in Redshift Spectrum

I am trying to extract a nested field with an Hyphen in the name through Redshift Spectrum
SELECT mystruct.mysubstruct.my-field.id
FROM my_external_schema.my_table
I see in other DBMS is suggested to wrap the field name with double quotes:
"mystruct.mysubstruct.my-field.id"
or back ticks
`mystruct.mysubstruct.my-field.id`
but none of these worked for me.
Any suggesitons?
Since the double quotes permit to escape the special characters, doing "mystruct.mysubstruct.my-field.id" means that you are looking for the column named 'mystruct.mysubstruct.my-field.id' at top level and not as the nested column, because the dot is not used to extract the field.
What you have to do is
SELECT mystruct.mysubstruct."my-field".id
FROM my_external_schema.my_table

Regex query to remove character(s) from lines that has a phrase

I'm trying to convert my DDL's from Oracle to Postgres but I'm having a problem with double quote characters. I want to remove double quotes from each and every line which contains "CREATE TABLE " phrase. For example I want this: CREATE TABLE "ILIKEMEMES" to be converted to this: CREATE TABLE ILIKEMEMES but I don't want line ("ID" VARCHAR(255) to change either. I'm doing this on Notepad++ so Python scripts wouldn't be my first choice of solution.
Try doing the following find and replace, in regex mode:
Find: \bCREATE TABLE "(.*?)"
Replace: CREATE TABLE $1
This will target only create table statements having a table name which appears in double quotes.

How to properly escape colon in QueryExecute sql statement?

Update: Not satisfied with this answer but I found that not passing a param struct will cause CF2016 to ignore colons. Looks like CF2018 doesn't have the issue either way (though I can only test that with query of query at the moment).
We have generated sql queries that do not use query params going through QueryExecute(). I am sometimes seeing the error Space is not allowed after parameter prefix ':' and found it is caused by a string literal with a colon and space. For example:
select 'test this: error'
I was not able to find an official way to escape the colon and the common escapes didn't work, but figured out this workaround...
sqlstring = replace(sqlstring, ": ", ":'+' ", "all")
However that doesn't account for other situations that could potentially come up that wouldn't be a string literal such as a column name with colon and space and likely many more I can't think of at the moment.
Is there an official way to escape a colon passed to QueryExecute not part of a queryparam?
I suppose you could separate the string out and have it be passed in
result = QueryExecute("
SELECT :mystring AS ...
",
{ mystring : "test this: error"}
);
Seems like a lot of work though.

SQLite - display table names finishing by "_1"

I am looking for a way to display table names I have in a database for which the name is ending by "_1".
I tried to use the command:
.tables '%_1';
Unfortunately the underscore symbol is used in the expression matching, so it returned me tables such as:
"125_1","125_11","125_21".
Only the first one is interesting in this example, I will not display the full result because there are hundreds of tables. So I tried something like this:
.tables '%_1' ESCAPE '_';
And it gave me the exact same result.
If you have a solution to overcome the problem of the underscore symbol, please post it.
remember that I have hundreds of tables with names following this pattern in regex: "^\d+_\d+$"
This is not how the ESCAPE clause works. To search for an underscore, you must escape the underscore with the escape character:
LIKE '%#_1' ESCAPE '#'
Anyway, .tables is not an SQL command and ignores the ESCAPE clause. To do your own search, you have to run your own query:
SELECT name
FROM sqlite_master
WHERE type = 'table'
AND name LIKE '%#_1' ESCAPE '#';

How do we include a variable in escaped double quotes?

I'm using Node.js and MongoDB, and I'm trying to perform a $search on a $text field from a collection. As mentioned in the docs, To match on a phrase, as opposed to individual terms, enclose the phrase in escaped double quotes (\"), as in:
"\"ssl certificate\""
I have a variable query that holds the value inputted by a user in a simple text search application. I want to add this query as a phrase, so that I can perform my search on all the words entered by the user appropriately.
Is there anyway one can achieve this?
assuming the user input is in the variable input you can add double qoutes around it like so:
input = '"'+input+'"';
this string, you should then be able to use in your $search.
If you post your code, I could try to give a more specific answer.
Instead of using regex of the format /regexString/g you can also create Regex objects using variables.
var regexExp = new RegExp(query,"g");
You can use this regexExp to search.