根据Oracle版本执行查询



我必须在几个Oracle服务器/实例上执行SQL。 如果Oracle版本为12G,则我要查询的表格为" foo"。如果Oracle版本为11G,则表将为" bar'

我尝试了一些事情,但是我对光标

不了解
    CURSOR C1
    IS
             SELECT version FROM V$INSTANCE

    MY_VERSION VARCHAR2 ( 500 );
BEGIN
    OPEN C1;
    FETCH C1
    INTO
           MY_QUERY;
    CLOSE C1;
    IF MY_QUERY like '%12.%
    THEN
        EXECUTE IMMEDIATE 'select * from foo';
ELSE IF MY_QUERY like '%11.%'
        EXECUTE IMMEDIATE 'select * from bar';
    END IF;
END;

我认为这实际上是一个非常糟糕的计划。如果版本不同,只需编写一个针对每个版本的不同过程,如果它们相同,则将表命名相同。继续执行该计划可能是一场维护噩梦,并且在以后的问题分析和解决方案中显然会如此。但是您可以通过有条件的汇编来完成此操作。示例:

CREATE OR REPLACE PROCEDURE foo_or_bar  AS
    $IF DBMS_DB_VERSION.VER_LE_11 $THEN
    type myfoobar_t is table of bar%rowtype;
    $ELSE
    type myfoobar_t in table of foo%rowtype;
    $END
    myfoobar myfoobar_t;
BEGIN
    $IF DBMS_DB_VERSION.VER_LE_11 $THEN
    select * 
      bulk collect 
      into myfoobar
      from bar; 
    $ELSE
    select * 
      bulk collect 
      into myfoobar
      from foo;     
    $END
   ... 
end foo_or_bar;

下一个匿名子程序可以帮助您解决问题。

declare
     type v_foo is table of foo%rowtype index by pls_integer;
     t_foo v_foo;
     type v_bar is table of bar%rowtype index by pls_integer;
     t_bar v_bar;
begin
    if dbms_db_version.version = 12 then
        execute immediate 'select * from foo' bulk collect into t_foo;
    elsif dbms_db_version.version = 11 then
        execute immediate 'select * from bar' bulk collect into t_bar;
    end if;
end;

另一种方法,

DECLARE
    v_SQL VARCHAR2(2000);
    v_instance VARCHAR2(100);
BEGIN
    SELECT name INTO v_instance FROM V$database;
    IF (NVL(v_instance, 'EE12C') = 'EE12C') THEN
        -- 12C related script goes here
        v_SQL := '';
    END IF;    
    IF (NVL(v_instance, 'EE19C') = 'EE19C') THEN 
        -- 19C related script goes here
        v_SQL := '';
    END IF;        
END;
/

我希望这对某人有帮助。

解决此问题的唯一正确方法是将一些编译器指令放入源代码中,以便将其移植到较新的版本中。这是通过使用(在Oracle版本或等于11中不支持的代码的示例(

来完成的。

$如果dbms_db_version.ver_le_11 $,则在Oracle版本中或等于11 之前支持的程序的电话$ else呼叫来自Oracle版本12及向上支持的过程的电话$ end

例如,来自Oracle 18 dbms_lock.sleep dbms_session.sleep 替换。因此,如果您使用dbms_lock.sleep,则需要在第18版或更高版本上替换dbms_session.sleep。通过这样做,该代码不再不再在以前的版本上运行,除非您使用编译器指令并实现这两种方法,一种用于版本,而在此之后的版本中进行。

在此处阅读更多:Oracle DBMS_DB_Version

最新更新