ON DUPLICATE KEY not working correctly - mysql

I am running the following query, but getting an error. I think it is coming from the ON DUPLICATE KEY part, but I'm not 100% sure what the correct syntax is to use there.
<?php
$form_id = $form->data['form_id'];
$cfid = $form->data['cf_id'];
$datesent = $form->data['datesent'];
$query = mysql_query("
INSERT INTO `email_history` (
`cf_id` ,
`$form_id`
)
VALUES (
'$cfid', '$datesent'
)
ON DUPLICATE KEY
UPDATE INTO
`email_history` (
`$form_id`
)
VALUES (
'$datesent'
);
") or die(mysql_error());
?>
EDIT
Using the following I am getting this error :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 10
<?php
$form_id = $form->data['form_id'];
$cfid = $form->data['cf_id'];
$datesent = $form->data['datesent'];
$query = mysql_query("
INSERT INTO `email_history` (
`cf_id` ,
`$form_id`
)
VALUES (
'$cfid', '$datesent'
)
ON DUPLICATE KEY
UPDATE `$form_id` = `$datesent`
);
") or die(mysql_error());
?>

The correct syntax of ON DUPLICATE KEY is something a long the lines described below.
Please note that it's just an example snippet, though it should be clear why your provided snippet fails to execute.
INSERT INTO tbl (
col1, col2, ... , colN
) VALUES (
#val1, #val2, ..., #valN
) ON DUPLICATE KEY UPDATE
col3 = VALUES(col3), col4 = #val4
Documentation
MySQL 5.0 Reference Manual :: 12.2.5.3 INSERT ... ON DUPLICATE KEY UPDATE Syntax
How would that look in my code?
$form_id = $form->data['form_id'];
$cfid = $form->data['cf_id'];
$datesent = $form->data['datesent'];
$query = mysql_query (<<<EOT
INSERT INTO `email_history` (`cf_id`, `$form_id`)
VALUES ('$cfid', '$datesent')
ON DUPLICATE KEY UPDATE `$form_id` = VALUES(`$form_id`)
EOT
) or die (mysql_error ());
What does VALUES($form_id) do?
It will yield the value of what was originally passed as the value for column named $form_id.
What is the use of <<<EOT?
In the previous snippet we are using a HEREDOC to have a string span multiple lines in an easy manner. You can read more about it in the documentation for heredocs.

Related

How to use `CONCAT` in a `UPDATE`

I´m trying to use CONCAT in a mysql UPDATE.
"INSERT INTO table (
objekt_nr,
objekt_status)
VALUES(
:objekt_nr,
'salj,$fakt')
ON DUPLICATE KEY UPDATE
objekt_status = VALUES(CONCAT(objekt_status, 'salj,$fakt'))";
$query_params = array(
':objekt_nr' => $_POST['objekt_nr']);
I have tried several:
objekt_status = VALUES(CONCAT(objekt_status, objekt_status))";
objekt_status = VALUES(CONCAT(objekt_status, 'addMe'))";
objekt_status = VALUES(CONCAT(objekt_status, 'salj,$fakt'))";
objekt_status = VALUES((CONCAT(objekt_status, 'salj,$fakt')))";
Error Code for:
objekt_status = VALUES(CONCAT(objekt_status, 'salj,$fakt'))";
...syntax to use near '(objekt_status, 'salj,fakt,'))'
How should the code look like?
You have an semicolon where there should be a comma (after VALUES(objekt_nr);), and it appears the apostrophe is in the wrong place on the last line at $fakt. VALUES is only required for the INSERT, manual here
This query should be correct:
"INSERT INTO table (
objekt_nr,
objekt_status)
VALUES(
:objekt_nr,
'salj,$fakt')
ON DUPLICATE KEY UPDATE
objekt_nr = objekt_nr,
objekt_status = CONCAT(objekt_status, 'salj,$fakt')";
Also please ensure your variables are escaped, or use a prepared statement.
Try removing values as well as semicolon from the query
"INSERT INTO table (
objekt_nr,
objekt_status)
VALUES(
:objekt_nr,
'salj,$fakt')
ON DUPLICATE KEY UPDATE
objekt_nr = objekt_nr,
objekt_status = CONCAT(objekt_status, 'salj,'$fakt)";
Actually in my case i needed the "Values" for every line but the CONCAT line.
objekt_created_when = VALUES(objekt_created_when),
objekt_status = CONCAT(objekt_status, 'salj,$fakt') ";
If i did remove VALUES from all rows, values in db, got empty!

Save multiple queries to sql database

