MySQL "old version syntax" - mysql

im currently porting my SQLite database to MySQL, just made a script to change all INSERT's and more to MySQL but im sometimes getting an "old version syntax error":
INSERT INTO players(id, name) VALUES (21457, '/Gohst_Killer67\');
The Database structure:
CREATE TABLE IF NOT EXISTS players (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(40))
I have alot usernames saved, but those / or \ keeps raising those error messages. I hope theres a way to fix it without editing all names which contain / or .
Thanks

In mysql the way is-
Hitesh> CREATE TABLE IF NOT EXISTS players (id INTEGER PRIMARY KEY AUTO_INCREMENT, name VARCHAR(40));
Query OK, 0 rows affected (0.21 sec)
Hitesh> INSERT INTO players(id, name) VALUES (21457, '/Gohst_Killer67\'');
Query OK, 1 row affected (0.04 sec)
for special character you should use \ before it. like i have used \' in insert.
You can disable backslash escapes by setting NO_BACKSLASH_ESCAPES in the SQL mode:
SET #old_sql_mode=##sql_mode;
SET ##sql_mode=CONCAT_WS(',', ##sql_mode, 'NO_BACKSLASH_ESCAPES');
Hitesh> INSERT INTO players(id, name) VALUES (21457, "/Gohst_Killer67'");
Query OK, 1 row affected (0.04 sec)
for insert single quote you can put string in "" when insert or vice versa like i did. other wise you can use quote function quote

Related

Can you create a table in mysql with dots in it?

Can you create a table in mysql with dots (.) in it?
I´m having trouble manipulating a table with a dot in its name. I did it this way as a shortcut for a php query.
You can create table names with punctuation by delimiting the identifiers with back-ticks.
mysql> create table `my...table` (id serial primary key);
Query OK, 0 rows affected (0.05 sec)
mysql> insert into `my...table` values (1234);
Query OK, 1 row affected (0.02 sec)
mysql> select * from `my...table`;
+------+
| id |
+------+
| 1234 |
+------+
It's legal, but probably more trouble than it's worth. You have to remember to use the back-ticks every time you reference the table.
A good compromise is to use _ instead of a dot, because you don't have to delimit the table name for that character.
You could quote the table name(s) with back-ticks — or, if you have control over it, and it's not too late, substitute the special characters with a standardized alternative:
select * from `table.name`
Permissible characters (without the need for quotes):
[0-9,a-z,A-Z$_]

on duplicate key update id=last_insert_id(id) - did the INSERT actually happen?

I need to INSERT a new row into my TABLE(with unique field 'A'), if it already exists(duplicate field, insert failed) - just return the ID of the existing one.
This code works well:
insert into TABLE set A=1 on duplicate key update id=last_insert_id(id)
But now I have another problem: how do I know if the returning ID belongs to a new (inserted) row or it's just an old one?
Yes, I can do "SELECT id WHERE A=1" beforehand, but it would overcomplicate the program code, require two steps, and just looks ugly. Besides, in future I may want to remove some UNIQUE indexes, then I'll have to rewrite the program as well to change all the 'where' checks. Maybe there is a better solution?
[solved, see my answer]
Found this solution. It works in console, but doesn't work in my program (must be a bug in the client, idk) - so probably it will work fine for everyone (except me, sigh)
Just check the 'affected rows count' - it will be 1 for the new record and 0 for the old one
mysql> INSERT INTO EMAIL set addr="test" ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
Query OK, 1 row affected (0.01 sec)<----- 1 = INSERTed
mysql> select last_insert_id(); //returns 1
mysql> INSERT INTO EMAIL set addr="test" ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
Query OK, 0 rows affected (0.00 sec) <----- 0 = OLD
mysql> select last_insert_id(); //returns 1
UPD: it didn't work for me because my program kept sending the 'CLIENT_FOUND_ROWS ' flag when connecting to mysql. Removed it, now everything is fine!

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

create database if not exists dbname , 1 row affected

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.

I set a MySQL column to "NOT NULL" but still I can insert an empty value

In MySQL I have a table with Column1 as NOT NULL:
create table myTable
(
Column1 int not null,
Column2 int not null
)
I can still insert an empty value like this:
INSERT INTO `myTable` ( `Column1` , `Column2` )
VALUES ( '66', '' );
How can I make the MySQL column also disallow blankstring?
EMPTY STRINGS
In ORACLE an empty string is used to represent NULL. In virtually everything else, however, an empty string is still a string, and so not NULL.
INTS
In your case you're actually inserting STRINGS into an INT column. This forces an implicit CAST operation.
When your RDBMS is converting the string '' to an INT it must get the value 0. As 0 is not NULL, this gets inserted.
A more valid test would be:
INSERT INTO `plekz`.`countries` (`Column1 ` , `Column2`)
VALUES (66, NULL);
EDIT
Sorry, I only half read your question. You also ask how to stop '' being inserted.
Your first problem is that you're inserting STRINGS and the table is defined as having INT fields. You can put constraints on the data that gets inserted, but these constraints will apply the the value after an conversion to an INT. Unless you want to prevent the value 0 from also being inserted, there is nothing you can do to the table to prevent this scenario.
Your better bet is to address why you are inserting strings in the first place. You could use a stored procedure that takes, and checks, the strings before converting them to INTs and then inserting them. Or, better still, you could make the checks in your client application.
A technically available option is to make the fields CHAR fields, then put a constraint on the fields, preventing '' from being inserted. I would strongly recommend against this.
You're inserting an empty string, not NULL. The constraint is only against NULL values, and it would appear that your database is not coercing empty strings to NULL when it converts them to INT (which raises the additional question of why you're inserting string literals into INT columns...)
MySQL, how to disallow empty string:
Create your table:
mysql> create table yar (val VARCHAR(25) not null);
Query OK, 0 rows affected (0.02 sec)
Create your 'before insert' trigger to check for blankstring and disallow.
mysql> create trigger foo before insert on yar
-> for each row
-> begin
-> if new.val = '' then
-> signal sqlstate '45000';
-> end if;
-> end;$$
Query OK, 0 rows affected (0.01 sec)
Try to insert null and blankstring into your column:
mysql> delimiter ;
mysql> insert into yar values("");
ERROR 1644 (45000): Unhandled user-defined exception condition
mysql> insert into yar values(NULL);
ERROR 1048 (23000): Column 'val' cannot be null
mysql> insert into yar values ("abc");
Query OK, 1 row affected (0.01 sec)
mysql> select * from yar;
+-----+
| val |
+-----+
| abc |
+-----+
1 row in set (0.00 sec)
Finally, Grumble to self and smack the nearest person who was responsible for picking mysql over postgresql.
As Martin mentions, depends on your RDBMS. Oracle treats empty strings as NULLs while others do not. See this SO post.
NULL is not equal to emptiness. In MySQL, there is an additional byte with each column entry to hold the "is null" information. To save space, a column is often defined as "not null" to spare this extra byte if the null status doesn't add any thing to the data model.