Reputation: 1373
I'm creating a stored procedure to insert values into four tables. The point being to take the SQL out of the PHP to prevent SQL injection and better define the permissions a user has, i.e. rather than being allowed unlimited access to INSERT
, SELECT
, ALTER
and DELETE
statements, they are simply only allowed to run the procedure they need to insert the passed variables.
However, if a player already exists, then it is unnecessary to add it again (and impossible considering I've made it unique). The problem arises because there is a one to many relationship between the player table and the coordinates table.
So what I'd like is a conditional INSERT
to test if the value already exists and if it does to move on to the next INSERT
statement.
Here's the stored procedure:
CREATE PROCEDURE `acdb_extended`.`addAlliedMember` (IN accountNumber VARCHAR(255),
IN userName VARCHAR(255), IN serverInitial CHAR(1), IN galaxy TINYINT(2),
IN region TINYINT(2), IN system TINYINT(2), IN astro TINYINT(2), IN level TINYINT(2),
IN allianceName VARCHAR(255))
BEGIN
INSERT INTO player (account_number, username)
VALUES (accountNumber, userName);
INSERT INTO coordinates (player_ID, server_initial, galaxy, region, system, astro)
VALUES ((SELECT player_ID FROM player WHERE username = userName), serverInitial,
galaxy, region, system, astro);
INSERT INTO jumpgate (player_ID, coordinates_ID, level, usable)
VALUES ((SELECT player_ID FROM player WHERE username = userName),
(SELECT c.coordinates_ID FROM coordinates c WHERE c.server_initial = serverInitial
AND c.galaxy = galaxy AND c.region = region AND c.system = system AND c.astro = astro),
level, FALSE);
INSERT INTO relationship (player_ID, ally, alliance_name)
VALUES ((SELECT player_ID FROM player WHERE username = userName),
TRUE, allianceName);
END
I think I need ON DUPLICATE KEY
but I can't quite figure out its usage.
Thanks in advance for all the help.
Upvotes: 1
Views: 6394
Reputation: 50074
There are several ways to do this with MySQL. A simple solution is to use INSERT IGNORE
instead of INSERT
. The former does basically nothing if the new row duplicates an existing UNIQUE INDEX
or PRIMARY KEY
value in the table. See the MySQL documentation on INSERT Syntax for more information.
You can also use the syntax INSERT INTO ... SELECT ...
which offers more flexibility. Let's make a simple example. The following statements basically do the same thing:
INSERT INTO foobar (foobar_id,display_name) VALUES (1,'one');
INSERT INTO foobar (foobar_id,display_name)
SELECT 1,'one' FROM dual;
If you change the SELECT
query to detect duplicate entries in foobar, you get the desired behavior. See the MySQL documentation on INSERT ... SELECT Syntax for more details.
Edit: This is works within stored procedures and with the parameters of the stored procedure:
CREATE PROCEDURE sp_foobar(IN _foobar_id int, IN _display_name varchar(255))
BEGIN
INSERT INTO foobar (foobar_id, display_name)
SELECT _foobar_id, _display_name
FROM dual;
END;
Upvotes: 1
Reputation: 31249
Can't you do it like this maybe:
IF NOT EXISTS(SELECT NULL FROM player WHERE account_number=accountNumber AND username=userName)
BEGIN
INSERT INTO player (account_number, username)
VALUES (accountNumber, userName);
INSERT INTO coordinates (player_ID, server_initial, galaxy, region, system, astro)
VALUES ((SELECT player_ID FROM player WHERE username = userName), serverInitial,
galaxy, region, system, astro);
END
Upvotes: 0