Unable to insert into database despite specifying a default constraint on column - mysql

I have the following table in MySQL database:
mysql> describe student;
+------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| name | varchar(50) | YES | | NULL | |
| dob | date | YES | | NULL | |
| reg_no | varchar(20) | NO | PRI | NULL | |
| department | varchar(50) | YES | | NULL | |
| branch | varchar(50) | YES | | NULL | |
| semester | int(11) | YES | | 1 | |
+------------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)
When I try to insert into this database without specifying the last value (i.e.semester), it results in an error
mysql> insert into student values('John Smith','1990-01-01','123ABC','Chemistry','Organic Chemistry');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
Why is this not working? Isn't that the whole point of having a default constraint? That the value specified as default gets assigned if it isn't present in the insert query.
If I write the query like this, it works:
mysql> insert into student values('John Smith','1990-01-01','123ABC','Chemistry','Organic Chemistry',DEFAULT);
Query OK, 1 row affected (0.01 sec)
What is happening? Is my syntax wrong? I would like to be able to insert the record without having to specify 'DEFAULT'

If you are not adding values to all the table columns you should specify which columns you add data.
Example:
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
So in your case,
INSERT INTO student(name, dob, regno, department, branch)
VALUES ('John Smith','1990-01-01','123ABC','Chemistry','Organic Chemistry');

your syntax is wrong while inserting default values,so instead of that query use insert into student(name,dob,reg_no,department,branch)values('John Smith','1990-01-01','123ABCF','Chemistry','Organic Chemistry');

Related

MySQL INSERT shows more affected rows than affected

Consider the following three queries.
The first one can only return a single row as bids_buy.id is the primary key.
The second one shows an existing record in entities_has_documents for primary key 3099541982-2536988132, and the third one doesn't execute due to that existing record.
The forth one does execute as expected, but shows two affected rows.
Why does it show two affected rows, and not just one associated with primary key 3099541982-2536988132?
mysql> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798;
+--------------+------------+----------+---------------------+-----------+
| bids_sell_id | 2536988132 | pub_bids | NOW() | 506836355 |
+--------------+------------+----------+---------------------+-----------+
| 3099541982 | 2536988132 | pub_bids | 2016-04-16 08:19:13 | 506836355 |
+--------------+------------+----------+---------------------+-----------+
1 row in set (0.00 sec)
mysql> SELECT * FROM entities_has_documents;
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
| entities_id | documents_id | type | date_added | date_removed | added_by | removed_by | purged_by | date_purged |
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
| 2453409798 | 2536988132 | pub_bids | 2016-04-16 08:07:13 | NULL | 506836355 | NULL | NULL | NULL |
| 3099541982 | 2536988132 | pub_bids | 2016-04-16 08:18:53 | NULL | 506836355 | NULL | NULL | NULL |
+-------------+--------------+----------+---------------------+--------------+-----------+------------+-----------+-------------+
2 rows in set (0.00 sec)
mysql> INSERT INTO entities_has_documents(entities_id,documents_id,type,date_added,added_by)
-> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798;
ERROR 1062 (23000): Duplicate entry '3099541982-2536988132' for key 'PRIMARY'
mysql> INSERT INTO entities_has_documents(entities_id,documents_id,type,date_added,added_by)
-> SELECT bb.bids_sell_id, 2536988132,"pub_bids", NOW(),506836355 FROM bids_buy bb WHERE bb.id=2453409798
-> ON DUPLICATE KEY UPDATE type="pub_bids", added_by=506836355, date_added=NOW(), removed_by=NULL, date_removed=NULL;
Query OK, 2 rows affected (0.00 sec)
Records: 1 Duplicates: 1 Warnings: 0
mysql> EXPLAIN bids_buy;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | NO | PRI | NULL | |
| bids_sell_id | int(10) unsigned | NO | MUL | NULL | |
| stage_buy_id | int(10) unsigned | NO | MUL | NULL | |
+--------------+------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> EXPLAIN entities_has_documents;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| entities_id | int(10) unsigned | NO | PRI | NULL | |
| documents_id | int(10) unsigned | NO | PRI | NULL | |
| type | varchar(16) | NO | MUL | NULL | |
| date_added | datetime | NO | | NULL | |
| date_removed | datetime | YES | | NULL | |
| added_by | int(10) unsigned | NO | MUL | NULL | |
| removed_by | int(10) unsigned | YES | MUL | NULL | |
| purged_by | int(10) unsigned | YES | MUL | NULL | |
| date_purged | datetime | YES | | NULL | |
+--------------+------------------+------+-----+---------+-------+
9 rows in set (0.01 sec)
mysql>
EDIT
Per http://php.net/manual/en/pdostatement.rowcount.php
If the last SQL statement executed by the associated PDOStatement was
a SELECT statement, some databases may return the number of rows
returned by that statement. However, this behaviour is not guaranteed
for all databases and should not be relied on for portable
applications.
So, am I just seeing the number or rows returned from my SELECT statement, and not the number or rows affected by my INSERT? Why would MySQL do such a thing?
EDIT DONE
I think it is due to ON DUPLICATE KEY UPDATE modifier as the MYSQL Reference Manual 5.5 as well as MySQL Reference Manual 5.7 says
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, an UPDATE of the old row is performed. The affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values. If you specify the CLIENT_FOUND_ROWS flag to mysql_real_connect() when connecting to mysqld, the affected-rows value is 1 (not 0) if an existing row is set to its current values.”.
In your case you already had a row with primary key value 3099541982-2536988132. Hence the MySQL lets you know that you are trying to insert a row with duplicate Primary or Unique key by indicating 2 rows affected. As the manual also say that ON DUPLICATE KEY UPDATE leads to the sequence of INSERT than UPDATE update command in case of duplicate key whereas it executes only the INSERT command in case the key is not present.
I hope this helps.
UPDATE
Also see this link.

