Sql 根据Oracle版本执行查询
我必须在几个oracle服务器/实例上执行sql。 如果oracle版本是12g,那么我要查询的表是“foo”。如果oracle版本为11g,则该表将为“bar” 我试过一些,但我对游标不太了解Sql 根据Oracle版本执行查询,sql,oracle,plsql,Sql,Oracle,Plsql,我必须在几个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
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;
下一个匿名子程序可以帮助您解决问题
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
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;
我认为这实际上是一个非常糟糕的计划。如果版本不同,只需针对每个版本编写不同的过程,如果它们相同,则将表命名为相同。继续执行此计划很可能是一场维护噩梦,在以后的问题分析和解决中也会如此。但您可以通过条件编译来实现这一点。例如:
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;
我认为这实际上是一个非常糟糕的计划。如果版本不同,只需针对每个版本编写不同的过程,如果它们相同,则将表命名为相同。继续执行此计划很可能是一场维护噩梦,在以后的问题分析和解决中也会如此。但您可以通过条件编译来实现这一点。例如:
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
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;
/
我希望这对某人有所帮助。另一种方法
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;
/
我希望这对其他人有所帮助。两个表是否都存在于每个版本中?如果是这样的话,frjtorres的答案应该有效。如果这些表甚至不存在,那么您可能需要使用条件编译;所以我不能只做
desc foo
并基于它执行查询两个表在每个版本中都存在吗?如果是这样的话,frjtorres的答案应该有效。如果这些表甚至不存在,那么您可能需要使用条件编译;因此,我不能像条件编译解决方案那样,只做desc foo
并基于iTunes执行查询。这种方法要求foo和BAR在两个数据库版本中都存在,也许是这样,问题还不清楚。但如果不是这样,则需要使用记录类型而不是%rowtype
来定义目标变量,@APC FOO和BAR可能不存在于所有数据库中。你能提供一个记录类型的例子吗?与条件编译解决方案不同,这种方法要求FOO和BAR在两个数据库版本中都存在,也许是这样,问题还不清楚。但如果不是这样,则需要使用记录类型而不是%rowtype
来定义目标变量,@APC FOO和BAR可能不存在于所有数据库中。你能提供一个记录类型的例子吗?