从PHP调用MySql存储过程显示错误

时间:2018-07-21 06:54:43

标签: php mysql pdo

我是PHP新手。在Mysql数据库中创建一个存储过程,现在从我的PHP代码调用时出现此错误:

  

SQLSTATE [42000]:语法错误或访问冲突:1414用于例行测试的OUT或INOUT参数6。InsertUser不是触发器之前的变量或NEW伪变量

我的程序是:

DELIMITER $$
CREATE PROCEDURE InsertUser
(
    FirstName   VARCHAR(100),
    LastName        VARCHAR(100),
    Email           VARCHAR(50),
    Age         INT,
    Location        VARCHAR(100),
    OUT Res INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
BEGIN
     SET Res = 0;
    ROLLBACK;       
END;

START TRANSACTION;

INSERT INTO USERS
(firstname,lastname,email,age,location,date)
VALUES
(FirstName,LastName,Email,Age,Location,CURRENT_TIMESTAMP());

COMMIT;
SET Res = 1;
END;
$$

我的PHP代码是:

$connection = new PDO($dsn, $username, $password, $options);
$resStatus=false;
    //$res = 0;
    $statement = $connection->prepare("CALL InsertUser(?,?,?,?,?,?)");
    $statement->bindParam(1, $_POST['firstname'], PDO::PARAM_STR, 100);
    $statement->bindParam(2, $_POST['lastname'], PDO::PARAM_STR, 100);
    $statement->bindParam(3, $_POST['email'], PDO::PARAM_STR, 100);
    $statement->bindParam(4, $_POST['age'], PDO::PARAM_INT, 10);
    $statement->bindParam(5, $_POST['location'], PDO::PARAM_STR, 100); 
    $statement->bindParam(6, $res, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 0);         
    // call the stored procedure
    $statement->execute();
    if($res == 1)
    {
        $resStatus = true;
    }

我的桌子:

CREATE DATABASE test;

use test;

CREATE TABLE users (
      id INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
      firstname VARCHAR(30) NOT NULL,
      lastname VARCHAR(30) NOT NULL,
      email VARCHAR(50) NOT NULL,
      age INT(3),
      location VARCHAR(50),
      date TIMESTAMP
 );

1 个答案:

答案 0 :(得分:1)

该问题是由您的程序中的错字引起的。您在以下行中键入“ loation”而不是“ location”

(firstname,lastname,email,age,location,date)

现在可以使用了

mysql> CREATE PROCEDURE InsertUser
    (
         FirstName       VARCHAR(100),
         LastName        VARCHAR(100),
         Email            VARCHAR(50),
         Age                      INT,
         Location        VARCHAR(100),
         OUT Res                  INT
    )
    BEGIN
      DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
      BEGIN
          SET Res = 0;
          ROLLBACK;
      END;

      START TRANSACTION;

      INSERT INTO USERS
      (firstname,lastname,email,age,location,date)
      VALUES
      (FirstName,LastName,Email,Age,Location,CURRENT_TIMESTAMP());

      COMMIT;
      SET Res = 1;
   END;
   $$
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;
mysql> select * FROM users;
Empty set (0.00 sec)

mysql> Call InsertUser("aaa", "bbb", "aaa@test.com", 12, "Earth", @res);
Query OK, 0 rows affected (0.08 sec)

mysql> select * FROM users\G
*************************** 1. row ***************************
       id: 1
firstname: aaa
 lastname: bbb
    email: aaa@test.com
      age: 12
 location: Earth
     date: 2018-07-21 12:09:47
1 row in set (0.00 sec)

mysql> select @res;
+------+
| @res |
+------+
|    1 |
+------+
1 row in set (0.02 sec)

谈到PHP错误,我调查了一下它,PARAM_INPUT_OUTPUT似乎不稳定。对我来说,它也不起作用。

有一个解决方法:使用MySQL变量并在运行CALL之后选择它:

<?php
try {
    $username = 'user';
    $password = '';
    $conn = new PDO('mysql:host=localhost;dbname=test1', $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}

// call the stored procedure
$statement = $conn->prepare("CALL InsertUser(?,?,?,?,?,@result)");

$params =  array("aaa", "bbb", "test@test.com", 13, "Earth");
$statement->bindParam(1, $params[0], PDO::PARAM_STR, 100);
$statement->bindParam(2, $params[1], PDO::PARAM_STR, 100);
$statement->bindParam(3, $params[2], PDO::PARAM_STR, 100);
$statement->bindParam(4, $params[3], PDO::PARAM_INT, 10);
$statement->bindParam(5, $params[4], PDO::PARAM_STR, 100);

$statement->execute();

//select result
$sql = "SELECT @result";
$stmt = $conn->prepare($sql);
$stmt->execute();

list($result) = $stmt->fetch(PDO::FETCH_NUM);
var_dump($result);

输出:string(1)“ 1”