如何动态地将表名传递给 PL SQL 游标?

Posted

技术标签:

【中文标题】如何动态地将表名传递给 PL SQL 游标?【英文标题】:how to Pass table name to PL SQL cursor dynamically? 【发布时间】:2015-07-20 13:21:17 【问题描述】:

我编写了一个 SQL 过程,其中我编写了一个游标,每次我必须动态地将表名传递给游标查询。

create or replace
PROCEDURE Add_DEN as 


v_TableName VARCHAR2(4000) := 'BO_USER_DATA';

cursor c_DEN is select * from BO_USER_DATA; // Want to pass dynamically ,now hardcoded
r_DEN c_DEN%ROWTYPE;

fetch c_DEN into r_DEN; 
v_Name := r_DEN."Name";

我可以这样写吗

cursor c_DEN is "select * from " || v_TableName; 

有什么帮助吗?

【问题讨论】:

您确定您已正确标记此问题吗?因为create or replacevarchar2:=%ROWTYPE 都不能在 SQL Server 中工作。 代码示例不是T-SQL 你真的需要光标吗?有几次应该使用游标,但在不需要游标时会非常频繁地使用它们。几乎在您进行 DML 的任何时候都不需要光标。 @Damien_The_Unbeliever 这是 PL SQL 。因为我们在 Oracle 上使用 SQL 开发人员执行此操作。 阅读有关 EXECUTE IMMEDIATE 和/或 DBMS_SQL 包的信息。 【参考方案1】:

这里是一个例子:

declare
  TYPE curtype IS REF CURSOR;
  l_cursor curtype;
  l_param  number;
  l_key number;
  l_value number;
  l_sql varchar2(200);
begin
  /* build your sql... */
  l_sql   := 'with data as (select 1 key, 100 value from dual union select 2, 200 from dual union select 3, 300 from dual union select 3, 301 from dual)' ||
         ' select key, value from data where key = :1';
  l_param := 3;

  open l_cursor for l_sql
    using l_param;

  loop
    fetch l_cursor
      into l_key, l_value;
    exit when l_cursor%notfound;

    dbms_output.put_line(l_key||' = '||l_value);
  end loop;
  close l_cursor;
end;

结果:

3 = 300

3 = 301

【讨论】:

【参考方案2】:

基本的答案是肯定的,你可以根据你的例子,我建议你使用立即执行来执行任意 SQL 字符串并绑定变量。 不过,我会重新考虑您是否真的需要动态设置表格,因为这并不经常需要。

例子:

DECLARE
   sql_stmt    VARCHAR2(200);
   emp_id      NUMBER(4) := 7566;
   emp_rec     emp%ROWTYPE;
BEGIN
   sql_stmt := 'SELECT * FROM emp WHERE empno = :id';
   EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;
END;

【讨论】:

以上是关于如何动态地将表名传递给 PL SQL 游标?的主要内容,如果未能解决你的问题,请参考以下文章

pl/sql 过程不允许将表名/视图名作为参数传递

Oracle函数:如何将表名作为参数传递,并使用游标结果作为表名?

iBatis的SqlMap中,我写的这条动态SQL语句,将表名当做参数动态传递,报“表名无效”错误。

存储过程:将表名转换为表变量

[mysql-connector-python在将表作为参数传递时,在表名周围添加单引号。表名来自Flask会话变量

将表名从外部或变量传递给 INSERT INTO 表名?