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

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

当我从上一篇文章"使用Oracle将三张表与PIVOT合并为一张"中获取代码,并在SQL Developer中单击"运行脚本"时,一切工作都很好,但是当我尝试从PHP执行相同的脚本时我收到文件" ORA-00900无效的SQL语句"-错误。 SQL Developers" Run Statement"也无法执行代码。看来我的代码不是使用" SQL语句"语法?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$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变量传递给函数以得到结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 '[cc lang="php"]';
          print_r($err);
          echo '

\\';
返回false;
}
}
}

那么有人可以告诉我如何重构代码吗?

感谢您的帮助!


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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语句:

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

函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
    }
}