I have an issue where I can only insert data into my table once. If i delete the row and insert a new one, it works but if I already have a row and try to insert another one, it doesn't work. No errors in the console or network.
I'm inserting with this:
<?php
error_reporting(E_ALL);
include 'DB.php';
$con = mysql_connect($host,$user,$pass)
or die("Error: ".mysql_error());
$dbs = mysql_select_db($databaseName, $con);
$name = mysql_real_escape_string($_POST['name']);
$date = date('Y-m-d');
$amount = $_POST['amount'];
$timPaid = $_POST['timPaid'];
$rennyPaid = $_POST['rennyPaid'];
$sql = "INSERT INTO $tableName (`name`, `date`, `amount`, `timpaid`, `rennypaid`)
VALUES ('$name', '$date', '$amount', '$timPaid', '$rennyPaid')";
$result = mysql_query($sql, $con)
or die("Error: ".mysql_error());
mysql_close($con);
?>
I'm thinking it might have to do with how my table is set up, primary key and such. I have an id column which is the primary and I think it's auto-increment, can't tell.
Since you are not sure about whether the id field is auto-increment or not, you should alter your table like this,
ALTER TABLE `yourtable`
MODIFY COLUMN `id` int(11) NULL AUTO_INCREMENT FIRST;
the result FROM SHOW CREATE TABLE tableName would help.
I would guess you have a unique index on on of your fields and you are trying to insert a second record with the same value.
Also CHECK TABLE tablename could help identify the problem.
I had this... I had set my first column as 'unique' and my 'Insert' didn't involve that column.
As a result the 'Insert' added a value of zero into the 'Unique' column (I'd set that column to 'integer').
When I did another insert 'I THINK' that the 'Insert' wanted to add another zero in the 'Unique' column that I wasn't 'Inserting' into, so it tried to 'Insert' another zero, BUT because that column was 'unique' it wouldn't allow another zero and refused the 'Insert'.
I proved this by changing the first 'Inserts' entry into the 'Unique' column manually to another 'Integer' then the 'Insert; statement worked one more time.... repeat process above as described and my table allowed another 'Insert'.
Hope this makes sense and helps?.
I had a similar problem, however mine was where I was using the INT data type in my create table script for storing a 13-digit long number, and it only wanted to accept something 10-digits in size. Changing this to a VARCHAR(13) fixed the problem for me.
Related
I have a table with 3 columns (ID, username, full name), I want the ID to be AUTOINCREMENT. I want to insert into the table only if it does not already exist in the table.
This is my Code:
$fullName = $_POST['fullname'];
$username = $_POST['username'];
$dbhost = "localhost";
$dbname = "databasename";
$dbusername = "root";
$dbpassword = "";
$link = new PDO("mysql:host=$dbhost;dbname=$dbname","$dbusername","");
$statement = $link->prepare('INSERT INTO accounts (username, fullname)
VALUES (:username, :fname)');
$statement->execute([
'fname' => $fullName,
'username' => $usernameget,
]);
If your id is already autoncrement then you no need to mention in query.
You can simply write below query
insert into accounts (username,fullname) values( $username , $fullname )
you can do this with if else condition in PHP
$fullname = $_POST['fullname'];
$username = $_POST['username'];
$chk = mysqli_query("select * FROM `accounts` where fullname='$fullname' and username='$username'");
$rs = mysqli_fetch_array($chk);
if($rs == "")
{
$ins = mysqli_query("INSERT INTO `accounts`(fullname,username) VALUES ('$fullname','$username'))";
}
else{
echo "Duplicate entry";
}
or you can do this by SQL Query also.
INSERT INTO accounts(username,fullname)
SELECT * from (SELECT '$username', '$fullname') AS tmp
WHERE NOT EXISTS
(SELECT username FROM accounts WHERE username='$username')
There's several things to fix here.
Don't specify column values if you don't need to, or don't care about the value. Only specify if necessary or relevant. In this case id should be omitted.
Always use placeholder values for your user data. Never put $_GET or $_POST data directly in a query.
To avoid duplication add a UNIQUE constraint on the table.
To fix that you do adjust your code:
// Enable exceptions, avoiding the need for manual error checking
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
// Try and keep the order of things like this consistent through your code
$username = $_POST['username'];
$fullname = $_POST['fullname'];
// Here using a short, common name for the database handle $db
$db = new mysqli("localhost","root","","database");
// Prepare your insert first as a query with no data, only placeholders
$db->prepare("insert into accounts (username,fullname) values(?,?)");
// Bind the data to the placeholders, here two string ("s") values.
$db->bind_param('ss', $username, $fullname);
// Execute the query
$db->execute();
To add the UNIQUE constraints use CREATE INDEX:
CREATE INDEX idx_accounts_username (username);
CREATE INDEX idx_accounts_full_name (full_name);
That has to be run in your MySQL shell, not PHP.
When a UNIQUE constraint is in place MySQL will not allow duplicate data. Note that NULL values don't count, and can be "duplicated". Set NOT NULL on your columns to force them to be completely unique.
As your id is autoincrement primary key, so you can create or update it with:
insert into accounts (username,fullname) values( $username , $fullname ) on duplicate key update username = '$username',fullname = '$fullname'
To get correct answers, a question must be asked with as much explanation as possible. you should atleast tell what have you done and then what are you getting.
As far as i have understood, to achieve your goal, the table structure must be changed and inserting query also.
Remember to accept the answer and click the upvote button if the answer satisfies you,else give more information in the question, so that members here, can give right answers.
If you understand table creating queries go to bottom of this answer or else do as follows:
if you use gui to create table,
1. click on create new table.
2. in the right pane give table name and column names as shown. (dont give space in 'full name' instead give 'full_name' or 'fullname')
3. scroll the winow to the right till you see A_I column as shown.
4. tick the first line (which we have used as id), 'add index' box will appear.
just click here go (at the bottom).
you will be redirected to table list as shown.
6. open (click) your table again.
7. click on structure.
now suppose you don't want duplicates in 'username' column, click this column and click on 'unique' as shown
if you don't want duplicate when both the columns' value together, click both the columns and then click 'unique' as shown
if you understand create table commands:here is the sql for above:
CREATE TABLE accounts (
id int(11) NOT NULL AUTO_INCREMENT,
username varchar(25) NOT NULL,
fullname varchar(55) NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY username (username)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
with above table structure records will be autoincremented and duplicate names will not be added. (remember to handle duplicate entries error in you inserting querie withINSERT IGNORE INTOwith this your query will be:
$statement = $link->prepare('INSERT IGNORE INTO accounts (username, fullname)
VALUES (:username, :fname)');
or you can also useON DUPLICATE KEY)
First set your primary key (eg. id) if not set as auto increment
Second use multiple insertion value
INSERT IGNORE INTO accounts (username,fullname) VALUES ("p","k"),("c","s");
IGNORE keyword is use to duplicate
IF you want to see with PDO
I've been stuck on this for a few hours now ...
Here's my code:
$SQLQuery1 = $db_info->prepare("SELECT COUNT(ID) FROM menusize WHERE typesize=:typesize");
$SQLQuery1->bindValue(':typesize',$_POST['typesize'],PDO::PARAM_STR);
$SQLQuery1->execute();
if($SQLQuery1->fetchColumn() > 0) {
$SQLQuery2 = $db_info->prepare("INSERT INTO menucatagorysize (menucatagory_ID,menusize_ID) VALUES (:catagoryid,(SELECT ID FROM menusize WHERE typesize=:typesize))");
$SQLQuery2->bindValue(':typesize',$_POST['typesize'],PDO::PARAM_STR);
$SQLQuery2->bindValue(':catagoryid',$_POST['catagoryid'],PDO::PARAM_STR);
$SQLQuery2->execute();
} else {
$SQLQuery2 = $db_info->prepare("INSERT INTO menusize (typesize) VALUES (:typesize);
SET #menusizeid=LAST_INSERT_ID();
INSERT INTO menucatagorysize (menusize_ID,menucatagory_ID) VALUES (#menusizeid,:catagoryid)");
$SQLQuery2->bindValue(':typesize',$_POST['typesize'],PDO::PARAM_STR);
$SQLQuery2->bindValue(':catagoryid',$_POST['catagoryid'],PDO::PARAM_STR);
$SQLQuery2->execute();
}
$SQLQuery3 = $db_info->prepare("SELECT DISTINCT(menuitem_ID) FROM menuprice WHERE menucatagory_ID=:catagoryid");
$SQLQuery3->bindValue(':catagoryid',$_POST['catagoryid'],PDO::PARAM_STR);
$SQLQuery3->execute();
$rows = $SQLQuery3->fetchAll(PDO::FETCH_ASSOC);
So, it will run through the if statement fine, running $SQLQuery1 and $SQLQuery2 (Which ever one is required) without any problems, errors or warnings. But, if it runs the else { part of the code, it will not run $SQLQuery3. Any thoughts?
Thanks :D
EDIT: Got it to work by doing $SQLQuery2=NULL in the else statement ... Sucks that I still cant figure out why it wouldnt work the original way.
It appears that you're trying to enforce a uniqueness constraint over the typesize column of your menusize table from within your application code. However, the database can do this for you—which will make your subsequent operations much simpler:
ALTER TABLE menusize ADD UNIQUE (typesize)
Now, one can simply attempt to insert the posted value into the table and the database will prevent duplicates arising. Furthermore, as documented under INSERT ... ON DUPLICATE KEY UPDATE Syntax:
If a table contains an AUTO_INCREMENT column and INSERT ... ON DUPLICATE KEY UPDATE inserts or updates a row, the LAST_INSERT_ID() function returns the AUTO_INCREMENT value. Exception: For updates, LAST_INSERT_ID() is not meaningful prior to MySQL 5.1.12. However, you can work around this by using LAST_INSERT_ID(expr). Suppose that id is the AUTO_INCREMENT column. To make LAST_INSERT_ID() meaningful for updates, insert rows as follows:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
Therefore, you can do:
$db_info->prepare('
INSERT INTO menusize (typesize) VALUES (:typesize)
ON DUPLICATE KEY UPDATE typesize=LAST_INSERT_ID(typesize)
')->execute(array(
':typesize' => $_POST['typesize']
));
$db_info->prepare('
INSERT INTO menucatagorysize
(menusize_ID, menucatagory_ID)
VALUES
(LAST_INSERT_ID(), :catagoryid)
')->execute(array(
':catagoryid' => $_POST['catagoryid']
));
$stmt = $db_info->prepare('
SELECT DISTINCT menuitem_ID
FROM menuprice
WHERE menucatagory_ID = :catagoryid
');
$stmt->execute(array(
':catagoryid' => $_POST['catagoryid']
));
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
// etc.
}
(As an aside, the English word is spelled cat*e*gory, not cat*a*gory.)
Let me explain what I need and canot get :(
I have to DB one i main the other is just getting part of data from the firs one.
This is my code:
foreach($id_product_array AS $id_product) {
$resultf = mysql_query("SELECT * FROM db1_available_product WHERE id_product='".$id_product."'");
while($rowi = mysql_fetch_array($resultf)) {
$aa1=$rowi['id_product'];
$aa2=$rowi['date'];
$aa3=$rowi['available'];
$aa4=$rowi['published'];
mysql_query("INSERT INTO aa_bb.db2_available_product (`id_product`, `date`, `available`, `published`) VALUES ('".$aa1."','".$aa2."', '".$aa3."', '".$aa4."') ON DUPLICATE KEY UPDATE `id_product` = '".$aa1."', `date` = '".$aa2."', `available` = '".$aa3."', `published` = '".$aa4."'");
}
The problem is that this multiples the record in DB2 so I am now in millions!!!
Its set up as cron job on 1h basis.
What I need is ether it checks what is existing and don't touch it or if need on update or insert.
The other solution would be to delete the whole table in DB2 then to insert a fresh one from DB1
You can simplify your query like so:
INSERT INTO tbl2 (column1, column2)
SELECT column1, column2 FROM tbl1
ON DUPLICATE ...
See the documentation
You are looking for MySQL's proprietary REPLACE command. It has the same syntax as a regular INSERT, but it checks for duplicate primary key before inserting, and if it is found it will do an UPDATE instead:
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.
Of course you will have to define a unique PK/index on your table that allows this functionality to work.
here is an update!
I solved the problem :)
Thanks s to Niels because he made me rethink my strategy so the solution was simple.
In the DB1 and DB2 there is and ID filed
A added
$aa5=$rowi['id'];
so that made ON DUPLICATE KEY UPDATE work correctly!
foreach($id_product_array AS $id_product) {
$resultf = mysql_query("SELECT * FROM db1_available_product WHERE id_product='".$id_product."'");
while($rowi = mysql_fetch_array($resultf)) {
$aa5=$rowi['id'];
$aa1=$rowi['id_product'];
$aa2=$rowi['date'];
$aa3=$rowi['available'];
$aa4=$rowi['published'];
mysql_query("INSERT INTO aa_bb.db2_available_product (`id`,`id_product`, `date`, `available`, `published`) VALUES ('".$aa5."','".$aa1."','".$aa2."', '".$aa3."', '".$aa4."') ON DUPLICATE KEY UPDATE `id` = '".$aa5."',`id_product` = '".$aa1."', `date` = '".$aa2."', `available` = '".$aa3."', `published` = '".$aa4."'");
}
and it seams that it is working OK!
:)
I want to insert a new row in my table. I want the id to be generated right automatically and not asked from the user. The user only provides title and text. I wrote this code in PHP:
<?php
$hostname = "localhost";
$database = "mydb";
$username = "myuser";
$password = "mypsw";
$link = mysql_connect( $hostname , $username , $password ) or
die("Attention! Problem with the connection : " . mysql_error());
if (!$link)
{
die('Could not connect: ' . mysql_error());
}
mysql_query("SET NAMES ‘utf8’",$link);
mysql_select_db("mydb", $link);
$lastid=mysql_insert_id();
$lastid=$lastid+1;
$sql="INSERT INTO announcements VALUES ('$lastid',CURDATE(),'$_POST[title]','$_POST[text]')";
if (!mysql_query($sql,$link))
{
die('Error: ' . mysql_error());
}
mysql_close($link);
header("Location: announcement.php");
?>
Sadly when I test it on my website, I get this error:
Error: Duplicate entry '0' for key 'PRIMARY'
Is mysql_insert_id() not working? What is wrong?
Don't do this. mysql will happily create an auto_increment column for you:
CREATE TABLE x (
id int not null primary key auto_increment
^^^^^^^^^^^^^^---add this to your PK field
);
INSERT INTO x (id) VALUES (null); // creates id = 1
INSERT INTO x (id) VALUES (null); // creates id = 2
mysql_insert_id() only returns the last id created by the CURRENT connection. You haven't inserted any data yet when you first run it, so you get back nothing.
Your version is incredibly vulnerable to race conditions. There is NO guarantee that the last ID you retrieve with mysql_insert_id() will not ALSO get retrieved by another copy of the script running in parallel, and get sniped out from under this copy of the script.
The primary key column on announcements should be auto_increment. When you do mysql_insert_id() it retrieves the id from the last query executed from that connection.
Because the INSERT is the query you are currently performing, it errors.
Try
INSERT INTO announcements
(date_field, title, text)
VALUES (CURDATE(),'$_POST[title]','$_POST[text]')
Just replace 'date_field', 'title', and 'text' with the applicable column names.
Alternatively the following should also work, as a NULL value in the AutoIncrement value should be acceptable
INSERT INTO announcements VALUES (NULL,CURDATE(),'$_POST[title]','$_POST[text]')
As mentioned in the other suggestion posted, you should make sure that the primary key field of the announcements table is set to be auto_increment.
Just for completion, you would use mysql_insert_id() when you want to use the id for the row you just inserted, i.e. if you then want to select the row you just inserted you could do
'SELECT * FROM announcements WHERE id = '.mysql_insert_id()
The problem is that you are asking for last insert id and you didn't inserted anything.
Convert your ID field in db to be autoincrement if its not.
Insert into database your announcment
Then ask for id using mysql_insert_id to get it.
But I see that you are not using it only when inserting then you don't need that functionality anyhow. Just insert without ID like this
"insert into announcements (InsertDate, Title, Text) VALUES (CURDATE(), '$_POST[title]', '$_POST[text]')";
and you should really be careful with your queries when using values from $_POST or $_GET or any other user typed value. There is possibility to execute SQLInjection through your form fields, so I suggest you to use mysql escape command or use parameters.
I hope this helps.
Assuming your table is set up properly, with the id field as AUTO_INCREMENT, you just need to perform an INSERT where you do not specify a value for id. That means you must specify the names of the columns you are inserting. So this line:
$sql="INSERT INTO announcements VALUES ('$lastid',CURDATE(),'$_POST[title]','$_POST[text]')";
becomes this
$sql="INSERT INTO announcements (`date`,`title`,`text`) VALUES (CURDATE(),'$_POST[title]','$_POST[text]')";
I guessed what your column names might be. Obviously they need to match your table definition.
If you do this, then the mysql_insert_id() function will return the id of the row you just inserted. (That is, it gives you the value of the previous insert, not the next one.)
You probably want to add "auto increment" to the table when creating it.
This will add an id automatically when inserting something.
e.g.
CREATE TABLE announcements
(
id int NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
some_date int(11),
title varchar(200),
text varchar(3000)
);
mysql_insert_id "Retrieves the ID generated for an AUTO_INCREMENT column by the previous query " - http://php.net/manual/en/function.mysql-insert-id.php
Im trying to write a function to check whether a user exists in a table, if so, update the row, if not, insert it.
Here is my function:
function UserExists($screenname){
$mysql = mysql_fetch_array ( mysql_query("SELECT * FROM `users` WHERE `screenname` = '$screenname' "));
if($mysql){
return TRUE;
}else{
return FALSE;
}
}
And im executing this function using the following:
if(UserExists($user)){
mysql_query("UPDATE `users` SET `token` = '$token' , `secret` = '$secret' WHERE `screenname` = '$user' ");
}else{
mysql_query("INSERT INTO `users` (`screenname`, `token`, `secret`) VALUES ('$user', '$token', '$secret')");
}
Its not doing anything, not throwing any errors, but also not updating the table.
You'd want to take a look at the INSERT ... ON DUPLICATE KEY UPDATE ... MySQL query syntax to make this work with just one query.
INSERT INTO users (screenname, token, secret) VALUES ('screenname', 'token', 'secret')
ON DUPLICATE KEY UPDATE token = 'token', secret = 'secret'
screenname should be unique (or a primary key) which you probably don't have at the moment. I suggest to add an ID column in your database table and use that to refer to database rows.
Your best solution is ON DUPLICATE KEY as JoostK stated
Call mysql_error after the calls to see what error you are getting. Also another good debugging technique is to execute it on the server using a MySQL client such as mysqlfront or phpMyAdmin.
I'd simply suggest to use REPLACE INTO SET col = val in this case, all you need to do is define a unique index on the table.
The Replace Command will have a look at the unique indexes, if a row already exists it will update the existing, if not it will insert a new one.