1

我正在创建一个存储过程来将值插入四个表中。重点是将 SQL 从 PHP 中取出以防止 SQL 注入并更好地定义用户拥有的权限,即,而不是被允许无限制地访问INSERTSELECT和语句,他们只被允许运行他们需要插入的过程传递的变量。ALTERDELETE

但是,如果一个玩家已经存在,那么就没有必要再次添加它(考虑到我已经让它独一无二了,这是不可能的)。出现问题是因为玩家表和坐标表之间存在一对多的关系。

所以我想要的是一个条件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,但我不太清楚它的用法。

提前感谢所有帮助。

4

2 回答 2

1

使用 MySQL 有几种方法可以做到这一点。一个简单的解决方案是使用INSERT IGNORE而不是INSERT. 如果新行与表中的现有值UNIQUE INDEXPRIMARY KEY值重复,则前者基本上什么都不做。有关更多信息,请参阅有关INSERT 语法的 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 语法的 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;
于 2012-04-06T14:13:30.983 回答
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
于 2012-04-06T13:45:56.470 回答