Php oci_执行标识符必须声明为ORA-06550

Php oci_执行标识符必须声明为ORA-06550,php,oracle,stored-procedures,Php,Oracle,Stored Procedures,程序如下: FUNCTION f_exists ( p_pidm gobansr.gobansr_pidm%TYPE, p_num gobansr.gobansr_num%TYPE, p_rowid gb_common.internal_record_id_type DEFAULT NULL) RETURN VARCHAR2 IS -- TYPE quer

程序如下:

FUNCTION f_exists (
  p_pidm                      gobansr.gobansr_pidm%TYPE,
  p_num                       gobansr.gobansr_num%TYPE,
  p_rowid                     gb_common.internal_record_id_type DEFAULT NULL)
RETURN VARCHAR2 IS
--
  TYPE queryone_ref IS REF CURSOR;
  lv_cursor queryone_ref;
  lv_tempout VARCHAR2(1) := 'N';
BEGIN
--
-- Assign the cursor variable to the appropriate cursor
--
  IF p_rowid IS NOT NULL THEN
    OPEN lv_cursor for
    SELECT 'Y'
      FROM gobansr
     WHERE ROWID = p_rowid;
  ELSE
    OPEN lv_cursor for
    SELECT 'Y'
      FROM gobansr
     WHERE gobansr_pidm = p_pidm
       AND gobansr_num = p_num;
  END IF;
  FETCH lv_cursor INTO lv_tempout;
  CLOSE lv_cursor;
  RETURN lv_tempout;
END f_exists;
$conn = oci_connect($username, $password, $db);
$sql = 'BEGIN "gb_pin_answer"."f_exists"(:p_pidm, :p_num); END;';
$stmt = oci_parse($conn, $sql);

if (!$conn)
  exit("DB did not connect.");

$p_pidm = 36706;
$p_num = 1;

oci_bind_by_name($stmt,':p_pidm',$p_pidm,5);
oci_bind_by_name($stmt,':p_num',$p_num,1);

if (!oci_execute($stmt))
  exit("Procedure Failed.");

oci_commit($conn);
oci_close($conn);
运行/查询存储过程的PHP代码:

FUNCTION f_exists (
  p_pidm                      gobansr.gobansr_pidm%TYPE,
  p_num                       gobansr.gobansr_num%TYPE,
  p_rowid                     gb_common.internal_record_id_type DEFAULT NULL)
RETURN VARCHAR2 IS
--
  TYPE queryone_ref IS REF CURSOR;
  lv_cursor queryone_ref;
  lv_tempout VARCHAR2(1) := 'N';
BEGIN
--
-- Assign the cursor variable to the appropriate cursor
--
  IF p_rowid IS NOT NULL THEN
    OPEN lv_cursor for
    SELECT 'Y'
      FROM gobansr
     WHERE ROWID = p_rowid;
  ELSE
    OPEN lv_cursor for
    SELECT 'Y'
      FROM gobansr
     WHERE gobansr_pidm = p_pidm
       AND gobansr_num = p_num;
  END IF;
  FETCH lv_cursor INTO lv_tempout;
  CLOSE lv_cursor;
  RETURN lv_tempout;
END f_exists;
$conn = oci_connect($username, $password, $db);
$sql = 'BEGIN "gb_pin_answer"."f_exists"(:p_pidm, :p_num); END;';
$stmt = oci_parse($conn, $sql);

if (!$conn)
  exit("DB did not connect.");

$p_pidm = 36706;
$p_num = 1;

oci_bind_by_name($stmt,':p_pidm',$p_pidm,5);
oci_bind_by_name($stmt,':p_num',$p_num,1);

if (!oci_execute($stmt))
  exit("Procedure Failed.");

oci_commit($conn);
oci_close($conn);
我已经向DBA验证了我对存储过程具有执行权限,并且PHP成功连接到数据库服务器

它返回以下错误:

消息:oci_execute():ORA-06550:第1行第8列:PLS-00201: 标识符“gb_pin_answer.f_exists”必须声明为ORA-06550:行 1,第8列:PL/SQL:语句被忽略

更新:

我能够运行:
select gb\u pin\u answer.f\u存在('36706','2')作为dual的结果,它返回Y

现在我需要弄清楚如何在我的php中使用此存储过程:

PROCEDURE p_create(
  p_pidm                      gobansr.gobansr_pidm%TYPE,
  p_num                       gobansr.gobansr_num%TYPE,
  p_gobqstn_id                gobansr.gobansr_gobqstn_id%TYPE DEFAULT NULL,
  p_qstn_desc                 gobansr.gobansr_qstn_desc%TYPE DEFAULT NULL,
  p_ansr_desc                 gobansr.gobansr_ansr_desc%TYPE,
  p_ansr_salt                 gobansr.gobansr_ansr_salt%TYPE,
  p_user_id                   gobansr.gobansr_user_id%TYPE DEFAULT gb_common.f_sct_user,
  p_data_origin               gobansr.gobansr_data_origin%TYPE,
  p_rowid_out             OUT gb_common.internal_record_id_type) IS
