在程序内部选择ROWID时出现问题

时间:2009-08-30 22:09:20

标签: database oracle rowid

我花了好几个小时试图找到解决这个问题的方法,但由于我无法找到,所以我决定在这里问。

我正在执行一个过程,根据行ROWID从表中检索信息,结果我正在使用execute immediate进行一些自定义查询。我已将问题简化为以下几行,我正在SQL Developer中直接执行:

declare
  row_id   ROWID;
  consulta VARCHAR2(1000);
begin  
  row_id := 'AAAEC5AAFAAAADHAAC';
  select 'insert into ' || 
    (select TABLA       from BITACORA where rowid = row_id) || ' values(' || 
    (select VALOR_VIEJO from BITACORA where rowid = row_id) || ')' 
    into Consulta from dual;
    DBMS_OUTPUT.PUT_LINE(Consulta);
    --execute immediate Consulta;        
end;

之前的行无法正常工作。当我打印Consulta的内容时,它会显示:

insert into  values()

但是如果我删除变量row_id并将其直接放在这样的查询中,它就会起作用:

declare
  consulta VARCHAR2(1000);
begin  
  select 'insert into ' || 
    (select TABLA       from BITACORA where rowid = 'AAAEC5AAFAAAADHAAC') || ' values(' || 
    (select VALOR_VIEJO from BITACORA where rowid = 'AAAEC5AAFAAAADHAAC') || ')' 
    into Consulta from dual;
    DBMS_OUTPUT.PUT_LINE(Consulta);
    --execute immediate Consulta;        
end;

显示我的期望,例如:

insert into MI_TABLA values(1,'Hola','Adios',3,1)

这与工作无关,因此不会担心性能/安全性。感谢您的任何反馈。

3 个答案:

答案 0 :(得分:1)

您可能必须使用CHARTOROWID()转换函数:

row_id := CHARTOROWID('AAAEC5AAFAAAADHAAC');

根据oracle doc,对于数据类型urowid,这不是必需的。

答案 1 :(得分:0)

你能得到一个解释计划:

select TABLA       from BITACORA where rowid = 'AAAEC5AAFAAAADHAAC';

和此:

select TABLA       from BITACORA where rowid = :1;

这取决于您所使用的Oracle版本,但请尝试以下操作:

explain plan for
select TABLA       from BITACORA where rowid = 'AAAEC5AAFAAAADHAAC';

select plan_table_output from table(dbms_xplan.display('plan_table',null,'serial'));

delete from plan table;

然后这个:

explain plan for
select TABLA       from BITACORA where rowid = :1;

select plan_table_output from table(dbms_xplan.display('plan_table',null,'serial'));

delete from plan table;

使用输出更新您的问题,这可能会提供更多线索。

答案 2 :(得分:0)

你为什么选择DUAL?除非你在简化中省略了一些重要的东西,否则它应该对你有用:

declare
  row_id   ROWID;
  consulta VARCHAR2(1000);
begin  
  row_id := 'AAAEC5AAFAAAADHAAC';
  select 'insert into ' ||TABLA || ' values(' ||VALOR_VIEJO|| ')' 
  into   Consulta
  where rowid = row_id; 
  DBMS_OUTPUT.PUT_LINE(Consulta);
  execute immediate Consulta;        
end;
/