Changing defaults

Ok let me rephrase. This is what my table is described as.
mysql> describe department;
+---------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| dnumber | int(1) | NO | PRI | NULL | |
| dname | varchar(15) | YES | | NULL | |
| mgrssn | varchar(9) | YES | | NULL | |
+---------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
This is what I need my table to be described as:
+--------------+-------------+------+-----+---------+
| Field | Type | Null | Key | Default |
+--------------+-------------+------+-----+---------+
| dnumber | int(1) | NO | PRI | NOT NULL|
| dname | varchar(15) | YES | | NULL |
| mgrssn | varchar(9) | YES | | NULL |
+--------------+-------------+------+-----+---------+
How do I change the default of dnumber to make it not null from null?
Since dnumber is the primary key of the department table, it cannot have a null value.
So, what will happen if you actually try to insert the following?
INSERT INTO department(dname, mgrssn) VALUES ("test", "123456789");
You'd expect the insert to fail with an error. But no, it succeeds, (albeit, with a warning):
mysql> INSERT INTO department(dname, mgrssn) VALUES ("test", "123456789");
Query OK, 1 row affected, 1 warning (0.04 sec)
What just happened? Well, turns out to be one of MySQL's many gotchas, where "NULL is NOT NULL". Today's MySQL manual says pretty much the same thing:
If a column definition includes no explicit DEFAULT value, MySQL determines the default value as described in Section 11.5, “Data Type Default Values”.
So, what actually got inserted? Let's take a look:
mysql> select * from department;
+---------+-------+-----------+
| dnumber | dname | mgrssn |
+---------+-------+-----------+
| 0 | test | 123456789 |
+---------+-------+-----------+
1 row in set (0.00 sec)
What happened here was that MySQL took that insert statement that was implicitly trying to insert NULL into dnumber and quietly converted it to the default value for INT, or 0.
There's also a really good video that describes this and other strange things MySQL does (as compared to PostgreSQL) in more detail.
Finally, let me add one more piece of advice - since it is the primary key, it's a really good practice to make dnumber an auto-incrementing column, like this:
mysql> ALTER TABLE department MODIFY dnumber int(1) AUTO_INCREMENT;
Query OK, 1 row affected (0.27 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> desc department;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| dnumber | int(1) | NO | PRI | NULL | auto_increment |
| dname | varchar(15) | YES | | NULL | |
| mgrssn | varchar(9) | YES | | NULL | |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
That way, future inserts into department won't always try to insert another 0 for dnumber causing a duplicate key error, but will instead use the next lowest available integer value, e.g. 1, then 2, then 3, etc.
Hope this helps!

mysql union different databases but the same schema

as picture(phpmyadmin),I have tables in the database week1 the tables are now empty.
I have another databases with exactly the same sql schema w1moninside and w1monoutside
but they have values.
I want to union these two and insert them in week1
what should I do?
I inserted the picture just for clearance.unoin for one of the tables for example the first one, data
is enough for me
Thanks.
mysql> describe w1moninside.data;
+--------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------------+------+-----+---------+-------+
| sid | int(10) unsigned | NO | PRI | NULL | |
| cid | int(10) unsigned | NO | PRI | NULL | |
| data_payload | text | YES | | NULL | |
+--------------+------------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
Insert into week1.TableName (column list)
select column list from w1moninside.TableName where...
union
select column list from w1monoutside.TableName where
Insert into week1 (column list)
select column list from dbname.w1moninside where...
union
select column list from dbname.w1monoutside where..

change a field and port mysql table data via script ?

mysql> desc oldtable;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| uid | int(11) | NO | PRI | NULL | auto_increment |
| active | char(1) | NO | | NULL | |
+---------------+--------------+------+-----+---------+----------------+
mysql> desc newtable;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| uid | int(11) | NO | PRI | NULL | auto_increment |
| active | tinyint(1) | NO | | 0 | |
+------------+--------------+------+-----+---------+----------------+
I would like to port data (dump) from oldtable into newtable. One issue is, earlier the table used char(1) for active which stores value either 'Y' or 'N'. Now the newtable stores it as int either 1 or 0.
How can i fix this before porting data? Should I use shell script for such fix & porting ?
Any sample scripts or tips :)
INSERT INTO newtable
SELECT uid,IF(active='Y',1,0) as active FROM oldtable
should do the trick
INSERT INTO newtable (uid, active)
SELECT uid, IF(active='Y', 1, 0) AS active
FROM oldtable
docs for this syntax here: http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-select-into-table.html
Joking version:
INSERT INTO newtable
SELECT uid,FIELD(active,'Y') as active
FROM oldtable

Insert 'even numbered' rows into an existing table in mysql

I have a table:
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| fooID | int(11) | NO | PRI | NULL | auto_increment |
| fooDetails | varchar(200) | YES | | NULL | |
| fooListingID | int(10) | YES | | NULL | |
| fooStatus | tinyint(4) | YES | | 0 | |
+----------------+--------------+------+-----+---------+----------------+
I would like to merge data from a similar table with this table but I would like the data to be alternating so that existing data in this table will all be odd "fooID" and the new inserts will all be the even "fooID".
Ideas?
I've interpreted your problem as you make to make all the existing fooIDs odd, and then merge into that table some new, even fooIDs.
You can accomplish this fairly easily:
#first make all the existing ids odd
UPDATE oldtable SET fooID=fooID*2-1;
#now insert rows from the other table, making sure the ids are even
INSERT INTO oldtable (fooID,fooDetails,fooListingID,fooStatus)
SELECT fooID*2,fooDetails,fooListingID,fooStatus FROM newtable;
You can insert the result of a select statement. Use modulo for alternating ids:
INSERT INTO NewTable
SELECT column1, column2
FROM OldTable
WHERE NOT id % 2