I am trying to save multiple queries into a database on two different tables. Below is the code that I have tried to no avail. firsttable.a is the same as secondtable.id, con holds the connection info, and everything saves perfectly with one query. Is there something I am missing here?
if(empty($id)){
$uuid = uniqid();
$query = "INSERT INTO firsttable (`id`, `a`, `b`, `uuid`) VALUES (NULL, '$a', '$b', '$uuid')";
$query2 = "INSERT INTO secondtable (`id`, `c`, `d`, `uuid`) VALUES (NULL, '$c', '$d', '$uuid')";
}else{
$query = "UPDATE `firsttable` SET `id` = '$id', `a` = '$a', `b` = '$b', `uuid` = '$uuid' WHERE `id` = $id";
$query2 = "Update INTO secondtable SET `id` = '$a', `c` = '$c', `d` = '$d',
if(!mysqli_multi_query($this->_con, $query;$query2)){
throw new Exception( mysqli_error($this->_con) );
mysql_multi_query takes two arguments: the database connection, and a single string.
You need to concatenate your two queries together as a string:
mysqli_multi_query($this->con, $query1 . ';' . $query2);
or what you were probably trying to do:
mysqli_multi_query($this->con, "$query1;$query2");
From the php documentation on how to retrieve the result sets for the subsequent queries:
To retrieve the resultset from the first query you can use mysqli_use_result() or mysqli_store_result(). All subsequent query results can be processed using mysqli_more_results() and mysqli_next_result().
The first example shows how it all works.
In your example, though, the correct syntax is UPDATE tablename ..., not UPDATE INTO tablename ....

SQL Error in INSERT and UPDATE

I have fought with this the last two hours and my head hurts..
I get this error:
You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near '' at line 7
This is my table http://i.imgur.com/5KzxxbR.png
This is my query:
if(!is_int($_POST['x']) || !is_int($_POST['x'])) break;
$q = mysql_query("
INSERT INTO `bit-board`
(value, type, x, y)
VALUES(
'".$_POST['post-it']."',
'post-it',
'".$_POST['x']."',
'".$_POST['y']."'
)"
);
echo mysql_error() ? mysql_error:mysql_insert_id();
And the second one:
if(!is_int(intval($_POST['x'])) || !is_int(intval($_POST['x'])) || !is_int(intval($_POST['id']))) break;
$q = mysql_query("
UPDATE `bit-board`
SET
value = '".$_POST['post-it']."',
type = 'post-it',
x = '".$_POST['x']."',
y = '".$_POST['y']."'
WHERE id = '".$_POST[id]."'
");
Thanks
X and Y are floats, so don't put quotes around a numeric value.
Also check the comment from #a_horse_with_no_name about quoting the table name.
$q = mysql_query("
INSERT INTO `bit-board`
(value, type, x, y)
VALUES(
'".$_POST['post-it']."',
'post-it',
".$_POST['x'].",
".$_POST['y']."
)"
);
(Not tested)

Cancel Insert if inner query find nothing

I got the following query :
INSERT INTO contracts_settings (contract_id, setting_id, setting_value)
VALUES (:contract_id, (
SELECT setting_id
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
), :setting_value)
ON DUPLICATE KEY UPDATE setting_value = :setting_value
The value with the prefix : is replaced with data using PHP PDO::bindBalue.
If the inner query find nothing (it return NULL) but also INSERT a NULL statement. How to avoid that ?
Thanks.
Convert the INSERT ... VALUES syntax to INSERT ... SELECT:
INSERT INTO contracts_settings
(contract_id, setting_id, setting_value)
SELECT
:contract_id,
setting_id,
:setting_value
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
ON DUPLICATE KEY UPDATE
setting_value = :setting_value ;

generating MD5 idHash directly in MySQL statement

In my table I have an userID that is auto-incremented. In the same row I have an idHash. Is it possible to generate the idHash (simply an MD5 sum) from it directly with the same INSERT statement so that I don't have to SELECT the id, and then UPDATE the idHash again?
Problem is: I do not know the userID before it is being generated (auto-incremented) by MySQL.
Thanks
Frank
PS: I'm using PHP.
PPS: This question is all about a SINGLE INSERT. I know that I can use PHP or other languages to manually select the data and then update it.
I don't believe you can do it within a single INSERT statement.
What you probably could do is use an INSERT trigger, that both determines the new ID, hashes it, and then updates the record.
One solution I can recommend is using the last insert ID instead of re-querying the table. Here is a simplified example:
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "INSERT INTO users VALUES (....)";
$mysqli->query($query);
$newUserID = $mysqli->insert_id;
$query = "UPDATE users SET idHash = MD5(userID) WHERE userID = $newUserID";
$mysqli->query($query);
/* close connection */
$mysqli->close();
?>
AFAIK there's no "secure" way for doing this in the same query if you're using auto_increment.
However, if rows are never deleted in your table, you can use this little trick :
insert into mytable (col1, col2, col3, idhash)
values ('', '', '', md5(select max(id) from mytable))
I don't understand why you need to hash the id though, why not use the id directly ?
This seems to work for me:
CREATE TABLE tbl (id INT PRIMARY KEY AUTO_INCREMENT, idHash TEXT);
INSERT INTO tbl (idHash) VALUES (MD5(LAST_INSERT_ID() + 1));
SELECT *, MD5(id) FROM tbl;
Note this will only work on single-row inserts as LAST_INSERT_ID returns the insert ID of the first row inserted.
Performing MD5(column_name) on an auto_increment value does not work as the value has not been generated yet, so it is essentially calling MD5(0).
PHP snippet
<?
$tablename = "tablename";
$next_increment = 0;
$qShowStatus = "SHOW TABLE STATUS LIKE '$tablename'";
$qShowStatusResult = mysql_query($qShowStatus) or die ( "Query failed: " . mysql_error() . "<br/>" . $qShowStatus );
$row = mysql_fetch_assoc($qShowStatusResult);
$next_increment = $row['Auto_increment'];
echo "next increment number: [$next_increment]";
?>
This will get you the next auto-increment and then you can use this in your insert.
Note: This is not perfect (Your method is imperfect as you will effectively have 2 primary keys)
From: http://blog.jamiedoris.com/geek/560/