--
  lv_gobansr_rec    gobansr%ROWTYPE;
  error_message     gb_common_strings.err_type;

  lv_hashed_answer  gobansr.gobansr_ansr_Desc%type;
  lv_salt           gobansr.gobansr_ansr_salt%type;
BEGIN
--
-- Make sure the record doesn't already exist
--
  IF (gb_pin_answer.f_exists(p_pidm,p_num)='Y') THEN
    error_message :=  gb_common_strings.f_append_error(error_message,
                        gb_pin_answer_strings.f_get_error('RECORD_EXISTS'));
  END IF;
--
  IF (error_message IS NOT NULL) THEN
    RAISE_APPLICATION_ERROR(gb_common_strings.ERR_CODE, error_message);
  END IF;

  lv_salt := gspcrpt.F_GET_SALT(length(replace(p_ansr_desc,' ')));
  gspcrpt.p_saltedhash(lower(replace(p_ansr_desc,' ')),lv_salt,lv_hashed_answer);

--
-- Execute business rules
--
  gb_pin_answer_rules.p_validate(
    p_pidm               => p_pidm,
    p_num                => p_num,
    p_gobqstn_id         => p_gobqstn_id,
    p_qstn_desc          => p_qstn_desc,
    p_ansr_desc          => p_ansr_desc,
    p_ansr_salt          => lv_salt,
    p_user_id            => p_user_id,
    p_data_origin        => p_data_origin);
--
-- This is where the local user exit call, if defined, will occur.
--
  /* -- No local call
    p_pidm                     => p_pidm,
    p_num                      => p_num,
    p_gobqstn_id               => p_gobqstn_id,
    p_qstn_desc                => p_qstn_desc,
    p_ansr_desc                => p_ansr_desc,
    p_ansr_salt                => lv_salt,
    p_user_id                  => p_user_id,
    p_data_origin              => p_data_origin);
*/
--
-- Build the DML record
--
  lv_gobansr_rec := f_build_gobansr_rec(
    p_pidm               => p_pidm,
    p_num                => p_num,
    p_gobqstn_id         => p_gobqstn_id,
    p_qstn_desc          => p_qstn_desc,
    p_ansr_desc          => lv_hashed_answer,
    p_ansr_salt          => lv_salt,
    p_user_id            => p_user_id,
    p_data_origin        => p_data_origin);
--
-- Set the activity date
--
  lv_gobansr_rec.gobansr_activity_date := SYSDATE;
--
-- Delegate to the DML layer
--

  dml_gobansr.p_insert(lv_gobansr_rec, p_rowid_out);
--
-- NOTE:  Banner Messaging Support logic is only called after a
--        successful DML operation
-- Check if messaging is enabled/licensed for this business entity.
--
  IF (gb_event.f_entity_publishable(gb_event.baseline_ind,
                                        M_ENTITY_NAME)) THEN
--    Register this business entity with messaging support.
    gb_pin_answer_rules.p_register_entity(
      p_operation_type     => gb_event.CREATE_OPERATION,
      p_pidm               => p_pidm,
      p_num                => p_num,
      p_gobqstn_id         => p_gobqstn_id,
      p_qstn_desc          => p_qstn_desc,
      p_ansr_desc          => p_ansr_desc,
      p_ansr_salt          => p_ansr_salt,
      p_user_id            => p_user_id,
      p_data_origin        => p_data_origin,
      p_internal_record_id => p_rowid_out);
  END IF;
END p_create;

您已经定义了一个函数,但所使用的PL/SQL表示您正在调用一个过程

PL/SQL应该如下所示:

$sql = 'BEGIN :f := "gb_pin_answer"."f_exists"(:p_pidm, :p_num); END;';

使用相同的凭据登录时,是否能够从SQLPlus调用该函数?此外,如果从SQLPlus调用函数,则需要执行以下操作:
从DUAL
中选择f_exists(arg,arg)。这可能值得在PHP代码中尝试,而不是在匿名块中尝试,但这只是一个猜测。我在Oracle SQL Developer中以同一用户的身份运行了它,(在mac上)并且select有效。我最初尝试使用gb_pin_answer.p_create,然后决定采取一些小步骤,从f_exists开始。我尝试将其作为select from dual运行,但也没有成功。在sql中,使用2个varchar2参数调用f_exists,而在php/oci代码中使用数值参数-可能自动转换失败。还可以尝试从sqlplus调用f_exists,其参数与代码中的参数相同(
('36706','1')
,而不是
('36706','2')
);