PDOStatement :: execute():执行存储过程

时间:2015-11-21 15:24:38

标签: php

我有一个存储过程,可以在MySQL中返回单个值。

然而,当尝试使用PHP调用它时,它返回正确的值,但也返回以下三个错误

Warning: PDOStatement::execute(): Premature end of data (mysqlnd_wireprotocol
Warning: PDOStatement::execute(): RSET_HEADER packet 1 bytes shorter than expected 
Warning: PDOStatement::execute(): Error reading result set's header 

他们都参考第90行 我通过PDO参数化查询执行SP的地方

$Statement->execute();

有谁知道我为什么会收到这些错误?谷歌搜索主要指的是当被拒绝访问数据库与#34;旧"样式密码。我没有遇到此问题,因为SP正在返回正确的值,但有三条错误消息。

嗨马库斯,谢谢你回复。对不起,我已经离开了。我的PHP版本是5.5.12,MySQL版本是5.6.17我在我的盒子上使用最新的WampServer。错误消息未提及"使用旧密码"目前我使用下面的代码使SP工作正常,但我必须将SP结果作为VARCHAR返回,然后转换" true / false"使用PHP将字符串添加到bool中。如果我尝试将SP值作为INT返回,那么当我得到错误时......

存储过程:

CREATE DEFINER=`MyDB`@`localhost` PROCEDURE `new_account`(
IN Cus_Title VARCHAR(4),
IN Cus_Name VARCHAR(35),
IN Cus_Surname VARCHAR(35),
IN Cus_Email VARCHAR(75),
IN Cus_Password VARBINARY(255),
IN Cus_Status TINYINT(1),
IN Cus_LoginIP VARCHAR(45),
IN Cus_Created TIMESTAMP,

IN Pho_Number VARCHAR(14),

IN Com_Name VARCHAR(50),
IN Com_BuildingNumber VARCHAR(14),
IN Com_Address VARCHAR(100),
IN Com_Street VARCHAR(35),
IN Com_City VARCHAR(25),
IN Com_County VARCHAR(35),
IN Com_PostCode VARCHAR(12),

IN Act_ActivationToken VARBINARY(255),
IN Act_Expiry TIMESTAMP,
-- OUT ReturnStatus INT(3) using this I get errors from PHP
OUT ReturnStatus VARCHAR(5)
)
BEGIN
DECLARE Cus_ID INT(11) UNSIGNED; -- CustomerID
DECLARE Com_ID INT(11) UNSIGNED; -- CompanyID

IF EXISTS(SELECT Email FROM customers WHERE Email = Cus_Email) THEN
SET ReturnStatus = "false";
SELECT ReturnStatus;
ELSE
INSERT INTO customers(Title, Name, Surname, Email, Password, Status, LoginIP, Created)
VALUES(Cus_Title, Cus_Name, Cus_Surname, Cus_Email, Cus_Password, Cus_Status, Cus_LoginIP, Cus_Created);
SET Cus_ID = LAST_INSERT_ID();


IF(Pho_Number != '') THEN -- Customer has registered a mobile number
INSERT INTO customers_phones(CustomerID, Type, Number)
VALUES(Cus_ID, 'Mobile', Pho_Number);
END IF;

IF EXISTS(SELECT ID, Name, PostCode FROM companys WHERE Name = Com_Name AND PostCode = Com_PostCode) THEN
SET Com_ID = (SELECT ID FROM companys WHERE Name = Com_Name AND PostCode = Com_PostCode);
ELSE
INSERT INTO companys(Name, BuildingNumber, Address, Street, City, County, PostCode)
VALUES(Com_Name, Com_BuildingNumber, Com_Address, Com_Street, Com_City, Com_County, Com_PostCode);
SET Com_ID = LAST_INSERT_ID();
END IF;

INSERT INTO customers_order_delivery(CustomerID, CompanyID)
VALUES(Cus_ID, Com_ID);

INSERT INTO customers_activations(CustomerID, ActivationToken, Expiry)
VALUES(Cus_ID, Act_ActivationToken, Act_Expiry);

INSERT INTO customers_subscriptions(CustomerID, Type, Method)
VALUES(Cus_ID, 'Newsletter', 'Email');
SET ReturnStatus = 'true';
SELECT ReturnStatus;
END IF;
END;


PHP bindings are as follows and are contained within a try/catch block:

$SQL = 'call new_account(:Cus_Title, :Cus_Name, :Cus_Surname, :Cus_Email, :Cus_Password, :Cus_Status, :Cus_LoginIP, :Cus_Created, :Pho_Mobile, :Com_Name, :Com_BuildingNumber, :Com_Address, :Com_Street, :Com_County, :Com_City, :Com_PostCode, :Act_ActivationToken, :Act_Expiry, :ReturnStatus)';
$Statement = $Connection->prepare($SQL);
#Bind parameters
$Statement->bindParam(':Cus_Title', $_Form->Validated['Title']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Cus_Name', $_Form->Validated['Name']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Cus_Surname', $_Form->Validated['Surname']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Cus_Email', $_Form->Validated['Email']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Cus_Password', $_Form->Validated['Password']['input'], PDO::PARAM_LOB);
$Statement->bindParam(':Cus_Status', $_Form->Validated['UserStatus']['input'], PDO::PARAM_INT);
$Statement->bindParam(':Cus_LoginIP', $_Form->Validated['LoginIP']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Cus_Created', $_Form->Validated['CreatedOn']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Pho_Mobile', $_Form->Validated['Mobile']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Act_ActivationToken', $_Form->Validated['ActivationToken']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Act_Expiry', $_Form->Validated['Expiry']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_Name', $_Form->Validated['Company']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_BuildingNumber', $_Form->Validated['BuildingNumber']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_Address', $_Form->Validated['Address']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_Street', $_Form->Validated['Street']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_City', $_Form->Validated['City']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_County', $_Form->Validated['County']['input'], PDO::PARAM_STR);
$Statement->bindParam(':Com_PostCode', $_Form->Validated['PostCode']['input'], PDO::PARAM_STR);
$Statement->bindParam(':ReturnStatus', $ReturnStatus, PDO::PARAM_INT | PDO::PARAM_INPUT_OUTPUT, 3);
$Statement->execute();
$AccountCreationStatus = $Statement->fetchColumn();  //Check the account was successfully created


$AccountCreationStatus = ($AccountCreationStatus == 'true') ? true : false; // Convert return from SP as currently its buggy as cannot return INT or BOOL
if($AccountCreationStatus){ // New account was successfully created
#Send new user activation email

嗨R3uK,EdChum,Wtower,Rajesh和Pinkal 我的帖子不是重复的,因为在引用的解决方案中 在那种情况下,他们谈论无法连接到MySQL。如果你们都仔细阅读我的帖子,你会发现我可以连接到MySQL,正如我的SP和脚本能够运行所证明的那样。将正确的值作为字符串返回。但是如果我尝试将返回值设置为1或0的int,我仍然可以从SP获得正确的返回输出,但在输出后立即添加3个php错误消息,他们没有提及"旧认证。 为避免混淆和清晰起见,错误消息全部为:

    • (!)警告:未知:第0行的未知数据提前结束(mysqlnd_wireprotocol.c:1116)
    • (!)警告:未知:RSET_HEADER数据包比第0行的未知数短1个字节
    • (!)警告:未知:在第0行的未知状态下读取结果集的标题时出错
  1. 在我发布之前,我确实花了相当多的时间寻找可能的解决方案并确实看到了帖子并在MySQL中检查了我的密码并且使用了新的身份验证...除非我失踪了一些东西。下次将帖子作为重复发布之前请多加小心,因为从我的帖子中可以清楚地知道它不是。

    那说任何帮助都会非常感激。 PHP Addict

1 个答案:

答案 0 :(得分:0)

我猜你刚刚在帖子中跳过了一些信息,所以完整的错误信息听起来像这样:

...: Premature end of data (mysqlnd_wireprotocol.c:554) in ...
...: OK packet 1 bytes shorter than expected in ...
...: mysqlnd cannot connect to MySQL XXX using the old insecure authentication. Please use an administration tool to reset your password with the command SET PASSWORD = PASSWORD('your_existing_password'). This will store a new, and more secure, hash value in mysql.user. If this user is used in other scripts executed by PHP XXX or earlier you might need to remove the old-passwords flag from your my.cnf file in ... 

如果是这样,您可以按照错误文本中的信息轻松解决问题。您可以找到更多详细信息here