Does the insert query need three quotation marks? - mysql

I frequently see (in this forum and elsewhere) SQL insert queries wrapped in three consecutive quotation marks, example:
query = """INSERT INTO test (value0, value1) VALUES (%s, %s)"""
mycursor.execute(query, ("foo","bar"))
I want to be able to iterate over table names. So when I use one quotation mark only, the query works just as well.
table1 = "test1"
query = "".join(("INSERT INTO ", table1," (value0, value1) VALUES (%s, %s)"))
mycursor.execute(query, ("foo","bar"))
Which syntax is correct now?

Triple quotes are used for strings that span multiple lines. They're a convenient shorthand to write readable indented code in strings. If your string is just one line you don't need them and 'abc' == '''abc''' (same with double quotes).
See the following example of a longer query string:
"select column1, column2, column3 "\
"from table1 t1"\
" join table2 t2 on t1.some_id_field = t2.another_id_field "\
"where column4 = 1"\
" and column5 is not null"\
" -- and so on"
This is a lot of typing and error prone if you forget the trailing ' ' (so that you get ... column3from ...). The same with triple quotes is much easier to read and write:
"""select column1, column2, column3
from table1 t1
join table2 t2 on t1.some_id_field = t2.another_id_field
where column4 = 1
and column5 is not null
-- and so on
"""
P.S.: Instead of
table1 = "test1"
query = "".join(("INSERT INTO ", table1," (value0, anycode) VALUES (%s, %s)"))
I'd always use
query = f"INSERT INTO {table1} (value0, anycode) VALUES (%s, %s)"
because it's not only easier to read but it makes it far less probable to forget the spaces around the table name.

Related

Truncated incorrect DOUBLE value error on SQL statement?

I'm trying to append a string to an existing record in a MySQL Database:
UPDATE `db`.`tbl` SET field1 = IFNULL(field1, '') + ',' + '12/15/16: $50' WHERE field2 = 'xyz'
In MySQL, + is exactly what it suggests: addition. You are getting an error on arithmetic presumably because the strings are not converted to a number (fortunately -- otherwise you would silently get the wrong answer).
So, try this:
UPDATE `db`.`tbl`
SET field1 = CONCAT(COALESCE(field1, ''), ',', '12/15/16: $50')
WHERE field2 = 'xyz';
Or, if you don't want the comma if field1 is NULL:
UPDATE `db`.`tbl`
SET field1 = CONCAT(COALESCE(CONCAT(field1, ','), ''), '12/15/16: $50')
WHERE field2 = 'xyz';
to append in MySQL, use concat not + eg
select concat('something', 'something_else');
returns
somethingsomething_else
you can also use concat_ws (with separator)
select concat_ws('#','something', 'something_else')
returns
something#something_else

MySQL Regex Replace Query

I have a field with this value:
TEST:ATEST:TESTA
And I want to replace "TEST" with "NEW", I have tried this query:
UPDATE `table` SET `field` = REPLACE(`field`, 'TEST', 'NEW') WHERE `field` REGEXP 'TEST';
The result was:
NEW:ANEW:NEWA
Q: How could I do the replacement query so the result would be like this:
NEW:ATEST:TESTA
It is a bit of a pain, but you can do it this way:
UPDATE `table`
SET field = substr(REPLACE(concat(':', field, ':'), ':TEST:', ':NEW:'),
2, length(REPLACE(concat(':', field, ':'), ':TEST:', ':NEW:')) - 2)
WHERE concat(':', field, ':') LIKE '%:TEST:%';
I prefer LIKE to REGEXP because there is the hope of being able to use an index. That is not a possibility in this case, but there is the hope.
This is delimiting the values with colons at the beginning and the end, and only replacing fully delimited values. The trick is to then remove the additional colons.
You can try http://sqlfiddle.com/#!9/4e66b/3
so the update query is (if table name = table1, field name = field1, and there is unique column id):
UPDATE `table1`
INNER JOIN
(SELECT id,
#set_idx:=FIND_IN_SET('TEST',REPLACE(field1,':',',')),
#set_size:=LENGTH(field1)-LENGTH(REPLACE(field1,':',''))+1,
CASE
WHEN #set_idx=1 THEN CONCAT('NEW',SUBSTRING(field1, 4))
WHEN #set_idx>1 THEN CONCAT(SUBSTRING_INDEX(field1, ':',#set_idx-1),':NEW', IF(#set_size>#set_idx,CONCAT(':',SUBSTRING_INDEX(field1, ':',-(#set_size-#set_idx))),''))
END as new
FROM table1
WHERE `field1` REGEXP '(^TEST$)|(^TEST:)|(:TEST$)|(:TEST:)'
) t
ON t.id = table1.id
SET table1.field1 = t.new;

Concatenation with case statement in mysql

