SQL UPDATE statement with large HTML data - sql

I have some automated workflow, which includes updating a column via SQL with HTML tags in it.
The basic SQL statement goes like this:
UPDATE content SET bodytext = '<div class="one two three">Here comes a whole lot of HTML with all special chars and double quotes " and single quotes ' and empty lines and all possible kind of stuff...</div>' WHERE pid = 10;
Is there a way to make MariaDB or MySQL to escape things automatically in SQL (without PHP)?

I'd suggest to use prepared statements. This way you separate the statement from it's parameters and don't need to care about additional escaping necessary in plain SQL.
Using functionality provided in PHP's MySQLi driver would simplify the process:
https://www.w3schools.com/php/php_mysql_prepared_statements.asp
Prepared statements are also possible in plain SQL, but I'm not sure if doing it manually would be worth the hassle
https://dev.mysql.com/doc/refman/8.0/en/sql-prepared-statements.html

Thank you for your input, but I think, I found a solution which works for me. It seems that you actually can tell the SQL server to accept a raw string by this kind of syntax:
SELECT q'[The 'end' of the day]'
(Source: https://www.databasestar.com/sql-escape-single-quote/)
So I did the following:
SELECT #html := '[<div class="one two three">Here comes a whole lot of HTML with all special chars and double quotes " and single quotes '' and empty lines and all possible kind of stuff...</div>]';
UPDATE content SET bodytext = #html WHERE pid = 10;
And it works that way without any escaping problems.

Related

String within externally saved Qlik Sense expression

I have a small issue, so here's a bit of background:
We are developing a Qlik Sense application and we normally write our expressions to an external script. We save these as variables, and then evaluate the variables in the application. The advantage of this is a) we can use better version control with GIT, and b) we can separate the queries from the application if we ever need to change platforms in future.
My Problem:
I have come across a situation where we need to concat a string to the result of an expression, which can be done easily in the application, but when you save the expression to an external file the single quotes around the expression interfere with the single quotes around the string.
I tried
using double quotes for the string only, but qlik doesn't evaluate it correctly.
same goes for the expression using double quotes only.
escaping the single quote inside the expression, eg. "\'" but same story.
What I was thinking of doing next was changing the quote to a rogue character so qlik would ignore it as text, then replacing it with a quote later so qlik would then try to evaluate it.
Example Code:
SET variable = 'if(isnull(month),'Month: ' & date(now(), 'MMM-YYYY'),'Month: ' & only({$<year={2016}, month={6}>}month)';
After some further research I found that Qlik has its own way of escaping characters without using the "\" character. I was able to solve this issue by escaping the inner single quotes like this:
SET variable = 'if(isnull(month),''Month: '' & date(now(), ''MMM-YYYY''),''Month: '' & only({$<year={2016}, month={6}>}month)';
Feels like a pretty silly oversight now, but hopefully this will save someone some time in the future.

Way to insert text having ' (apostrophe) into a SQL table

