I'm new to mysql and wanted to consult about using mysql for my mini game. The idea is that from a game i get two variables - one is email, and another is score.
I'm thinking of creating a table with two columns and setting email as the primary.
The question is how do I make php script replace score value for a player which tries for the second time?
For example user#user.com scores 100 in the first try, script adds that as INSERT INTO table VALUES ($email,$score); then user tries another time, same script tries to add but gets duplicate error. Any help on script logic would be great! cheers
INSERT
INTO mytable (email, score)
VALUES ($email, $score)
ON DUPLICATE KEY
UPDATE
SET score = $score
This requires email to be the PRIMARY KEY of mytable.
It's difficult to answer without more details. If there is some sort of session or pre-registering of the player, you could insert a "default score" of zero, for instance, and then always update instead of insert. If not, Queassnoi's solution is probably the best.
You need to use UPDATE rather than INSERT
UPDATE table SET score = $newScore where email=$email
You are trying to add a new record with the same primary key, hence the error message
Related
I have a table called INVOICES that receives entries from a PHP script. It has many columns, but the two most relevant are INVOICE_ID and INVOICE_TYPE. Basically the INVOICE_TYPE is a number from 0 to 3, which designates different types of invoices.
Up to this point, everything ran smoothly until two users submitted invoices while the server had a hiccup and wrote both in as the same INVOICE_ID. The reason for this is the PHP script reads the MAX INVOICE_ID of the INVOICE_TYPE, then adds 1, then inserts the new row with that INVOICE_ID. In essence, it is programmatically a primary key. 99.9% of the time it worked, but that one time it was a problem.
I have tried finding SQL solutions but do not have sufficient knowledge of it. I have tried doing it myself in an SQL query to read the MAX, increment, and the insert but just throws an exception that you cannot select and insert from the same table at once.
What I'm wondering is if there is an auto-increment that could be conditional to the INVOICE_TYPE, to only increment if the type is matched. Any suggestions would help at this point.
An unique index over the two columns (INVOICE_ID, INVOICE_TYPE) will make one of such hiccupy queries fail.
CREATE UNIQUE INDEX id_type_unique ON INVOICES (INVOICE_ID, INVOICE_TYPE);
INSERT INTO INVOICES (INVOICE_ID, INVOICE_TYPE) VALUES (1, 5); -- okay
INSERT INTO INVOICES (INVOICE_ID, INVOICE_TYPE) VALUES (1, 5); -- error
If you insert only one row to one table at once simplest solution is to apply unique index on both columns.
CREATE UNIQUE INDEX invoice_id_type_unique
ON INVOICES(INVOICE_ID,INVOICE_TYPE);
But if you execute more queries based on the same data you need to use transactions to prevent modifying/inserting only part of data.
START TRANSACTION;
SELECT #invoice_id:=MAX(INVOICE_ID) FROM INVOICES WHERE INVOICE_TYPE=1;
INSERT INTO INVOICES (...,#invoice_id,...);
...
... #OTHER QUERIES UPDATING DATA
COMMIT;
make (INVOICE_ID) as UNIQUE, this will solved your problem, sql will not allowed duplicate value in same column.
The way i like it is to create a table to handle all the sequences and a stored procedure that i can call with the name of the sequence that i like to know the next value, something similar to:
START TRANSACTION;
SELECT value INTO result FROM Sequences WHERE name like paramSeqName FOR UPDATE;
UPDATE Sequences SET value = value + 1 WHERE name like paramSeqName;
COMMIT;
There is a good example here:
http://www.microshell.com/database/mysql/emulating-nextval-function-to-get-sequence-in-mysql/
Let's say I have dynamic numbers with unique id's to them.
I'd like to insert them into database. But if I already have that certain ID (UNIQUE) I need to add to the value that already exists.
I've already tried using "ON KEY UPDATE" ,but it's not really working out. And selecting the old data so we could add to it and then updating it ,is not efficient.
Is there any query that could do that?
Incrementing your value in your application does not guarantee you'll always have accurate results in your database because of concurrency issues. For instance, if two web requests need to increment the number with the same ID, depending on when the computer switches the processes on the CPU, you could have the requests overwriting each other.
Instead do an update similar to:
UPDATE `table` SET `number` = `number` + 1 WHERE `ID` = YOUR_ID
Check the return value from the statement. An update should return the number of rows affected, so if the value is 1, you can move on happy to know that you were as efficient as possible. On the other hand, if your return value is 0, then you'll have to run a subsequent insert statement to add your new ID/Value.
This is also the safest way to ensure concurrency.
Hope this helps and good luck!
Did something different. Instead of updating the old values ,I'm inserting new data and leaving old one ,but using certain uniques so I wouldn't have duplicates. And now to display that data I use a simple select query with sum property and then grouping it by an id. Works great ,just don't know if it's the most efficient way of doing it.
I am trying to develop a system to assign room numbers to tenants of a hostel upon registration, using the auto increment feature of sql.
However, it automatically increases by one after every entry. Because the hostel accommodates four people in one room, I want to change this to 4, so that after every 4 entries I get only one id/room number.
How do I go about this? I am using php and sql. If the autoincrement feature is not possible can you please suggest another way to achieve this? Thanks.
You would need:
http://dev.mysql.com/doc/refman/5.1/en/replication-options-master.html#sysvar_auto_increment_increment
It works like this:
mysql> SET ##auto_increment_increment=4;
So when you insert 4 rows, the auto increment column will be:
4,8,12,16
as best of my knowledge you cannot change the steps of auto-increment field. I suggest add another field and write a trigger to update its value based on auto-increment field (auto-increment/4).
I don't think this is possible with autoincrement..
Maybe you can do something like this:
//Pseudo code
//First you get the count of the highest id, to see how many users are in the last room.
SELECT COUNT(*) FROM table WHERE id=(SELECT id FROM table ORDER BY id DESC LIMIT 1)
//If the result of the last query is >= 4 then insert the next customer with id +1
Don't use auto_increment for this - it can't handle a situation where multiple records will share the same number and although you can reset it manually (see below) it's also not designed for a situation where numbers may get reused in a random order.
You could just have a room_number field with one of the mysql integer types (e.g. tinyint, smallint, mediumint…) or you could separate your database into two tables, one for people (each of whom have an id) and a second to map those ids to rooms.
However you do it, you'd then write a select query to check which room numbers are available before you add the person's details to the database.
You may need to read up on relational databases if that doesn't sound very clear.
If you do need to reset the auto_increment (sometimes it's nice to do it if you've filled a database with test data which you're about to wipe, and you want the real "production" data to begin at 1) you can use:
ALTER TABLE [tablename] AUTO_INCREMENT = 1
https://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
Is there a way to auto increment entries to a MySQL table based on the value of another column in the inserted row? For example, something to say that this is the fifth entry for a specific username?
I know I could do a row count after I make my query, but that's not what I'm looking for. I've looked around and just can't seem to find anything on this.
Thanks!
Assuming that you have a table Users with 2 columns, username and counter. Example code for the case you mentioned. Run this to create the trigger. It should fire on every insert.
CREATE TRIGGER insert_update BEFORE INSERT ON Users
FOR EACH ROW
BEGIN
DECLARE name_count INTEGER;
SELECT COUNT(*) INTO #name_count FROM Users WHERE username = NEW.username;
INSERT INTO Users VALUES (NEW.username, #name_count+1);
END
END
Disclaimer: this might not be the most efficient or cleanest thing in the world. I would be interested in what the other folks can come up with.
If I have an insert statement with a bunch of values where the first value is an id that's also the primary key to my database, how can I check if everything else in those values is not completely the same and to update the fields that are different? (second part not necessary for an answer, but it'd be nice. If it's too convoluted to do the second part I can just delete the record first and then insert the full line of updated values)
I'm guessing that it has something to do with SELECT FROM TABLE1 * WHERE id=1 and then somehow do an inequality statement with the INSERT INTO TABLE1 VALUES ('1','A'... etc.) but I'm not sure how to write that.
Edit: I think I asked the question wrong so I'll try again:
I have a database that has first column id that is a primary key and then a lot of other columns, too long to type out by hand. I have a script that will get data and I will not know if this data is a duplicate or not e.g.
id value
1 dog
2 cat
if the new info coming in is "1, dog" then I need a signal (say boolean) that tells me true, if the new info is "1, monkey" then I need a signal that tells me false on the match and then update every single field. The question is how do I generate the boolean value that tells me whether the new values with the same id is completely identical to the one in the db? (It has to check every single filed of long list of fields that will take forever to type out, any type of output would be good as long as I can tell one means it's different and one means it's the same)
A side question is how do I update the row after that since I don't want to type out every single field, my temporary solution is to delete the row with the out of date primary id and then insert the new data in but if there is a fast way to update all columns in a row that'd be great.
MySQL can do "on duplicate key update" as part of the insert statement:
INSERT INTO table (id, ...) VALUES ($id, ...)
ON DUPLICATE KEY UPDATE somefield=VALUES(somefield), ...=VALUES(...)
Simple and effective. You only specify the fields you want changed if there is a primary key duplication, and any other fields in the previously-existing record are left alone.