私は、Webサービスから取得したXMLを処理し、その結果をデータベースに挿入するためにPHPを使用しています。私はレコードを挿入するストアドプロシージャを作成していると私は、このようなもの、私はその後、複数回実行したい文を準備するためにPDOを使用しています:ストアドプロシージャをプリペアドステートメントで複数回呼び出す
$st = $this->db->prepare('CALL AddClient(:Name, :Id, :Priority, :Territory, :DateCreated, :Result)');
$st->bindParam(':Name', $Name, PDO::PARAM_STR);
$st->bindParam(':Id', $Id, PDO::PARAM_INT);
$st->bindParam(':Priority', $Priority, PDO::PARAM_STR);
$st->bindParam(':Territory', $Territory, PDO::PARAM_STR);
$st->bindParam(':DateCreated', $dateFormat, PDO::PARAM_STR);
$st->bindParam(':Result', $result, PDO::PARAM_STR);
foreach ($this->xml->AccountsDataSet->MainRecord as $Account) {
$Name = (string) $Account->AcctDesc;
$Id = (int) $Account->AcctID;
if ($num = (int)$Account->CDF309607) {
$Priority = self::$priorityFields[$num];
} else {
$Priority = '';
}
if (! $Territory = (string) $Account->AcctState) {
$Territory = '';
}
$date = new DateTime($Account->AcctCreationDate, new DateTimeZone('UTC'));
$dateFormat = $date->format('Y-m-d H:i:s');
$st->execute();
echo $result . '<br />';
}
この例では「:検索結果を」プロシージャの出力値になります。しかし、私はこの仕事を全然できない。プロシージャーコードとPHPの両方でout putパラメーターを省略すると、1つの行が挿入されますが、ループ内の後続呼び出しは失敗します。この作業を行うためには、ループのたびに新しい文を準備してから、パラメータを文に再度バインドする必要があります。私はまだプロシージャの出力パラメータでこの作業を行うことはできませんし、処理するためにいくつかの戻り値を得るためにプロシージャの値を選択する必要があります。
誰も私がこれに間違っていると知っていますか?理想的には、ステートメントを一度準備してから、結果をループして、毎回新しいデータで実行したいと考えています。私はこのすべての仕事をするために欠けているトリックはありますか?私はApache 2.2.17、PHP 5.3.5、MySQL 5.5.8を使ってWindows 7で開発しています。
EDIT: まあ、ループ内のステートメントを実行するに答え、複数回のPDOStatementを呼び出した後にPDOStatement ::続くcloseCursor()メソッドを毎回呼び出すことのようです::実行()。しかし、出力パラメータの値をPHPに戻す方法についてはまだ考えていません。
EDIT は、ここでプロシージャのコードです:出力パラメータに文字列の長さを加えること
CREATE
PROCEDURE foo.AddClient(IN ClientName VARCHAR(255), IN Client_Id INT UNSIGNED, IN Priority VARCHAR(255), IN Territory VARCHAR(100), IN DateCreated DATETIME, OUT Result VARCHAR(100))
COMMENT 'Procedure to add a new client to the database'
BEGIN
#Declare variables.
DECLARE Priority_Id, Territory_Id TINYINT UNSIGNED DEFAULT NULL;
# Check if a Priority is defined. If so get the id, if not add it and get the id
IF LENGTH(Priority) > 0 THEN
SELECT
PriorityId
INTO
Priority_Id
FROM
client_priority
WHERE
Name = Priority;
IF Priority_Id IS NULL THEN
INSERT INTO client_priority (Name) VALUES (Priority);
SET Priority_Id = LAST_INSERT_ID();
END IF;
END IF;
#Check if a Territory is defined. If so get the id, if not add it and get the id.
IF LENGTH(Territory) > 0 THEN
SELECT
TerritoryId
INTO
Territory_Id
FROM
territories
WHERE
Name = Territory;
IF Territory_Id IS NULL THEN
INSERT INTO territories (Name) VALUES (Territory);
SET Territory_Id = LAST_INSERT_ID();
END IF;
END IF;
#Add the details of the client.
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '23000'
SET Result = 'Client already exists'; # Error handler in case client with the same name already exists.
INSERT INTO clients
(ClientId, Name, PriorityId, TerritoryId, DateCreatedSalesNet) VALUES (Client_Id, ClientName, Priority_Id, Territory_Id, DateCreated);
SET Result = 'Client Inserted';
END;
END
保存されたprocを投稿できますか? –