Oracle 7 EXECUTE IMMEDIATE 替代方案

Oracle 7 EXECUTE IMMEDIATE alternative

我正在使用 旧版数据库,它是 Oracle 7,我想使用 EXECUTE IMMEDIATE 执行转换为 varchar 的字节,但我发现所述函数已发布 Oracle 10g.

这是我的例子:

存储过程:

create or replace procedure QUERY_EXECUTOR
(
    IN_QUERY_STATEMENT IN LONG RAW
)
AS
BEGIN

    declare CONVERTED_QUERY varchar2(32767); 
    cursor c1 is select IN_QUERY_STATEMENT from dual;
    BEGIN  
        for r2 in c1 loop
        converted_query:=UTL_RAW.CAST_TO_VARCHAR2(substr(r2.IN_QUERY_STATEMENT,0)); 
        dbms_output.put_line(converted_query);
        end loop;
        execute immediate converted_query; --THIS LINE
    END;

END;

查看立即执行命令。当我评论出来的时候。 SP在Oracle 7中编译成功。

但是在 Oracle 12g(我们目前使用的)上,示例代码执行得很好。

EXEC QUERY_EXECUTOR('53454c45435420312046524f4d204455414c3b');

转换后为"SELECT 1 FROM DUAL;";

这种转换和执行是我们处理当前问题的最佳方式,因此非常感谢您的回答。

问题

如果我们不能在 Oracle 7 中使用上述命令,是否有其他方法或替代解决方案?

编辑:

找到这个 topic 这是执行文字字符串命令的另一个实用程序,但它仅适用于 DDL 命令。

编辑 2:解决方案

@Wernfried Domscheit 爵士的回答帮了我的忙。我将答案与我的逻辑结合起来。虽然它并不完美,但我认为我需要阅读更多文档。

首先,DBMS_SQL.VARCHAR2A 似乎在 Oracle7 中不起作用。

然后我发现 this 具有不同的 DBMS_SQL.PARSE 方法签名。我使用它是因为它说 DBMS_SQL.V7 所以它可能是 Oracle 7 但我真的不知道。我需要阅读文档。

create or replace procedure QUERY_EXECUTOR
(
    IN_QUERY_STATEMENT IN LONG RAW
)
AS
BEGIN
DECLARE
    res INTEGER;
    cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;
    CONVERTED_QUERY varchar2(32767);
    cursor c1 is select IN_QUERY_STATEMENT from dual;
    BEGIN
        for r2 in c1 loop
            converted_query:=UTL_RAW.CAST_TO_VARCHAR2(substr(r2.IN_QUERY_STATEMENT,0)); 
        end loop;
        DBMS_SQL.PARSE(cur, converted_query, DBMS_SQL.V7);
        dbms_output.put_line(cur);
        res := DBMS_SQL.EXECUTE(cur);
        DBMS_SQL.CLOSE_CURSOR(cur);
    END;
END;

PS:

我不是 DBA,所以如果我在解决方案部分做错了什么,你能提出你的意见以获得更好的解决方案吗?非常感谢回答。

如果我理解你是对的,你的问题是:如何在 Oracle 7 中执行动态 SQL。

pl/sql 'execute' 命令在 Oracle 7 中不存在,但包 'dbms_sql' 存在并被描述 PL/SQL User’s Guide and Reference, Release 2.3, Part No. A32542-1 'Chapter 5: Interaction with Oracle' 第 5-7 页 并在 Oracle 7 Server Application Developer's Guide, Release 7.3, Part No. A32536-1 'Chapter 10: Using Dynamic SQL',第 10-1 页

对于 Oracle 8i 之前的动态,您必须使用 DBMS_SQL 包。会是这样的:

DECLARE
   sqlcmd DBMS_SQL.VARCHAR2A;
   res INTEGER;
   cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR;

BEGIN

    sqlcmd(1) := 'SELECT 1';
    sqlcmd(sqlcmd.LAST+1) := 'FROM dual';

    DBMS_SQL.PARSE(cur, sqlcmd, sqlcmd.FIRST, sqlcmd.LAST, TRUE, DBMS_SQL.NATIVE); 
    res := DBMS_SQL.EXECUTE(cur);
    DBMS_SQL.CLOSE_CURSOR(cur);

END;

据我记得DBMS_SQL.VARCHAR2A是最近推出的,也许你必须使用DBMS_SQL.VARCHAR2_TABLEDBMS_SQL.VARCHAR2S

为了从 SELECT 获得结果,您必须使用 FETCH_ROWSEXECUTE_AND_FETCH 函数,文档应该对您有所帮助。