1

初めてstackoverflowへの投稿を使用する必要がありました(主にサイト自体が原因です)が、これでうまくいきました。

基本的な概要は、PDO トランザクションで 2 つのストアド プロシージャ (テーブルの挿入) を実行しようとしていることです。この問題は、私が試したすべての回避策と一致しています。どちらも実行され、最初のレコードは正常にレコードに入力され、2 番目はエラーや例外が発生しません (yes$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 パラメータを一重引用符で囲んでいることです。これを止める方法がわかりません(マークされたプレースホルダーを試してみました..execute()内で配列を使用するなど)

私は困惑しています、それは遅いです、ここに私が見逃したばかげた理由があることを願っています. ありがとうございました

編集: execute、commit、および closeCursor 関数をすべてエコーして、1 を返しました。

4

0 に答える 0