While I was trying the following SQL command , I got sql error.
INSERT INTO exampleTbl VALUES('he doesn't work for me')
where doesn't contain the apostrophe.
What is the way to insert text having ' (apostrophe) into a SQL table.
In SQL, the way to do this is to double the apostrophe:
'he doesn''t work for me'
However, if you are doing this programmatically, you should use an API that accepts parameters and escapes them for you automatically. Programmatically escaping and using string concatenation to assemble a query yourself is a sure way to end up with SQL injection vulnerabilities.
INSERT INTO exampleTbl VALUES('he doesn''t work for me')
If you're adding a record through ASP.NET, you can use the SqlParameter object to pass in values so you don't have to worry about the apostrophe's that users enter in.
$value = "he doesn't work for me";
$new_value = str_replace("'", "''", "$value"); // it looks like " ' " , " ' ' "
INSERT INTO exampleTbl (`column`) VALUES('$new_value')
try this
INSERT INTO exampleTbl VALUES('he doesn''t work for me')
insert into table1 values("sunil''s book",123,99382932938);
use double apostrophe inside of single apostrophe,
it will work
I know the question is aimed at the direct escaping of the apostrophe character but I assume that usually this is going to be triggered by some sort of program providing the input.
What I have done universally in the scripts and programs I have worked with is to substitute it with a ` character when processing the formatting of the text being input.
Now I know that in some cases, the backtick character may in fact be part of what you might be trying to save (such as on a forum like this) but if you're simply saving text input from users it's a possible solution.
Going into the SQL database
$newval=~s/\'/`/g;
Then, when coming back out for display, filtered again like this:
$showval=~s/`/\'/g;
This example was when PERL/CGI is being used but it can apply to PHP and other bases as well. I have found it works well because I think it helps prevent possible injection attempts, because all ' are removed prior to attempting an insertion of a record.
yes, sql server doesn't allow to insert single quote in table field due to the sql injection attack. so we must replace single appostrophe by double while saving.
(he doesn't work for me) must be => (he doesn''t work for me)
you can use backslash '\' if you want to display a single quote in your text.
INSERT INTO exampleTbl VALUES('He doesn(\')t') ;

Regex for doubling single quotes in string

I would like a regex that would make this:
VALUES('Hit 'n Run')
into
VALUES('Hit ''n Run')
Is this possible?
No, this is not really possible. If you have VALUES('Hit 'n Run'), you already have an invalid mixture of delimiting apostrophes and literal apostrophes. String processing is like mixing sugar and salt: once you've mixed contexts without proper escaping there is no way of pulling them back apart.
If you are trying to rescue broken data, you could try something like (?<!\()'(?!\)) to match apostrophes that don't have a bracket next to them. It's a weak and easily fooled tactic but for simple data it might work.
If you are putting together dynamic SQL queries you must escape the ' before you put it into the query string, either using a simple string replace ' with '' if you're sure that's the only escape your DBMS requires, or — much better — using a dedicated SQL-string-literal-escaping function appropriate to your DBMS. Quite what that function would be depends on what platform (language, DBMS) you're talking about.
Any pattern that could be expressed in RegEx could then be exploited to create the very SQL injection issues you're trying to avoid.
Example nasty input:
VALUES(');DELETE * FROM customer;SELECT '

Error when replacing words that contain quotes in mySQL

I have updated many records already, but when it came to a word that contains a quote I get this error: "ERROR: Unclosed quote # 1357"
I know why it's giving me this error, I just don't how to solve it.
Here's a sample:
UPDATE invnum SET cAccountName = replace(cAccountName,'JOHN'S','BEN')
Thanks in advance.
Escape quotes inside strings:
UPDATE invnum SET cAccountName = replace(cAccountName,'JOHN\'S','BEN')
You want to be really careful with this - not dealing with this properly is the source of SQL injection attacks, and is a major source of security problems.
if you’re using a script to update your records use a builtin escaping function. for php that would be mysql_real_escape_string
Try this instead:
UPDATE invnum SET cAccountName = replace(cAccountName,"JOHN'S","BEN")
If you need to use both types of quotes within a string, then you'll need to escape the type of quotes you use to surround the string when they occur within it (otherwise the SQL interpreter will think the string ends before it actually does.
For instance:
Johns becomes "Johns"
John's becomes "John's" or 'John\'s'
"John" becomes '"John"' or "\"John\""
et cetera.

Split SQL statements

I am writing a backend application which needs to be able to send multiple SQL commands to a MySQL server.
MySQL >= 5.x support multiple statements, but unfortunately we are interfacing with MySQL 4.x.
I am trying to find a way (hint: regex) to split SQL statements by their semicolon, but it should ignore semicolons in single and double quotes strings.
http://www.dev-explorer.com/articles/multiple-mysql-queries has a very nice regex to do that, but doesn't support double quotes.
I'd be happy to hear your suggestions.
Can't be done with regex, it's insufficiently powerful to parse SQL. There may be an SQL parser available for your language — which is it? — but parsing SQL is quite hard, especially given the range of different syntaxes available. Even in MySQL alone there are many SQL_MODE flags on a server and connection level that can affect how basic strings and comments are parsed, making statements behave quite differently.
The example at dev-explorer goes to amusing lengths to try to cope with escaped apostrophes and trailing strings, but will still fail for many valid combinations of them, not to mention the double quotes, backticks, the various comment syntaxes, or ANSI SQL_MODE.
As bobince said, regular expressions are probably not going to be powerful enough to do this. They're certainly not going to be powerful enough to do it in any halfway elegant manner. The second link cdonner provided also does not address this; most answers there were trying to talk the questioner out of doing this without semicolons; if he had taken the general advice, then he'd have ended up where you are.
I think the quickest path to solving this is going to be with a string scanner function, that examines every character of the string in sequence, and reacts based on a bit of stored state. Rough pseudocode:
Read in a character
If the character is not special, CONTINUE
If the character is escaped (checking this probably requires examining the previous character), CONTINUE
If the character would start a new string or end an existing one, toggle a flag IN_STRING (you might need multiple flags for different string types... I've honestly tried and succeeded at remaining ignorant of the minutiae of SQL quoting/escaping) and CONTINUE
If the character is a semicolon AND we are not currently in a string, we have found a query! OUTPUT it and CONTINUE scanning until the end of the string.
Language parsing is not any of my areas of experience, so you'll want to consider that approach carefully; nonetheless, it's going to be fast (with C-style strings, none of those steps are at all expensive, save possibly for the OUTPUT, depending on what "outputting" means in your context) and I think it should get the job done.
maybe with the following Java Regexp? check the test...
#Test
public void testRegexp() {
String s = //
"SELECT 'hello;world' \n" + //
"FROM DUAL; \n" + //
"\n" + //
"SELECT 'hello;world' \n" + //
"FROM DUAL; \n" + //
"\n";
String regexp = "([^;]*?('.*?')?)*?;\\s*";
assertEquals("<statement><statement>", s.replaceAll(regexp, "<statement>"));
}
I would suggest seeing if you can redefine the problem space so the need to send multiple queries separated only by their terminator is not required.
Try this. Just replaced the 1st ' with \" and it seems to work for both ' and "
;+(?=([^\"|^\\']['|\\'][^'|^\\']['|\\'])[^'|^\\'][^'|^\\']$)