I am trying to make an SQL query that :
IF the $post_id exists then it updates the records,
IF NOT then then it creates the record
Here is my code
$vote_new_total = $vote_total + $vote;
$vote_count = $vote_count + 1;
$query = " INSERT INTO cute_review_vote (vote_total, vote_count)
VALUES ('$vote_new_total', '$vote_count')
ON DUPLICATE KEY UPDATE vote_total = $vote_new_total, vote_count = $vote_count
WHERE post_id = $post_id";
mysql_query($query) or trigger_error(mysql_error()." in ".$sql);
However, I keep getting the following error:
Notice: 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 'WHERE post_id = 214748364' at line 4 in in C:\xampp\htdocs\xbm-vote\do_vote.php on line 68
Is this an issue with my syntax or am I missing something more obvious than that?
Any help/advice would be greatly appreciated. Thanks.
There is no where with ON DUPLICATE statement. Always check syntax: http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
Also, that is not a secure query. Turn that into a prepared statement.
http://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php
EDIT: Updating answer since OP didn't understand usage of ON DUPLICATE statement:
ON DUPLICATE will consider that you're trying to insert a KEY value.
Consider the example table:
CREATE TABLE `user` (
`email` varchar(50) NOT NULL,
`name` varchar(20) NOT NULL,
`is_active` tinyint(4) NOT NULL,
`datecreated` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`email`)
);
And the query:
INSERT INTO user (email, name, is_active) VALUES ("user#user.com", "User", 1)
ON DUPLICATE KEY UPDATE name = "User Edited", is_active = 0
Since we're setting PRIMARY KEY as email, and the insert statement is inserting a key, then, at the second time you run the query, ON DUPLICATE would run once a email is already on the table, because it is the KEY and you are trying to insert it again, but you defined a ON DUPLICATE KEY ....
If a table runs with a AUTO_INCREMENT column, is most likely you have to SELECT post_id applying some filter with WHERE statement.
Ok, I found my problem.
INSERT INTO cute_review_vote (post_id, vote_total, vote_count)
VALUES ('$post_id', '$vote_new_total', '$vote_count')
ON DUPLICATE KEY UPDATE vote_total = $vote_new_total, vote_count = $vote_count
I realized, thanks to Fabiano, that the WHERE clause is not required.
WHERE post_id = $post_id"
Is simply replaced by defining the database entry within the INSERT INTO command.
Related
I have created a database composed of three tables. This is my query in creating my tables with Foreign Key.
CREATE TABLE reporter
(
reporterid INT NOT NULL AUTO_INCREMENT,
firstname VARCHAR(1000) NOT NULL,
lastname VARCHAR(100) NOT NULL,
PRIMARY KEY (reporterid)
);
CREATE TABLE flood
(
floodid INT NOT NULL AUTO_INCREMENT,
address VARCHAR(500) NOT NULL,
description VARCHAR(1000) NOT NULL,
dateofflood DATE NOT NULL,
timeofflood INT NOT NULL,
PRIMARY KEY (floodid)
);
CREATE TABLE reports
(
reportid INT NOT NULL AUTO_INCREMENT,
timereport NODATATYPE NOT NULL,
datereport DATE NOT NULL,
rid INT NOT NULL,
fid INT NOT NULL,
PRIMARY KEY (reportid),
FOREIGN KEY (rid) REFERENCES reporter(reporterid),
FOREIGN KEY (fid) REFERENCES flood(floodid)
);
I created a system in order for me to add records/row on my database through PHP. This is my code:
<?php
mysql_connect("localhost", "root", "") or die("Connection Failed");
mysql_select_db("flooddatabase")or die("Connection Failed");
$description = $_POST['description'];
$address = $_POST['address']; // Make sure to clean the
$dateofflood=$_POST['dateofflood'];
$timeofflood=$_POST['timeofflood'];
$firstname=$_POST['firstname'];
$lastname=$_POST['lastname'];
$dateofreport=$_POST['dateofreport'];
$timeofreport=$_POST['timeofreport'];
$query = "INSERT into flood(address,description,dateofflood,timeofflood) values ('$address','$description','$dateofflood','$timeofflood')";
$query2 = "INSERT into reporter(firstname,lastname) values ('$firstname','$lastname')";
$query3 = "INSERT into reports(dateofreport,timeofreport) values ('$dateofreport','$timeofreport')";
if(mysql_query($query))
if(mysql_query($query2))
if(mysql_query($query3))
{
echo "";
} else
{
echo "fail";
}
?>
The result that I am getting is fine. It's just that, in my REPORTS table, there is no foreign key that is being generated. For example I input something on my reporter table and flood table, the foreign key 'rid' and 'fid' has no values that references to both tables. Need help thank you.
Get the just inserted Primary key value from flood table insert
query. And store it to a variable say $f_id;
Get the just inserted primary key value from reporter table insert
query and store it to a variable say $r_id;
Now Make your last insert statement like below:
"INSERT into reports(dateofreport,timeofreport,rid,fid) values ('$dateofreport','$timeofreport',$r_id,$f_id)";
I am not giving you a direct copy paste solution.
If you need to know how to get the last inserted id by executing an insert query then look at this link
there is no foreign key that is being generated
I'm not entirely sure what you even mean by that. Foreign keys aren't "generated". Primary keys can be, which you do:
reporterid INT NOT NULL AUTO_INCREMENT
(as well as for your other two tables)
the foreign key 'rid' and 'fid' has no values
Well, look at your query:
INSERT into reports(dateofreport,timeofreport) values ...
Where do you insert values for rid and fid? I'm actually pretty surprised this query works at all, since those columns don't allow NULL values:
rid INT NOT NULL,
fid INT NOT NULL,
(Though your column names also don't line up, so I find it likely that the code you're showing isn't actually the code you're using...) That point aside however, the fact still remains that if you want a value in those fields then you have to put a value in those fields:
INSERT into reports(dateofreport,timeofreport,rid,fid) values ...
After each query, you can get the last generated identifier from mysql_insert_id():
$last_id = mysql_insert_id();
Use that to then populate the values being inserted as foreign keys in subsequent queries.
Also worth noting, the mysql_* libraries are long since deprecated and have been replaced with mysqli_ and other libraries such as PDO. I highly recommend you upgrade to a current technology, since what you're using isn't supported by any vendor.
Additionally, and this is very important, your code is wide open to SQL injection attacks. This basically means that you execute any code your users send you. You should treat user input as values, not as executable code. This is a good place to start reading on the subject, as is this.
In my MySQL database I have a table "table1" with unique constraint set on column "name" - I want to prevent duplicate names.
If there's already name 'John' in table this code:
$db=new mysqli(...);
$sql="INSERT INTO table1 SET id=10,name='John'";
if(!$db->query($sql))
{
if($db->errno==1062)
{
throw new InsertNonUniqueException(...);
}
else
{
throw new InsertException(...);
}
}
should throw InsertNonUniqueException() (my own exception). Instead, it throws InsertException().
Execution of query returns false and execution enters the if() loop. Also $db->row_affected is -1 but problem is that $db->errno is always O (it should be 1062)!!! So I can't detect that my insert error was caused by violating unique key constraint on name column!
I don't know why mysqli does not return 1062 code when unique key constraint violation occurs!
I can't leave a comment, thus going to ask you here.
Please provide the result of SHOW CREATE TABLE table1;
I can't reproduce your problem using your code and next table:
CREATE TABLE `table1` (
`name` varchar(11) COLLATE utf8_unicode_ci NOT NULL,
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Am I the only one around here that thinks you have an error in your SQL syntax?.. There is no room for SET in INSERT INTO, because you can only use SET in UPDATE statements (assuming you habe MySQL in version 5.5 or below).
INSERT INTO syntax is like the following (as described in the docs):
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE col_name=expr, ... ]
OR
INSERT INTO tbl_temp2 (fld_id)
SELECT tbl_temp1.fld_order_id
FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
Try it like this:
<?php
$sql="INSERT INTO table1 (id, name) VALUES ('10', 'John')";
...
step 1
make sure that the table has a unique key
SHOW CREATE TABLE table1
expected result
CREATE TABLE `table1` (
`id` INT(11) default NULL,
`name` varchar(11) COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
if there is UNIQUE KEY name (name) we have a unique key
step 2
try to change your code
$db = new mysqli(...);
// first insert
if( !$db->query("INSERT INTO table1 (id, name) VALUES (10, 'John')") ) {
throw new Exception($db->error);
}
// second insert (for me raise: Duplicate entry 'John' for key 'name')
if( !$db->query("INSERT INTO table1 (id, name) VALUES (11, 'John')") ) {
throw new Exception($db->error);
}
Please, try these two steps
Side note: if you have name and id as duplicates, only the first duplicate encountered will be returned in the message.
The only issue i have with your code is that:
having setup your table and columns.
I setup a unique index on the table. I did .. stuff on a two column table that ensure it works.
You missed the 'new'
keyword when you 'throw exceptions'.
this is the only error with your posted code that i could find.
i.e: throw new Exception('Division by zero.'); // example taken from PHP manual.
php
$dnumber = '9515551212';
$device_id = 'f3847010927038970110923';
device is a text field
phnum (I have used bigint, text, varchar) all give the same result.
mysql_query("INSERT INTO devices(device, phnum) VALUES('$device_id', '$dnumber')");
the above query is TRUE but the value in phnum will be empty.
mysql_query("INSERT INTO devices(device, phnum) VALUES('$device_id', $dnumber)");
the above query is FALSE, but it still inserts the record perfectly! I also get error 1064 near ")" (I removed the quotes from $dnumber)
So why is the first saying it succeeded but didnt put anything there while second says it fails but it inserted it as I wanted it to?
I think, there's something with incoming data. SQL works well.
I tried that query from php:
$sql = "INSERT INTO test(device_id, phnum) VALUES('$device_id', '$dnumber')";
$res = mysql_query($sql);
For the table with the following structure:
CREATE TABLE `test` (
`phnum` int(30) unsigned NOT NULL AUTO_INCREMENT,
`device_id` varchar(256) NOT NULL DEFAULT '',
PRIMARY KEY (`phnum`)
) ENGINE=InnoDB AUTO_INCREMENT=4294967295 DEFAULT CHARSET=utf8;
It worked well without any warnings. From SQL client - the same, works well.
If there is a row for user_id then I want to update, if not insert (but I was told to use replace). In the table there is id (which is primary key, auto inc) and user_id (index, session relates to). I have a form that when the data is changed it should be changed in the database for that particular user in session, otherwise it is just added for that particular user in session
if (empty($err)) {
$thesis_Name = mysql_real_escape_string($_POST['thesis_Name']);
$abstract = mysql_real_escape_string($_POST['abstract']);
$query="UPDATE thesis SET thesis_Name ='$thesis_Name',
abstract='$abstract' WHERE id='$_SESSION[user_id]'
IF ROW_COUNT()=0
REPLACE INTO thesis (thesis_Name,abstract)VALUES ('$thesis_Name', '$abstract')
";
mysql_query($query) or die();
// query is ok?
if (mysql_query($the_query, $link) ){
// redirect to user profile
header('Location: myaccount.php?id=' . $user_id);
}
With this the page just dies.
EDIT:
`thesis` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`thesis_Name` varchar(200) NOT NULL,
`abstract` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
)
Thanks so much
You don't need to do the UPDATE first - REPLACE handles all of this for you. From the MySQL manual:
REPLACE works exactly like INSERT, except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted. See Section 13.2.5, “INSERT Syntax”.
Therefore, so long as id is a unique key in your thesis table, the only SQL you need is:
REPLACE INTO thesis (id, thesis_Name, abstract)
VALUES ('$_SESSION[userid]', '$thesis_name', '$abstract');
There are a few things in your code that pose problem. First you don't have to do an insert and a replace in the same query : replace will insert if there is no row to replace (besides, I'm not even sure the sql syntax you're using is correct)...
Then you do a mysql_query($query) or die() which is probably where your code dies (maybe due to the fact that the sql syntax you used could be incorrect).
Right after that, you do a mysql_query again, which would reexecute the query a second time. Anyway, if your query didn't work, your code would have died on the previous line...
What you could do would be
$query = "REPLACE INTO blablabla";
if (!mysql_query($query))
echo "the query failed";
else header ("location:blabla");
but your query should mention for which user_id you want to update like this
REPLACE INTO thesis (id, thesis_Name, abstract)
VALUES ('{$_SESSION[userid]}', '$thesis_name', '$abstract');
INSERT
INTO thesis (id, abstract, thesis)
VALUES ('$_SESSION[user_id]', '$abstract', '$thesis_Name')
ON DUPLICATE KEY
UPDATE
abstract = VALUES(abstract),
thesis_Name = VALUES(thesis_Name)
You can do it with prepared statements.You can see an example sql ;
DROP PROCEDURE IF EXISTS `UPDATETHESIS`
|
CREATE PROCEDURE `UPDATETHESIS` (IN _id VARCHAR(50), IN _thesis_name VARCHAR(50), IN _abstract VARCHAR(50))
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY INVOKER
IF EXISTS (SELECT * FROM thesis WHERE id = _id)
BEGIN
UPDATE thesis SET thesis_Name = _thesis_name,
abstract = _abstract WHERE id = _id
END
ELSE
BEGIN
INSERT INTO thesis (thesis_Name,abstract) VALUES (_thesis_name, _abstract)
END
You can call this like CALL UPDATETHESIS(userid, thesis_name, abstratc);
I created the following table for user to user subscriptions.
CREATE TABLE IF NOT EXISTS `subscriptions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`subscribed_to` int(11) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_subscription` (`user_id`,`subscribed_to`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=76 ;
I'm disallowing identical rows by making the columns user_id and subscribed_to unique. If a user tries to resubmit the same data I get:
A Database Error Occurred Error Number: 1062
Duplicate entry '62-88' for key 'unique_subscription'
INSERT INTO subscriptions (user_id, subscribed_to, date) VALUES ('62',
'88', '2011-07-11 19:15:13')
Line Number: 330
I'm preventing the database error by checking if an identical row exists before trying to insert data.
$query = "SELECT COUNT(*) FROM subscriptions WHERE (user_id = '62' AND subscribed_to = '88')";
if ($query > 0)
{
//display already subscribed message
}
else
{
//insert new row
}
The database already checks the table and returns an error. The select count(*) query above seems redundant. Do I really need to check the table once more in my application? Is there a way to capture the database error if it occurs, and do something with that in my application?
If you have an idea how please share an example. I haven't a clue how this is done..!
Check out PHP function mysql_error
You can wrap the db call within a try catch statement for functions that throw exceptions to prevent your application from crashing.
PHP function mysql_query does not throw exception on error, but returns FALSE. You can check the return value and execute mysql_error to find out the trouble or log it.