带参数的MySQL条件插入

带参数的MySQL条件插入,mysql,insert,Mysql,Insert,我正在创建一个存储过程,将值插入到四个表中。关键是要将SQL从PHP中移除,以防止SQL注入,并更好地定义用户拥有的权限,即不允许无限访问INSERT、SELECT、ALTER和DELETE语句,只允许它们运行插入传递的变量所需的过程 然而,如果一个玩家已经存在,那么就没有必要再添加它(考虑到我已经使它独一无二,这是不可能的)。问题的出现是因为玩家表和坐标表之间存在一对多关系 所以我想要的是一个有条件的INSERT来测试这个值是否已经存在,以及它是否已经存在,然后转到下一个INSERT语句 以下

我正在创建一个存储过程,将值插入到四个表中。关键是要将SQL从PHP中移除,以防止SQL注入,并更好地定义用户拥有的权限,即不允许无限访问
INSERT
SELECT
ALTER
DELETE
语句,只允许它们运行插入传递的变量所需的过程

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

所以我想要的是一个有条件的
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
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;
我想我需要在重复键上加上
,但我不太清楚它的用法


提前感谢您的帮助。

您不能这样做吗

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

你不能这样做吗也许:

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

使用MySQL有几种方法可以做到这一点。一个简单的解决方案是使用
INSERT IGNORE
而不是
INSERT
。如果新行复制表中现有的
唯一索引
主键
值,则前者基本不起作用。有关更多信息,请参阅上的MySQL文档

您还可以使用语法
插入到。。。选择…
,可提供更大的灵活性。让我们做一个简单的例子。以下语句基本上做了相同的事情:

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

INSERT INTO foobar (foobar_id,display_name)
    SELECT 1,'one' FROM dual;
如果更改
SELECT
查询以检测foobar中的重复条目,则可以获得所需的行为。有关更多详细信息,请参阅上的MySQL文档

编辑:这是在存储过程中使用存储过程的参数:

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

使用MySQL有几种方法可以做到这一点。一个简单的解决方案是使用
INSERT IGNORE
而不是
INSERT
。如果新行复制表中现有的
唯一索引
主键
值,则前者基本不起作用。有关更多信息,请参阅上的MySQL文档

您还可以使用语法
插入到。。。选择…
,可提供更大的灵活性。让我们做一个简单的例子。以下语句基本上做了相同的事情:

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

INSERT INTO foobar (foobar_id,display_name)
    SELECT 1,'one' FROM dual;
如果更改
SELECT
查询以检测foobar中的重复条目,则可以获得所需的行为。有关更多详细信息,请参阅上的MySQL文档

编辑:这是在存储过程中使用存储过程的参数:

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

如果要插入的值是参数,是否可以使用
INSERT…选择
?你能给我举个例子吗?dual指的是什么?这是一个表名吗?或者双参数是参数的参考?我理解
SELECT
,但我不太明白您在此处将
指向何处。如果要插入的值是参数,是否可以使用
INSERT…SELECT
?你能给我举个例子吗?dual指的是什么?这是一个表名吗?或者双参数是参数的参考?我理解
选择
,但我不太明白您在这里将
指向何处。