create database if not exists dbname , 1 row affected - mysql

When I try to create a database which already exists,
CREATE DATABASE IF NOT EXISTS test;
Query OK, 1 row affected (0.00 sec)
CREATE DATABASE IF NOT EXISTS test;
Query OK, 1 row affected, 1 warning (0.00 sec)
Why does it show 1 row affected message second time , even though it is not creating a new database with the same name?

Although the CREATE DATABASE IF NOT EXISTS test; command won't directly modify rows in an exiting instance of the test database, it will affect the actual details stored internally in the mysql database, or possibly in one of the derived meta views, like the information_schema or performance_schema etc.
The reported Query OK, 1 row affected (0.00 sec) is referring to a row in one of these internal data constructs. When you reissue the CREATE DATABASE command, and it fails gracefully thanks to the IF NOT EXISTS clause, it is still likely to store meta-data internally, maybe an accumulating field that counts warnings or similar, or even just a 'last acted on' timestamp against this database's row. In any case the stored data in this record is changed, and is reflected as an 'affected' row.

Related

Table named by a MySQL reserved word cannot be altered or dropped

Accidentally I named my table "RollUp" which is a reserved word in MySQL.
For some reason there was no error and the table had been successfully created.
Now I can SELECT, DESCRIBE etc. but I cannot ALTER, RENAME or DROP.
Backtick doesn't help.
How could I get rid of this table (either change its name or completely drop it)?
I cannot replicate this:
mysql> CREATE TABLE rollup (i INT NOT NULL);
Query OK, 0 rows affected (0.02 sec)
mysql> DROP TABLE rollup;
Query OK, 0 rows affected (0.01 sec)
So the problem was I did not close Python connection to the database.
Thank you and I am sorry for asking stupid question, it may be removed.

Can MySQL transaction rollback without ROLLBACK query?

