我第一次不得不在 stackoverflow 上发布帖子(主要是由于网站本身),但这让我很受用。
基本失败是我正在尝试使用 PDO 事务执行 2 个存储过程(表插入)。问题与我尝试过的每个解决方法都是一致的:它们都执行,第一个成功输入记录,第二个没有错误或异常($connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
设置为是。
PHP 代码片段:
$qry_add_address = "call egen_add_address(
:district_id,
:country_id,
:city_id,
:addr1,
:addr2,
:postal,
:pobox,
NULL,
@newid
)";
$db_link->beginTransaction();
try {
$db_add_addr = $db_link->prepare($qry_add_address);
$db_add_addr->bindParam(':district_id',$address_inputs['district']['value'], PDO::PARAM_INT);
$db_add_addr->bindParam(':country_id',$address_inputs['country']['value'], PDO::PARAM_INT);
$db_add_addr->bindParam(':city_id',$address_inputs['city']['value'], PDO::PARAM_INT);
$db_add_addr->bindParam(':addr1',$address_inputs['addr1']['value'], PDO::PARAM_STR);
$db_add_addr->bindParam(':addr2',$address_inputs['addr2']['value'], PDO::PARAM_STR);
$db_add_addr->bindParam(':postal',$address_inputs['postal']['value'], PDO::PARAM_STR);
$db_add_addr->bindParam(':pobox',$address_inputs['pobox']['value'], PDO::PARAM_STR);
$db_add_addr->execute();
$newid = $db_add_addr->fetch(PDO::FETCH_NUM);
$venue_inputs['address_id']['value'] = $newid[0];
$db_link->commit();
$db_add_addr->closeCursor();
} catch (PDOException $e) {
$logs['error'][] = 'call egen_add_address : '.$e->getMessage();
$db_link->rollBack();
}
/*
* Add venue after address
*/
$qry_add_venue =
"call egen_add_venue(
:venue_type,
:address_id,
:zone_id,
:name,
:description,
:img_file,
:phone_num,
:website,
1,
:max_capacity,
'',
@newid)";
$db_link->beginTransaction();
try {
$db_add_venue = $db_link->prepare($qry_add_venue);
$db_add_venue->bindParam(':venue_type', $venue_inputs['type_id']['value']);
$db_add_venue->bindParam(':address_id', $venue_inputs['address_id']['value'], PDO::PARAM_INT);
$db_add_venue->bindParam(':zone_id',$address_inputs['zone_id']['value'], PDO::PARAM_INT);
$db_add_venue->bindParam(':name',$venue_inputs['name']['value'], PDO::PARAM_STR);
$db_add_venue->bindParam(':description',$venue_inputs['description']['value'], PDO::PARAM_STR);
$db_add_venue->bindParam(':img_file',$venue_inputs['img_file']['value'], PDO::PARAM_STR);
$db_add_venue->bindParam(':phone_num',$venue_inputs['phone_num']['value'], PDO::PARAM_STR);
$db_add_venue->bindParam(':website',$venue_inputs['website']['value'], PDO::PARAM_STR);
$db_add_venue->bindParam(':max_capacity',$venue_inputs['max_capacity']['value'], PDO::PARAM_INT);
$db_add_venue->execute();
$logs['newid'] = $db_add_venue->fetch(PDO::FETCH_ASSOC);
$db_link->commit();
$db_add_venue->closeCursor();
} catch (PDOException $e) {
$logs['error'][] = 'call egen_add_venue : '.$e->getMessage();
$db_link->rollBack();
}
添加场地存储过程:
DELIMITER $$
DROP PROCEDURE IF EXISTS egen_add_venue;
CREATE PROCEDURE egen_add_venue (
IN typid SMALLINT(3),
IN addid BIGINT(9),
IN znid BIGINT(10),
IN nm VARCHAR(90),
IN dscrptn TEXT,
IN imgfile VARCHAR(255),
IN phno VARCHAR(22),
IN url VARCHAR(2000),
IN actv BIT(1),
IN maxcap INT(7),
IN tzone VARCHAR(20),
OUT insertid BIGINT(9)
)
BEGIN
INSERT INTO venue (
`type_id`, `address_id`, `zone_id`,
`name_eng`, `description`, `img_file`, `phone_num`,
`website`, `active`, `max_capacity`, `timezone`)
VALUES (typid, addid, znid,
nm, dscrptn, imgfile, phno,
url, actv, maxcap, tzone);
select last_insert_id() as insertid;
END $$
DELIMITER ;
mysql 日志文件片段:
123 Query START TRANSACTION
123 Query call egen_add_address(
'36',
'124'
'18056'
'',
'',
'',
'0',
NULL,
@newid
)
123 Query START TRANSACTION
123 Query call egen_add_venue(
'1',
'62',
'97',
'HOME',
'sss',
'',
'',
'',
1,
0,
'',
@newid)
当我复制并粘贴存储过程调用的日志时,它可以工作并插入记录。我注意到的唯一一件事是用单引号将我的 int 参数包装起来,这在尝试将其放入 mysql cli 时并不重要。我不知道如何阻止它这样做(我尝试了标记的占位符..在execute()中使用数组等)
我被难住了,已经很晚了,希望有一个愚蠢的理由让我错过了。谢谢
编辑:我已经回显了执行、提交和 closeCursor 函数都返回 1。