2012-04-06 60 views
1

我正在创建一个存储过程以将值插入到四个表中。重点在于从SQL中取出SQL以防止SQL注入并更好地定义用户拥有的权限,即不允许无限制地访问INSERT,SELECT,ALTERDELETE语句,它们仅被允许运行该过程他们需要插入传递的变量。但是,如果玩家已经存在,那么就没有必要再次添加它(并且考虑到我已经使其独特),所以不必再添加它(并且不可能)。问题的产生是因为玩家表和坐标表之间存在一对多的关系。带参数的MySQL条件插入

所以我想要的是一个条件INSERT来测试值是否已经存在,如果它确实移动到下一个INSERT声明。

这里的存储过程:

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 

我想我需要ON DUPLICATE KEY但我不能完全弄清楚它的使用。

在此先感谢您的帮助。

回答

1

有几种方式与MySQL做到这一点。一个简单的解决方案是使用INSERT IGNORE而不是INSERT。如果新行与表中现有的UNIQUE INDEXPRIMARY KEY值重复,则前者基本上不会执行任何操作。有关更多信息,请参阅INSERT Syntax上的MySQL文档。

您还可以使用提供更多灵活性的语法INSERT INTO ... SELECT ...。我们来举个简单的例子。下面的语句基本上做的是同一件事:

INSERT INTO foobar (foobar_id,display_name) VALUES (1,'one'); 

INSERT INTO foobar (foobar_id,display_name) 
    SELECT 1,'one' FROM dual; 

如果更改SELECT查询检测foobar的重复条目,获取所需要的行为。有关更多详细信息,请参阅INSERT ... SELECT Syntax上的MySQL文档。

编辑:这是存储过程中,并与存储过程的参数作品:

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; 
+0

您可以用'INSERT ... SELECT'如果你想插入值的参数?你能告诉我一个这样的例子吗? – Arcadian 2012-04-06 15:23:35

+0

双重指什么?这是表名吗?或者双参考参数?我明白'SELECT',但我不太明白你在哪里指出'FROM'。 – Arcadian 2012-04-06 20:30:56

+0

http://en.wikipedia.org/wiki/DUAL_table – nosid 2012-04-06 20:52:28

0

你不能做这样的可能:

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