可以直接调用SQL存储过程,但不能在Java应用程序中调用

时间:2016-12-06 02:44:02

标签: java sql oracle stored-procedures

我编写了一个PL / SQL过程,我试图从Java应用程序调用它。问题是,当我在sqlplus中调用该过程时,它完全按预期运行,但是当它从Java应用程序运行时,会产生以下错误:

SQLException Message:ORA-01453: SET TRANSACTION must be first statement of transaction
ORA-06512: at "JTRIBUNA.ASSIGN_PILOT2", line 24
ORA-06512: at line 1

Java方法如下:

private static boolean assignFlight() throws SQLException {
    CallableStatement cstmt = null;
    try {
        // Prepare to call the stored procedure
        System.out.println("Assigning flights...");
        cstmt = connection.prepareCall("{call assign_pilot2()}");
        cstmt.execute();
    } catch (SQLException e) {
        System.out.println("Problem with assignFlight ");
        throw (e); // let caller handle after above output
    } finally {
        //closeCallableStatement doesn't compile
        //closeCallableStatement(cstmt);
        cstmt.close();
    }
    return true;
}

这是创建程序的脚本:

create or replace procedure assign_pilot2  as

--cursor through flights
CURSOR fl_cur IS
    SELECT * FROM flights
    ORDER BY departs;

--createSP1
CURSOR pl_cur IS
    SELECT e.eid, ename, a.aid, cruisingrange
    FROM employees1 e
    INNER JOIN certified1 c
    ON e.eid=c.eid
    INNER JOIN aircraft a
    ON c.aid=a.aid
    ORDER BY cruisingrange ASC;

pl_row pl_cur%ROWTYPE;
fl_row fl_cur%ROWTYPE;
is_assigned number;
need_delay number;

BEGIN
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    dbms_output.put_line('hi from SP assign_pilot2');
    --loop through flights
    FOR fl_row IN fl_cur LOOP
        DBMS_OUTPUT.PUT_LINE('processing flight '|| fl_row.flno);

        --loop cursor through pilots
        FOR pl_row IN pl_cur LOOP
            --see if the range is long enough
            IF (pl_row.cruisingrange >= fl_row.distance) THEN
                --see if pilot is available (not present in flight_assignments)
                SELECT COUNT(*)
                INTO is_assigned
                FROM flight_assignments FA
                WHERE FA.eid = pl_row.eid;

                --if pilot is available
                IF(is_assigned = 0) THEN
                    --add fight to flight_assignments;
                    INSERT INTO flight_assignments
                    VALUES(fl_row.flno, pl_row.aid, pl_row.eid);
                    EXIT;
                END IF;
            END IF;
        END LOOP;

        --if flight isn't present in flight_assignments, delay it
        SELECT COUNT(*)
        INTO need_delay
        FROM flight_assignments FA
        WHERE FA.flno = fl_row.flno;

        IF(need_delay = 0) THEN
            INSERT INTO delayed_flights
            VALUES(fl_row.flno);
        END IF;
    END LOOP;
    COMMIT;
END;
/
show errors;

让我感到困惑的部分是错误是语法错误。正如我之前提到的,我可以正常地从sqlplus调用这个过程,它完全符合我的要求。

我不熟悉使用事务性SQL,因此非常感谢任何帮助!

0 个答案:

没有答案