Related
I want to add a row to a database table, but if a row exists with the same unique key, I want to update the row.
Here is my query:
$query = "INSERT INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('$audit_no','$form_details_subquestion_id','$form_details_section_id','$mark')
ON DUPLICATE KEY UPDATE mark = VALUES($mark)";
But, it will keep on inserting new record. Let's say audit_section_id, form_details_subquestion_id, form_details_section_id is unique key. If audit_section_id, form_details_subquestion_id, form_details_section_id exists it will not insert new record into the database; while update the record.
I also tried this:
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`)
VALUES ('$audit_no','$form_details_subquestion_id','$form_details_section_id','$mark')
I not sure is that the for loop problem of my code.
for ($i=0; $i < ($_POST['count']); $i++)
{
$form_details_subquestion_id = $_POST['form_details_subquestion_id'][$i];
$form_details_section_id = $_POST['form_details_section_id'][$i];
$mark = $_POST['mark'][$i];
$remark = $_POST['remark'][$i];
//$query = "INSERT INTO `table` (`id`, `name`, `email`) VALUES (' ".$_POST['id']." ', ' ".$_POST['name']." ', ' ".$_POST['email']." ')";
$query = "REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`)
VALUES ('$audit_no','$form_details_subquestion_id','$form_details_section_id','$mark')";
$result = $db->query($query);
}
I'm using for loop to insert all the data.
Here is the output for echo $query;
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','89','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','86','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','87','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','88','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','85','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','83','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','84','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','81','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','82','1','1.00')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','98','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','99','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','100','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','101','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','102','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','96','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','97','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','90','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','91','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','92','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','93','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','94','1','2')
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','95','1','2')
SQL table
CREATE TABLE IF NOT EXISTS `audit_section_markrecord` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`audit_section_id` int(10) unsigned NOT NULL,
`form_details_subquestion_id` int(10) unsigned NOT NULL,
`form_details_section_id` int(10) unsigned NOT NULL,
`mark` decimal(5,2) unsigned NOT NULL,
`dateofmodify` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
)
Edit after your last question edit:
you have in your table this:
`id` int(11) NOT NULL AUTO_INCREMENT,
....
PRIMARY KEY (`id`)
Your id (PRIMARY KEY) is autoincremental and your question is:
I want to add a row to a database table, but if a row exists with the
same unique key, I want to update the row.
With your querys your never will have the same id because you never set the id value in your query, your query is:
REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`) VALUES ('602633','95','1','2')
and if you don't set the id value in your query the database system autoincrement automatically the id column value, and you never will have to update a row.
This should be your query:
$query = "REPLACE INTO audit_section_markrecord(`audit_section_id`,`form_details_subquestion_id`,`form_details_section_id`,`mark`)
VALUES ('$audit_no','$form_details_subquestion_id','$form_details_section_id','$mark')";
But the audit_section_id, form_details_subquestion_id and form_details_section_id column values must match those of an existing row for the row to be replaced; otherwise, a row is inserted.
You can read more at:
http://dev.mysql.com/doc/refman/5.7/en/replace.html
EXAMPLE:
Consider the table created by the following CREATE TABLE statement:
CREATE TABLE test (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(64) DEFAULT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
When you create this table and run the statements shown in the mysql client, the result is as follows:
mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)
mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)
mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts |
+----+------+---------------------+
| 1 | New | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)
Now if you create a second table almost identical to the first, except that the primary key now covers 2 columns, as shown here (PRIMARY KEY (id, ts)):
CREATE TABLE test2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(64) DEFAULT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id, ts)
);
When you run on test2 the same two REPLACE statements as we did on the original(first) test table, we obtain a different result:
mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.05 sec)
mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.06 sec)
mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts |
+----+------+---------------------+
| 1 | Old | 2014-08-20 18:47:00 |
| 1 | New | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.00 sec)
This is due to the fact that, when run on test2, both the id and ts column values must match those of an existing row for the row to be replaced; otherwise, a row is inserted.
I have birthday column as a date defined in my table. When i insert a person and left blank birthday field, i get 0000-00-00 and i want to get NULL values. when i insert date as birthday i get date, which is fine.
i tried :
Create table (
birthday DATE NULL,
birthday DATE DEFAULT NULL,
birthday DATE NULL DEFAULT NULL,
);
doesn't work, please a little advice to get NULL instead of 0000-00-00 in my birthday fields.
my php script:
$q = "INSERT INTO users (birthday, other_column, data_registration) VALUES ('$birthday', '$other_column', NOW())
i get no solution yet, any ideea please?
What is in your $birthday?
Suppose you have $birthday = null or $birthday = "null", you will get 0000-00-00. This is because when it's passing to your query, it becomes something like (I believe it's treating your 'null' or null as a string, because you have single quotes around it):
INSERT INTO users (birthday, other_column, data_registration) VALUES ('null', '$other_column', NOW())
Instead try this, which the 2 single quotes around $birthday are removed:
$q = "INSERT INTO users (birthday, other_column, data_registration) VALUES ($birthday, '$other_column', NOW())
Here is an alternative fix:
if ($birthday) {
$q = "INSERT INTO b (birthday, other_column, data_registration) VALUES ('$birthday', '$other_column', NOW())";
} else {
$q = "INSERT INTO b (birthday, other_column, data_registration) VALUES (DEFAULT, '$other_column', NOW())";
}
if you use birthday DATE DEFAULT NULL, in your create statemnt and use
INSERT INTO users (other_column) VALUES ( '$other_column')
You should get null´inbirthday` column.
If you want to EXPLICITLY insert null into the table, then you will need to insert NULL from PHP.
If you want to leave the table to assume its default value, then either OMIT the column from the insert clause entirely, or otherwise use the literal DEFAULT which will apply the default.
e.g.
CREATE TABLE Person
(
Name VARCHAR(20),
BirthDate DATE DEFAULT NULL -- Redundant, since a NULLABLE column will default NULL
);
INSERT INTO Person(Name) VALUES('Joe'); -- Default, NULL
INSERT INTO Person(Name, BirthDate) VALUES('Joe', NULL); -- Explicit Null
INSERT INTO Person(Name, BirthDate) VALUES('Joe', DEFAULT); -- Default, NULL
SqlFiddle example here
If the date in PHP you are inserting is 0000-00-00, then you will need to apply logic in your code to either substitute NULL, DEFAULT for the column, or omit the column (or I guess use a trigger, but this is a hack)
I have two mysql insert statements. The one with all the fields specified in insert statement works fine and insert record to testTable.(Even when http_referer is empty the insert statement insert records to table with referer field empty)
First Insert statement with all fields specified:
mysql_query("INSERT INTO testTable VALUES('$ID','".$_SERVER['REMOTE_ADDR']."',NOW(),'Page1','".$_SERVER['HTTP_REFERER']."')");
The problem is with second insert statement that doesn't insert any record to testTable!
Could you guys tell me why my second insert statement doesn't insert any record to testTable?
Second insert Statment:
mysql_query("INSERT INTO testTable VALUES('$ID','".$_SERVER['REMOTE_ADDR']."',NOW(),'Page1')");
Create Table:
CREATE TABLE IF NOT EXISTS `testTable` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(32) DEFAULT NULL,
`date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`Title` varchar(32) NOT NULL,
`Ref` varchar(250) NULL default '',
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1784 ;
Yes, by using a column list.
$sql = "INSERT INTO table (`ip`, `date`, `Title`) VALUES ('".$_SERVER['REMOTE_ADDR']."', NOW(), 'Page 1')";
Please, don't use mysql_* functions in new code. They are no longer maintained and are officially deprecated. See the red box? Learn about prepared statements instead, and use PDO, or MySQLi - this article will help you decide which.
You can choose to specify which columns you want to insert into in an insert statement.
$sql = "INSERT INTO testTable(ID, ip, date, Title)
VALUES('$ID','".$_SERVER['REMOTE_ADDR']."',NOW(),'Page1')";
Additionally, please don't use mysql functions as they are deprecated now. Use MySQLi, or PDO
You have to specify the fields with the second query. If you're not going to insert every column, in the order of the columns, then you have to specify the column names.
INSERT INTO table (column1, column2, columns3) VALUES ('$value1', '$value2', '$value3');
You can use a column list or SET syntax
Column list:
INSERT INTO table (column1, column2) VALUES ('$value1', '$value2');
SET syntax:
INSERT INTO table SET column1 = '$value1', column2 = '$value2';
In first query error not comes because you are specifying all column and fieleds.If any filed is auto increment or by default null you should mention all the column name along with values in insert query accepting null of auto increment field
this are demo with
All field value
insert into testtable values (1,"127.1.1.0",curdate(),"test 1","default");
Without Default value
insert into testtable (id,ip,date,title) values (1,"127.1.1.0",curdate(),"test 1");
without auto increment field
insert into testtable (ip,date,title) values ("127.1.1.0",curdate(),"test 1");
It is not as easy as the title itself. I have a table users which has a field assignedlessons. Data stored in this field is like 69|308|50|91. As you may have already know, it keep several lessons of a user has at the same time. What I am going to do is to export data from this field along with user_id and import to another newly created table user_assigned_elearning_lessons. The structure of this table is: id, user_id, elearning_lesson_id, created_at. After the importing, the structure in the new table should be like this:
id user_id elearning_lesson_id created_at
1 1 69 2011-01-12
2 1 308 2011-04-11
3 2 50 2011-05-18
4 3 91 2011-05-21
5 3 50 2011-07-18
6 3 308 2011-07-18
How do I do that?
Probably you'll want to look into using INSERT ... SELECT FROM syntax. Without full details of the source and destination tables, we can't help beyond that.
Despite what others have suggested, you can't do what you want with INSERT ... SELECT syntax, because you've to split values and insert more than one row for each row of the source table.
You can instead write a short PHP script to do the job, I've assumed the following table structure and test data:
CREATE TABLE IF NOT EXISTS `users` (
`user_id` int(11) NOT NULL,
`assignedlessons` varchar(100) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `users` (`user_id`, `assignedlessons`) VALUES
(1, '69|308|50|91'),
(2, '56|34|7');
CREATE TABLE IF NOT EXISTS `user_assigned_elearning_lessons` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`elearning_lesson_id` int(11) NOT NULL,
`created_at` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;
With a PHP script you can loop over all the rows of the first table, explode the composite field into its parts and do an INSERT statement for each of those part. I've used mysqli object oriented style with prepared statements to build the insert queries.
<?php
main();
function main() {
$source = new mysqli("localhost", "username", "password", "database");
$destin = new mysqli("localhost", "username", "password", "database");
$stmt = prepareInsertStatement($destin);
$result = $source->query("SELECT user_id, assignedlessons FROM users");
while ($user = $result->fetch_object()) {
insertUser($stmt, $user);
}
$result->close();
$source->close();
$destin->close();
}
function insertUser(&$stmt, &$user) {
$lessons = explode('|', $user->assignedlessons);
foreach ($lessons AS $lesson) {
$stmt->bind_param("ii", $user->user_id, $lesson);
$stmt->execute();
echo "User " . $user->user_id . " lesson $lesson<br/>";
}
}
function &prepareInsertStatement(&$destin) {
$sql = "INSERT INTO user_assigned_elearning_lessons
(user_id, elearning_lesson_id, created_at) VALUES (?, ?, NOW())";
$stmt = $destin->stmt_init();
$stmt->prepare($sql);
return $stmt;
}
?>
I bind the parameters to the the prepared statement with bind_param:
$stmt->bind_param("ii", $user->user_id, $lesson);
Where the "ii" means that the type of those parameters is integer and integer.
The output with this test data will be:
User 1 lesson 69
User 1 lesson 308
User 1 lesson 50
User 1 lesson 91
User 2 lesson 56
User 2 lesson 34
User 2 lesson 7
You could use syntax like:
INSERT INTO tbl2 (col1, col2, col3, ....)
SELECT col1, col2, col3
FROM tbl1
or check http://dev.mysql.com/doc/refman/5.1/en/insert-select.html for further details.
I have a simple mysql DB and use this PHP code to update it.
mysql_query("REPLACE INTO `$db_table` (username, live, datetime, ip)
VALUES ('$username', '1', '$timeofentry', '$ip')");
I use REPLACE INTO along with a primary key on "username" to let users bump themselves to the top of the most recent list...
I would like to add a bump count. The number of times an entry has been updated (or "replaced into").
How would I go about doing this?
Thanks a lot!
You can use INSERT ... ON DUPLICATE KEY UPDATE which performs an actual update of existing rows.
$mysql = mysql_connect(..
...
$username = mysql_real_escape_string(...
$ip = mysql_real_escape_string(...
...
$query = "
INSERT INTO
`$db_table`
(username, live, datetime, ip)
VALUES
(
'$username',
'1',
'$timeofentry',
'$ip'
)
ON DUPLICATE KEY UPDATE
ip = '$ip',
bumpCount = bumpCount + 1
";
$result = mysql_query($query, $mysql);
First, you need to add another column to your table to keep the count.
Second, you should probably use the UPDATE statement instead of REPLACE.
REPLACE will actually delete the row, then INSERT a new one which isn't very efficient.
UPDATE `$db_table` SET datetime = NOW(), ip = '$IP',
bumpCount = bumpCount + 1 WHERE username = '$username' LIMIT 1;
#dot
You'd define your bumpCount field as another column in the table. I'd recommend setting it to a default value as well.
Then your table definition would be sometime like:
CREATE TABLE my_table
(username varchar(255) not null primary key,
live int,
datetime datetime not null,
ip varchar(15) not null,
bumpCount int unsigned not null default 1);
And your insert/update would be something like:
INSERT INTO my_table (username,live,datetime,ip)
VALUES
('$username',1,now(),'$ip')
ON DUPLICATE KEY UPDATE datetime=now() ip='$ip', bumpCount=bumpCount + 1;