I want to generate .sql file with the sql query output . I am doing this with concat statement in sql . I am using case statement in some queries this will be the problem for me.
select concat('insert into x values(',CASE a when B then 'Book' else 'NONE' end , ') on duplicate key update B = values(B)') from author;
select 'insert into x values('+CASE a when B then 'Book' else 'NONE' end +') on duplicate key update B = values(B)' from author;
It also not works because in mysql + used for adding only numbers not for strings .
Is there any way for doing this?.
The problem with the first version is the quotes of things within the string. For instance, you want your string to contain "'Book'"
select concat('insert into x values(',
(CASE a when 'B' then '''Book''' else '''NONE''' end) ,
') on duplicate key update B = values(''B'')'
)
from author;
I think this quotes al the strings as they should be. I'm guess column A is a character that should be compared to 'B' and not to column B.

MySQL, Concatenate two columns

There are two columns in a MySQL table: SUBJECT and YEAR.
I want to generate an alphanumeric unique number which holds the concatenated data from SUBJECT and YEAR.
How can I do this? Is it possible to use a simple operator like +?
You can use the CONCAT function like this:
SELECT CONCAT(`SUBJECT`, ' ', `YEAR`) FROM `table`
Update:
To get that result you can try this:
SET #rn := 0;
SELECT CONCAT(`SUBJECT`,'-',`YEAR`,'-',LPAD(#rn := #rn+1,3,'0'))
FROM `table`
You can use mysql built in CONCAT() for this.
SELECT CONCAT(`name`, ' ', `email`) as password_email FROM `table`;
change field name as your requirement
then the result is
and if you want to concat same field using other field which same then
SELECT filed1 as category,filed2 as item, GROUP_CONCAT(CAST(filed2 as CHAR)) as item_name FROM `table` group by filed1
then this is output
In php, we have two option to concatenate table columns.
First Option using Query
In query, CONCAT keyword used to concatenate two columns
SELECT CONCAT(`SUBJECT`,'_', `YEAR`) AS subject_year FROM `table_name`;
Second Option using symbol ( . )
After fetch the data from database table, assign the values to variable, then using ( . ) Symbol and concatenate the values
$subject = $row['SUBJECT'];
$year = $row['YEAR'];
$subject_year = $subject . "_" . $year;
Instead of underscore( _ ) , we will use the spaces, comma, letters,numbers..etc
In query, CONCAT_WS() function.
This function not only add multiple string values and makes them a single string value. It also let you define separator ( ” “, ” , “, ” – “,” _ “, etc.).
Syntax –
CONCAT_WS( SEPERATOR, column1, column2, ... )
Example
SELECT
topic,
CONCAT_WS( " ", subject, year ) AS subject_year
FROM table
I have two columns:
prenom and nom so to concatenate into a column with name chauffeur_sortant I used this script:
SELECT date as depart, retour, duree_mission, duree_utilisation, difference, observation, concat( tb_chaufeur_sortant.prenom, ' ', tb_chaufeur_sortant.nom) as chauffeur_sortant, concat(tb_chaufeur_entrant.prenom, ' ', tb_chaufeur_entrant.nom) as chauffeur_entrant
FROM tb_passation
INNER JOIN tb_vehicule
ON tb_vehicule.id = tb_passation.id_vehicule
INNER JOIN tb_chaufeur_sortant
ON tb_chaufeur_sortant.id = tb_passation.id_sortant
INNER JOIN tb_chaufeur_entrant
ON tb_chaufeur_entrant.id = tb_passation.id_entrant WHERE tb_vehicule.id = '';
$crud->set_relation('id','students','{first_name} {last_name}');
$crud->display_as('student_id','Students Name');

snprintf truncates the last sign

Consider the following code:
char *myContent = "content";
int size = snprintf(NULL, 0, "INSERT INTO myTable (col1) VALUES('%s')",myContent);
char *query = malloc(size+2);
snprintf(query, size, "INSERT INTO myTable (col1) VALUES('%s')",myContent);
Now I have the problem that the last bracket is truncated:
(gdb) print query
$2 = 0x616080 "INSERT INTO myTable (col1) VALUES('content'"
This is not a valid SQL statement, so have you an idea what the reason could be that the last bracket is missing?
snprintfreturns:
the number of characters printed (not including the trailing '\0' used to end output to strings)
But the size argument is:
and vsnprintf() write at most size bytes (including the trailing null byte ('\0'))
So you should:
char *query = malloc(size+1);
snprintf(query, size+1, "INSERT INTO myTable (col1) VALUES('%s')",myContent);
snprintf returns the size of the resulting string, not including the NULL terminator. I think you need to pass size+1 to the second snprintf.
What the others have said. But as myContent hasn't changed, it's safe to simply say:
sprintf(query, "INSERT INTO myTable (col1) VALUES('%s')",myContent);