I'm working on a financial system and I've got a problem with the MySQL transactions.
The system is a simple stock exchange, where users can buy and sell virtual shares. To keep integrity in buy and sell process I use transactions.
The problem is that in some cases (I don't know what it depends on) some of transactions are rolled back (or not commited), but next queries are processed.
The process is following:
User wants to buy shares for 1000 USD
In orderbook there are 4 offers for 250 USD
START TRANSACTION
For every offer:
Script does a UPDATE query (moving USD from one user to another and shares in the opposite way). Then script INSERTs entries to history tables.
Users pay a fee (UPDATE balances).
Repeat 5 and 6 for the next offer.
COMMIT
Now the key part - in some cases changes from point 5 are not saved, but from the 6 they are (I see that fee was paid, but there is no transaction in the history).
I'm not using ROLLBACK during this transactions and the script is not breaking (because in this case fee wouldn't be paid).
Is there any possibility that transaction is rolling back without ROLLBACK query? Or can MySQL COMMIT only few newest queries instead of all?
Transactions or not, it's the responsibility of your client code to verity that all your INSERT or UPDATE queries complete successfully and then either issue a explicit ROLLBACK or close the connection withour COMMIT to issue an implicity ROLLBACK. If any of them fails but your code goes on, those queries will not take effect (because they failed) but the rest will do.
Here's a simplified example:
mysql> create table test (
-> id int(10) unsigned not null,
-> primary key (id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into test(id) values (1);
Query OK, 1 row affected (0.00 sec)
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test(id) values (2);
Query OK, 1 row affected (0.00 sec)
mysql> insert into test(id) values (-3);
ERROR 1264 (22003): Out of range value for column 'id' at row 1
We should have rollbacked and aborted here, but we didn't.
mysql> insert into test(id) values (4);
Query OK, 1 row affected (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test;
+----+
| id |
+----+
| 1 |
| 2 |
| 4 |
+----+
3 rows in set (0.00 sec)
4 rows expected, got 3.
Other than that, there're many circumstances where you can get an unwanted COMMIT but an unwanted ROLLBACK is something I'm not sure that can happen unless you terminate a session with pending changes.
It's long time since the question was asked, but the problem actually was that I didn't check for the SQL errors for every query.
Actually at some points, when I should rollback transaction, I didn't do it.
If your are looking for answer - check again if you testing ALL queries in your transaction for successful execution and don't trust that the framework you are using is doing it for you automatically (just check it again).

Fetching last insert id shows wrong number

I have table with three records. There is one filed as auto_increment. The ID's are 1, 2, 3...
When I run query
SELECT LAST_INSERT_ID() FROM myTable
The result is 5, even the last ID is 3. Why?
And what is better to use? LAST_INSERT_ID() or SELECT MAX(ID) FROM myTable?
The LAST_INSERT_ID() function only returns the most recent autoincremented id value for the most recent INSERT operation, to any table, on your MySQL connection.
If you haven't just done an INSERT it returns an unpredictable value. If you do several INSERT queries in a row it returns the id of the most recent one. The ids of the previous ones are lost.
If you use it within a MySQL transaction, the row you just inserted won't be visible to another connection until you commit the transaction. So, it may seem like there's no row matching the returned LAST_INSERT_ID() value if you're stepping through code to debug it.
You don't have to use it within a transaction, because it is a connection-specific value. If you have two connections (two MySQL client programs) inserting stuff, they each have their own distinct value of LAST_INSERT_ID() for the INSERT operations they are doing.
edit If you are trying to create a parent - child relationship, for example name and email addresses, you might try this kind of sequence of MySQL statements.
INSERT INTO user (name) VALUES ('Josef');
SET #userId := LAST_INSERT_ID();
INSERT INTO email (user_id, email) VALUES (#userId, 'josef#example.com');
INSERT INTO email (user_id, email) VALUES (#userId, 'josef#josefsdomain.me');
This uses LAST_INSERT_ID() to get the autoincremented ID from the user row after you insert it. It then makes a copy of that id in #userId, and uses it twice, to insert two rows in the child table. By using more INSERT INTO email requests, you could insert an arbitrary number of child rows for a single parent row.
Pro tip: SELECT MAX(id) FROM table is a bad, bad way to figure out the ID of the most recently inserted row. It's vulnerable to race conditions. So it will work fine until you start scaling up your application, then it will start returning the wrong values at random. That will ruin your weekends.
last_insert_id() has no relation to specific tables. In the same connection, all table share the same.
Below is a demo for it.
Demo:
mysql> create table t1(c1 int primary key auto_increment);
Query OK, 0 rows affected (0.11 sec)
mysql> create table t2(c1 int primary key auto_increment);
Query OK, 0 rows affected (0.06 sec)
mysql> insert into t1 values(null);
Query OK, 1 row affected (0.01 sec)
mysql> insert into t2 values(4);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values(null);
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id() from t1;
+------------------+
| last_insert_id() |
+------------------+
| 5 |
+------------------+
1 row in set (0.00 sec)
I don't think this function does what you think it does. It returns the last id inserted on the current connection.
If you compare that to SELECT MAX(ID) this selects the highest ID irrespective of connection, be careful not to get them mixed up or you will get unexpected results.
As for why it is showing 5 its probably because its the last id to be inserted, I believe that this value will remain even if the record is removed, perhaps someone could confirm this.
Table level triggers is what can come to rescue here. e.g. before insert trigger.
maybe you should restart the database connection than reconnected again for fresh data

Does UPDATE overwrite values if they are identical?

I only want to update a vale in my database if it is different. Reading through the Oracle docs on UPDATE, it says...
...the UPDATE statement updates columns of existing rows in the named table with new values.
Since it doesn't say it won't overwrite identical values, should I take this statement literally? Does this mean MySQL does some sort of Boolean matching check for me?
No, MySQL won't overwrite identical values.
Lets say we insert some data:
insert into foo(id,val1,val2,val3) values (0,1,2,3);
Query OK, 1 row affected (0.00 sec)
If you update it with the same values:
update foo set id=0, val1=1, val2=2, val3=3 where id=0;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 0
Take a look on servers response 0 rows affected
an sql query would update even identical value by practically substituting them. Anyway, you can structure your sql to avoid it will substitute the identical value. (I think also that the latter way would be more time consuming then the normal procedure and maybe useless for the final result)

MySQL row_count() function always returning 0

I want to show the result of rows affected after update, insert, or delete in mysql. I have put
DELETE FROM A WHERE ID='1';
SELECT ROW_COUNT();
With the ROW_COUNT the last statement, but the result show me is 0.
If you want to know number of rows affected by delete query in PHPMYADMIN then by running your query it will show you the result see below screenshot :
As #Flash Thunder said PHPmyadmin does not allow multiple queries sent at once
If you want to see the affected rows then you can also write a script using PHP which will exceute you sql query and returns the number of affected rows
Just to be clear.
phpMyAdmin is written in PHP, and PHP does not allow multiple queries sent at once... if you are sending two queries separately, second query is on new connection, so it has no access to previous query information. That's why SELECT ROW_COUNT(); returns 0.
But by default phpMyAdmin returns affected rows count in information after query. It probably uses mysql(i)_affected_rows() function.
FOUND_ROWS() returns number of tables in database when there was no previous query.
mysql> use hunting;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select found_rows();
+--------------+
| found_rows() |
+--------------+
| 24 |
+--------------+
1 row in set (0.00 sec)
mysql> show tables;
(...)
24 rows in set (0.00 sec)