简体   繁体   English

使用Oracle和PHP:在SQL Developer中有效,但是PHP文件导致ORA-00900:无效的语句

[英]Using Oracle and PHP: Works in SQL Developer but PHP file results ORA-00900: Invalid Statement

When I take the code from my earlier post " Using Oracle combine three tables to one with PIVOT " and hit "Run Script" in SQL Developer everything works just perfectly but when I try to execute same script from PHP file I get "ORA-00900 Invalid SQL Statement" -error. 当我从先前的文章“ 使用Oracle将三个表与PIVOT合并到一个表 ”中的代码并在SQL Developer中单击“运行脚本”时,一切工作都很好,但是当我尝试从PHP文件执行相同的脚本时,出现“ ORA-00900 SQL语句无效”-错误。 SQL Developers "Run Statement" fails as well to execute the code. SQL开发人员的“运行语句”也无法执行代码。 It seems my code isn't in the "SQL Statement" syntax? 看来我的代码不是“ SQL语句”语法?

My PHP code for putting sql script in the variable: 我的用于将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";

Then I pass the $sql variable to function for the results: 然后,我将$ 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;
        }
    }
}

So can anyone show me how to refactor the code? 那么谁能告诉我如何重构代码?

Thanks for any help! 谢谢你的帮助!

I think I figured that out. 我想我知道了。 It seems that needed to make from that PL/SQL script a procedure: 似乎需要从该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;
/

Then run that procedure in the database. 然后在数据库中运行该过程。 After that in the PHP file I had to refactor the sql statement: 之后,在PHP文件中,我不得不重构sql语句:

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

And the function: 和功能:

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM