Параметр Oracle procedure out возвращает -1 из PHP


Я пытаюсь заставить процедуры Oracle выполняться из моей PHP-программы. Я создал простую процедуру тестирования:

CREATE OR REPLACE PROCEDURE "JKJ3"."GetUserLogin"
{
    userlogin_in in varchar2,
    userid_out out numeric,
    pass_out out varchar2
}
IS 
BEGIN
    SELECT user_id, password
    INTO userid_out, pass_out
    FROM "JKJ3"."USERS"
    WHERE login = userlogin_in;
END;

Я протестировал процедуру с помощью Aqua Data Studio:

DECLARE
    userid_out number;
    password_out number;
BEGIN
    "JKJ3"."GetUserLogin"('UserName', userid_out, password_out);
    dbms_enable(10000);
    dbms_put_line(userid_out);
    dbms_put_line(password_out);
END;

Это работает нормально, возвращает идентификатор пользователя и значение пароля. Пока все так хорошо!

Я попытался выполнить процедуру с PHP, но я не могу заставить процедуру работать, чтобы спасти свою жизнь! PHP-код:

PutEnv("ORACLE_HOME=/afs/cad/solaris/oraclient10.2");   
$this->conn=oci_connect($this->ucid, $this->dbpassword, $this->db);

// Check if connection was sucessful.
if ( !$this->conn ) {
    echo "Unable to connect: " . var_dump( OCIError() );
    die("Unable to connect: " . var_dump( OCIError() ));
}

$query = 'BEGIN "JKJ3"."GetUserLogin"(:login_in, :userid_out, :password_out); END;';

// Execute stored procedure to add new user and return the new users ID        
$command = oci_parse($this->conn, $query) or die('Cannot parse query');

$userid;
$password_out;

// bind the input variables and out put variables.
oci_bind_by_name($command, ':login_in', $login, 30) or die('cannot bind login');        
oci_bind_by_name($command, ':userid_out', $userid) or die('cannot bind userid');
oci_bind_by_name($command, ':password_out', $password_out, 300) or die('cannot bind password');              

oci_execute($command);
echo 'userid = ' . $userid . ' password = ' . $password_out;
oci_close($this->conn); 

Когда я выполняю это, я получаю идентификатор пользователя и пароль null.

Редактировать У меня те же результаты с другими процедурами, черт возьми, я даже зашел так далеко, что создал процедуру, которая принимает и присваивает статическое значение возвращаемой переменной, и я все равно ничего не получаю обратно (включая отсутствие ошибок).
http://www.oracle.com/technetwork/articles/fuecks-sps-095636.html (пример Сайхелло). И снова процедура работает из Aqua Data Studio, но не из PHP. Исключение не создается, переменная не возвращается.

Есть ли у Oracle что-то например, профилировщик SQL SERVER, который позволяет просматривать запросы, выполняемые в Oracle? (Хотя у меня нет прав администратора для сервера).

Не похоже, что это может быть основано на разрешениях, так как оно работает с рекламой.

Я могу без проблем выполнять запросы к базе данных, поэтому я уверен, что мое соединение работает.

Я упускаю что-то очевидное?

Author: Jake1164, 2012-07-05

2 answers

Я не знаком с PHP, но в соответствии с руководством страница для oci_bind_by_name:

Вы должны указать максимальную длину при использовании OUT-привязки, чтобы PHP выделяет достаточно памяти для хранения возвращаемого значения.

Кроме того, в вашем блоке PL/SQL есть по крайней мере одна незначительная синтаксическая ошибка. Вам нужно всегда использовать двойные кавычки при ссылке на GetUserLogin. (Хотя я сомневаюсь, что это ваша главная проблема. Если бы это было так, вы должны получить сообщение об ошибке.)

 3
Author: Jon Heller, 2012-07-05 05:58:33

После борьбы с этим с моей стороны было множество ошибок (не так ли всегда?):

  1. Отсутствие кавычек вокруг процедуры в блоке PL/SQL (и помеченный ответ на вопрос).

    $query = 'BEGIN "JKJ3"."GetUserLogin"(:login_in, :userid_out, :password_out); END;';

  2. Не включив отчеты об ошибках (и не видя, в чем заключаются проблемы).

error_reporting(E_ALL); ini_set('display_errors', true);

  1. Не имеющие выходных размеров.

  2. Передаю неправильную переменную, потому что у меня были переменные логина и пароля перенесенный ( опускает голову от стыда ).

 1
Author: Jake1164, 2012-07-05 23:25:12