Error: Duplicate entry '0' for key 'PRIMARY' - mysql

I can't resolve my problem, this is the error from mysql that I'm getting:
I can edit and update my data when I've got one record in the database but when I add two rows, I get the error.
Some pictures from database
And when I change the row, row ID goes down to 0 and that's is a problem as I can't edit other rows.
CREATE TABLE `dati` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`value1` varchar(255) NOT NULL,
`value2` varchar(255) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 PACK_KEYS=1
Update Code:
<?php // Izlabot datus datubāzē!
$titletxt = $_POST['title_edit'];
$value1 = $_POST['value1_edit'];
$value2 = $_POST['value2_edit'];
if(isset($_POST['edit'])){
$con=mysqli_connect("localhost","root","","dbname");
if (mysqli_connect_errno())
{
echo "Neizdevās savienoties ar MySQL: " . mysqli_connect_error();
}
$sql="UPDATE dati SET ID='$ID',title= '$titletxt',value1='$value1',value2='$value2' WHERE 1";
if (!mysqli_query($con,$sql))
{
die('Error: ' . mysqli_error($con));
}
echo '<script>
alert(" Ieraksts ir veiksmīgi labots! ");
window.location.href = "index.php";
</script>';
mysqli_close($con);
}
?>
From form:
<?php
$con=mysqli_connect("localhost","root","","dbname");
if (mysqli_connect_errno())
{
echo "Neizdevās savienoties ar MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM dati");
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td><input id='titled' type='text' name='title_edit' value='" . $row['title'] . "'></td>";
echo "<td><input id='value1d' type='text' name='value1_edit' value='" . $row['value1'] . "'></td>";
echo "<td><input id='value2d' type='text' name='value2_edit' value='" . $row['value2'] . "'></td>";
echo "<input type='hidden' name='id' value='" . $row['ID'] . "'>";
echo "<td><button name='edit' id='edit_btn' class='frm_btns' value='" . $row['ID'] . "'>Edit</button></td>";
echo "</tr>";
}
mysqli_close($con);
?>
It couldn't read the value of ID, as 0 was returned.

For those arriving at this question because of the question title (as I did), this solved my problem:
This error can indicate that the table's PRIMARY KEY is not set to AUTO-INCREMENT, (and your insert query did not specify an ID value).
To resolve:
Check that there is a PRIMARY KEY set on your table, and that the PRIMARY KEY is set to AUTO-INCREMENT.
How to add auto-increment to column in mysql database using phpmyadmin?

