使用 Oracle 和 PHP:在 SQL Developer 中工作,但 PHP 文件结果 ORA-00900:无效语句

Posted

技术标签:

【中文标题】使用 Oracle 和 PHP:在 SQL Developer 中工作,但 PHP 文件结果 ORA-00900:无效语句【英文标题】:Using Oracle and PHP: Works in SQL Developer but PHP file results ORA-00900: Invalid Statement 【发布时间】:2018-07-12 11:19:31 【问题描述】:

当我从我之前的帖子“Using Oracle combine three tables to one with PIVOT”中获取代码并在 SQL Developer 中点击“运行脚本”时,一切正常,但是当我尝试从 php 文件执行相同的脚本时,我得到“ORA-00900 Invalid SQL Statement “ -错误。 SQL Developers“运行语句”也无法执行代码。看来我的代码不是“SQL 语句”语法?

我将 sql 脚本放入变量的 PHP 代码:

$sql = "variable x REFCURSOR
DECLARE
    exam_ids   VARCHAR2(255);
BEGIN
    SELECT
        LISTAGG(''''
                  || exam_id
                  || ''' AS \"'
                  || exam_name
                  || '\"',',') WITHIN GROUP(
            ORDER BY
                exam_id ASC
        )
    INTO exam_ids
    FROM
        exam;

    OPEN :x FOR 'SELECT
        *
               FROM
        (
            SELECT
                u.user_id,
                u.user_name,
                e.exam_id,
                eu.exam_date
            FROM
                users u
                LEFT JOIN exam_user eu ON u.user_id = eu.user_id
                LEFT JOIN exam e ON e.exam_id = eu.exam_id
            ORDER BY
                u.user_id
        )
            PIVOT ( MAX ( exam_date )
                FOR exam_id
                IN ( ' || EXAM_IDS || ' )
            )
    ORDER BY
        1';
END;
/

print x";

然后我将 $sql 变量传递给结果:

function getSQLResult($sql, $conn) 
    $stmt = OCIParse($conn, $sql);

    if( $stmt === false ) 
        errorShutdown(__('...'), __('...'));
        die();
     else 
        //Executes a statement
        if (OCIExecute($stmt)) 
            return $stmt;
        
        else 
          $err = oci_error($stmt);
          echo '<pre>';
          print_r($err);
          echo '</pre>';
          return false;
        
    

那么谁能告诉我如何重构代码?

感谢您的帮助!

【问题讨论】:

如果是Oracle,为什么要标记SQL Server?我已经为你删除了不相关的标签。请不要在提问时标记您不使用的 RDBMS,这只会使试图帮助您的志愿者感到困惑。 【参考方案1】:

我想我明白了。似乎需要从那个 PL/SQL 脚本中创建一个过程:

CREATE OR REPLACE PROCEDURE getExamStatus(RC OUT SYS_REFCURSOR) AS
    exam_ids   VARCHAR2(255);
BEGIN
    SELECT
        LISTAGG(''''
                  || exam_id
                  || ''' AS \"'
                  || exam_name
                  || '\"',',') WITHIN GROUP(
            ORDER BY
                exam_id ASC
        )
    INTO exam_ids
    FROM
        exam;

    OPEN rc FOR 'SELECT
        *
               FROM
        (
            SELECT
                u.user_id,
                u.user_name,
                e.exam_id,
                eu.exam_date
            FROM
                users u
                LEFT JOIN exam_user eu ON u.user_id = eu.user_id
                LEFT JOIN exam e ON e.exam_id = eu.exam_id
            ORDER BY
                u.user_id
        )
            PIVOT ( MAX ( exam_date )
                FOR exam_id
                IN ( ' || EXAM_IDS || ' )
            )
    ORDER BY
        1';
END;
/

然后在数据库中运行该过程。之后在 PHP 文件中我不得不重构 sql 语句:

$sql = "BEGIN getExamStatus(:rc); END;";

以及功能:

function getSQLResult($sql, $conn) 
    $stmt = oci_parse($conn, $sql);

    if( $stmt === false ) 
        errorShutdown(__('...'), __('...'));
        die();
     else 
        $rc = oci_new_cursor($conn);
        oci_bind_by_name($stmt, ':rc', $rc, -1, OCI_B_CURSOR);
        if(!oci_execute($stmt)) 
            return false;
            //return oci_error($stmt);
        
        if(!oci_execute($rc)) 
            return false;
            //return oci_error($stmt);
        
        $results = array();
        while (($row = oci_fetch_array($rc, OCI_ASSOC+OCI_RETURN_NULLS)) != false) 
            $results[] = $row;
        
        oci_free_statement($stmt);
        oci_free_statement($rc);
        return $results;
    

【讨论】:

以上是关于使用 Oracle 和 PHP:在 SQL Developer 中工作,但 PHP 文件结果 ORA-00900:无效语句的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL Error

Oracle sqlplus 开启数据库权限不足如何解决

如何清理Oracle11g RAC日志文件

如何使用 ORACLE(OCI) 在 SQL/PHP 中进行更新查询

PL/SQL dev 工具连接远程服务器oracle注意点

如何从 PHP 获取 Oracle SQL 查询的 EXPLAIN PLAN?