Вызов хранимой процедуры в подготовленном выражении несколько раз - PullRequest
2 голосов
/ 24 января 2011

Я использую PHP для обработки некоторого XML, который я получаю от веб-службы, и для вставки результатов в базу данных.Я создал хранимую процедуру для вставки записей, и я использую 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 />';
              }

В этом примере ':Результат 'будет выходным значением из процедуры.Я не могу заставить эту работу вообще, хотя.Если я опускаю параметр out put и в коде процедуры, и в PHP, вставляется одна строка, но последующие вызовы в цикле завершаются неудачно.Чтобы сделать это, я должен подготовить оператор каждый раз в цикле, а затем снова связать параметры с оператором.Я все еще не могу заставить это работать с выходным параметром в процедуре, и мне приходится выбирать значение в процедуре, чтобы получить какое-то возвращаемое значение для обработки PHP.

Кто-нибудь знает, где я ошибаюсь с этим?В идеале я хотел бы подготовить оператор один раз, а затем просмотреть результаты, каждый раз выполняя его со свежими данными.Есть ли какие-то хитрости, которые мне не хватает, чтобы заставить все это работать?Я работаю на Windows 7 с Apache 2.2.17, PHP 5.3.5 и MySQL 5.5.8.

EDIT: Что ж, ответ на выполнение оператора несколько раз в цикле, по-видимому, заключается в вызове метода PDOStatement :: closeCursor () каждый раз после вызова PDOStatement :: execute (),До сих пор не знаю, как получить значение выходного параметра, возвращаемого в PHP.

РЕДАКТИРОВАТЬ Вот код для процедуры:

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

Ответы [ 3 ]

1 голос
/ 31 января 2011

Попробуйте добавить PDO :: PARAM_INPUT_OUTPUT:

 $st->bindParam(':Result', $result, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
1 голос
/ 02 февраля 2011

Дело в том, что вы не можете получить доступ к своим результатам, как это, см. Эти сообщения:

Таким образом, вам нужно будет сохранить результат в переменной MySQL, затем вы можете отобразить его следующим образом:

<?php
// change 
$st = $this->db->prepare('CALL AddClient(:Name, :Id, :Priority, :Territory, :DateCreated, :Result)');
// to
$st = $this->db->prepare('CALL AddClient(:Name, :Id, :Priority, :Territory, :DateCreated, @result)');

// remove this line
$st->bindParam(':Result', $result, PDO::PARAM_STR);

// change
$st->execute();
echo $result . '<br />';
// to 
$st->execute();
echo $this->db->query('SELECT @result')->fetchColumn() . '<br />';
1 голос
/ 24 января 2011

Попробуйте добавить длину строки к выходному параметру:

$st->bindParam(':Result', $result, PDO::PARAM_STR, 4000);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...