The error log like (In my case), I'm using Aurora DB:
PHP message: WordPress database error Duplicate entry '0' for key 'PRIMARY' for query INSERT INTO `date173_postmeta
How to fix it using MySQL Workbench:
1- Connect at your DB, and go to the table with the issue, in my case date173_postmeta
2- Select the tools icon:
3- In the windows/tab at right, select the AI checkbox and click on Apply button:
Following the last steps my issues gone.

The problem is that your code attempts to change every row in the data changing the primary key to the value in $ID. This is not set anywhere in your code, and presumably is being cast as 0
$sql="UPDATE `dati` SET `ID`='$ID',`title`=
'$titletxt',`value1`='$value1',`value2`='$value2' WHERE 1";
The primary key value should be sent to the form and returned so it can be processed by your code, but the value should be retained, hence....
$sql="UPDATE `dati` SET `title`=
'$titletxt',`value1`='$value1',`value2`='$value2' WHERE `ID`=$ID";
You should also read up on MySQL injection - even after you've fixed the errors here, anyone can do just about anything they want with your database.

Try this:
ID int(11) PRIMARY KEY AUTOINCREMENT(1,3)

The problem in set ID = $ID
Try removing it so the code should be
$sql="UPDATE `dati` `title`= '$titletxt',`value1`='$value1',`value2`='$value2' WHERE 1";
Be sure to change this where cause it'll update ever row with these values

Just make sure that your primery keys are also A-I.

I'd been struggling to fix this. My tables had auto increment (AI) switched on
Before I started tinkering with records I tried a simple repair in phpMyAdmin.
Go to the SQL tab and run each command in turn.
REPAIR TABLE wp_options
REPAIR TABLE wp_users
REPAIR TABLE wp_usermeta
This did the trick for me and allowed me to login.

i am using phpmyadmin,
so go to db , search for wp_postmeta tabel
add AI(auto-increment) to meta_id
save the changes

Related

Wordpress plugin creation how to execute .sql in order to insert multiple rows at activation of plugin

I am creating a wordpress plugin which upon activation i create my database table. I have an .sql file which has ~2000 rows of data and i would like to execute it after the creation of my database table. Which do you think is the best way to insert those data upon the plugin activation?
I know it is going to execute on activation hook - but is it possible to execute an .sql file or do i have to find another way and somehow execute each row through $wpdb->insert()?
If you need any further infomation please ask and i will provide - i also searched but couldn't find the same case.
Below is the best way by which you can achieve this as first it will initialize custom_create_plugin_tables and next it will initialize custom_insert_data_custom_table
register_activation_hook( __FILE__, 'custom_create_plugin_tables' )
register_activation_hook( __FILE__, 'custom_insert_data_custom_table' );
function custom_create_plugin_tables()
{
global $wpdb;
$table_name = $wpdb->prefix . 'table_name';
$sql = "CREATE TABLE $table_name (
id int(11) NOT NULL AUTO_INCREMENT,
column_two varchar(255) DEFAULT NULL,
column_three int(11) NOT NULL,
UNIQUE KEY id (id)
);";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
}
function custom_insert_data_custom_table()
{
global $wpdb;
$table_name = $wpdb->prefix . 'table_name';
$rows_affected = $wpdb->insert( $table_name, array( 'column_two' => "column_two_value", 'column_three' => 'column_three_value' ));
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $rows_affected );
}

Do i really need an auto increment id column?

I have a table structure with META_ID | KEY | VALUE | USER_ID where META_ID is auto-increment. Now in my php logic
1 get the result key-value pairs per user
2 delete the key value row per user
3 update or insert the key value pair for a already known USER_ID
4 insert key value pair for a new user
But the META_ID keeps growing, so i was wondering if i could just delete the META_ID column?
Case logic
An registered user or returning registered user can update their form over time if they haven't submit it yet. So overtime an user can select and deselect certain form options and update, insert or delete is triggered.
Now the logic behind "returning user deselects a key (and the row needs to be deleted)" gives me a problem. That's why i just delete all users key-value pairs. But what would be the right way?
So if the key-value exists in the db table but not in $params i need to delete it!
btw here's my function
function user_shopping_meta_data($params) {
global $wpdb;
$shopping_meta_table = 'wp_shopping_metavalues';
$wp_user_id = $params['wp_user_id'];
//1 CHECK IF USER HAS KEY VALUE PAIRS
$checkKeyValues = $wpdb->get_results("SELECT meta_shopping_key FROM $shopping_meta_table WHERE wp_user_id = '$wp_user_id'");
//2 WE DELETE
$qdel = $wpdb->delete($shopping_meta_table, array('wp_user_id' => $wp_user_id));
//3 UPDATE OR INSERT
foreach ($params as $key => $val) {
//variables
if (is_array($val)) {
$val = json_encode($val);
}
$shopping_meta_values = array(
'wp_user_id' => $wp_user_id,
'meta_shopping_key' => $key,
'meta_shopping_value' => $val
);
if (count($checkKeyValues) > 0) {//3 USER IS KNOWN SO UPDATE and/or INSERT new key-value
foreach ($checkKeyValues as $check) {
//UPDATE OR INSERT
if (($key != "wp_user_id")) {
//FOR UPDATE where
$shopping_meta_where = array('meta_shopping_key' => $key, 'wp_user_id' => $wp_user_id);
$result = $wpdb->get_results("SELECT * FROM $shopping_meta_table WHERE meta_shopping_key = '" . $key . "' AND wp_user_id = '$wp_user_id'");
if (count($result) > 0) {//KEY ALREADY EXISTS FOR USER
$return .= $wpdb->update($shopping_meta_table, array('meta_shopping_key' => $key, 'meta_shopping_value' => $val), $shopping_meta_where) . '<br/>';
//$return .= 'UDPATE<br/>';
} else {//KEY IS NEW
$return .= $wpdb->insert($shopping_meta_table, $shopping_meta_values) . '<br/>';
// $return .= 'INSERT for old';
}
}//.end $key
}//.end foreach checkKeyValue
}//.end count
else {//4 INSERT KEY VALUE PAIR FOR NEW USER
if (($key != "wp_user_id")) {
$return .= $wpdb->insert($shopping_meta_table, $shopping_meta_values) . '<br/>';
// $return .= 'INSERT NEW';
}
}
}//.end each
echo 'Test return: ' . $return;
}
You won't gain much by deleting it. You might think that you save some space, but in fact you don't. An auto_increment column is always also (part of) the primary key. If you delete it, MySQL will create an "implicit" primary key, which is not visible but necessary for MySQL to identify rows. Also you will lose some comfort like not being able to use LAST_INSERT_ID().
You can very well delete it. It is just a unique ID. If you can distinguish different rows without the META_ID or you do not need to distinguish rows, then META_ID is redundant.
If i can give you a suggest is better to leave that field as a history.
If you need to want to know what is the last action done for that user you can order by META_ID.
Is usefull to have a primary key in a table. But this is just a suggest
I suggest you have a primary key that you are sure of that it is unique. It is a good idea to use a auto-increment column for this because you will always be sure that it is unique.

how to know insert in mysql failed due to duplicate primary key

I am inserting records in user_table with user_email as primary key.
$result = mysqli_query($db, "insert into user_table(user_full_name, user_email, user_password) values('".$fullnames."','".$emails."','".$passs."')");
How to know that insert failed due to duplicate primary key, without quering once again to user_table
mysqli_errno(), function can help you,
try this
if (!$result )
{
if(mysqli_errno($con) == 1062){
echo "duplicate entry";
}else{
echo("Error description: " . mysqli_error($con));
}
}
For More error code :https://dev.mysql.com/doc/refman/5.0/en/error-messages-server.html
I can answer my question myself.
after query
I can check
if( mysqli_errno($db) == 1062 ) {
""*DUPLICATE PRIMARY KEY**
}

How to adjust ID column after deleting a records from HTML table?

On my index.php page I have HTML table which shows data (authors and their books) from two different database tables (author and book). First column in the HTML table is ID from the Book table.
The problem is, when I delete a book from index.php page (using delete button inside HTML table), the ID column doesn't "fill" the gap which shows up after deleting a record.
For example, if I have 5 rows in HTML table with ID's 1, 2, 3, 4, 5, and if I delete third row, the ID column would show up 1, 2, 4, 5; So, I would like the column to "adjust itself" to the new situation and go 1, 2, 3, 4 (because there are no more five books in the table).
Any ideas how to do it?
Here's the code:
// Loading all authors
$Authors = array();
$result = mysqli_query ($db, "select * from Author");
if (!$result)
die (mysqli_error ($db));
while ($Author = mysqli_fetch_object ($result))
$Authors[$Author->ID] = $Author;
// Loading all books
$result = mysqli_query ($db, "select * from Book");
if (!$result)
die (mysqli_error ($db));
// Listing all the data
while ($Book = mysqli_fetch_object ($result))
{
echo "<tr>";
echo "<td> {$Book->ID} </td>";
echo "<td> {$Authors[$Book->Author_ID]->Name} </td>";
echo "<td> {$Book->Title} </td>";
echo "<td> {$Book->Publisher} </td>";
echo "<td> {$Book->Year} </td>";
echo "</tr>";
}
I am using MySQL server 5.5.34 (MySQL community server GPL)
One author may have written more then one book
Author_ID is foreign key in Book table
You shouldn't display the IDs at all. Database IDs are not meant to be tampered with.
You might use CSS to not have to bother with the numbers at all. Check this out:
table {
counter-reset: rowNumber;
}
table tr {
counter-increment: rowNumber;
}
table tr td:first-child::before {
content: counter(rowNumber);
min-width: 1em;
margin-right: 0.5em;
}
http://jsfiddle.net/davidThomas/7RyGX/
This is just a suggestion. I don't say this is the best solution. Just consider.
You execute your delete query.
DELETE FROM table_name WHERE ID = 3;
Once deleted you make a select query request with PHP and get the data set to an array.
SELECT id, Name from table_name ORDER BY ID ASC;
Then make a UPDATE execution using a loop.
$id = 1;
foreach($dataset as $item)
{
// Your update query
$sql = "UPDATE table_name SET ID=$id where Name='" . $item['Name'] . "'";
$id++;
}
Before you insert next query you have to get the max value of id and set +1 value as the id of the insert query. This is just an idea. Not the complete code.
don't post the IDs. Instead use a variable that counts the columns to be displayed then use for loop to print the variable.

special mysql query from a joomla website

I have this context:
CREATE TABLE `atdees` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`params` text NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `atdees` (`id`, `params`) VALUES
(1,'{"field282":"0","field347":"1"}'),
(2,'{"field282":"0","field347":"0"}'),
(3,'{"field282":"0"}');
I have to extract from the table the rows where :
an atdee must have the string '"field282":"0"'
an atdee has the string '"field282":"0"' but not the string '"field347":"0"'
an atdee has both string '"field282":"0"' and '"field347":"0"'
In other words I have to extract the Id 2 and 3.
Thank you.
Ps: Sorry for my english, I am not a native speaker ;)
edit: well i found my query
SELECT id
FROM atdees
WHERE
INSTR(`params`, '"field282":"0"') > 0 and
( params LIKE '%"field347":"0"%' OR
INSTR(`params`, '"field347"') = 0 )
If it's simply getting data from the database, then you can use something like this:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('id'));
$query->from($db->quoteName('#__atdees'));
$query->where($db->quoteName('params') . " = " . $db->quote('"field282":"0"') . "OR" . $db->quote('"field347":"0"'));
$db->setQuery($query);
$results = $db->loadObjectList();
foreach ( $results as $result ) {
echo "<p>" . $result->id . "</p>";
}
Not sure if the database table is for a Joomla extensions but if so, keep it as #__atdees in your query, else change to atdees
Hope this helps