当表名是参数时Oracle使用动态sql

Posted

技术标签:

【中文标题】当表名是参数时Oracle使用动态sql【英文标题】:Oracle using dynamic sql when table name is a parameter 【发布时间】:2013-12-30 12:45:57 【问题描述】:

我有一个想要转换为 PLSQL 的 SQL 查询(一个存储过程) 我已经转换了大部分存储过程,但我无法转换以下部分:

DECLARE lookupTableRow CURSOR FOR
  SELECT TableName FROM SYS_LookUpTable
  OPEN lookupTableRow
  FETCH NEXT FROM lookupTableRow INTO @tableName
  WHILE @@FETCH_STATUS=0
  BEGIN

  SET @sql='SELECT * FROM '+@tableName
EXECUTE sp_executesql @sql

  IF @counter=0
  BEGIN
  INSERT INTO T_TABLE_MAPPING VALUES('P_MAIN_METADATA', 'Table', @tableName)
  END
  ELSE
  BEGIN
  INSERT INTO T_TABLE_MAPPING 
      VALUES(  'P_MAIN_METADATA', 
               'Table' + CONVERT(NVARCHAR(10),@counter), 
               @tableName)
  END

  SET @counter=@counter+1
  FETCH NEXT FROM lookupTableRow INTO @tableName
  END
  CLOSE lookupTableRow
  DEALLOCATE lookupTableRow

据我了解,当表名是参数时,我不能使用 ORACLE 动态 sql(立即执行)。

此外,当我在我的 SQL 存储过程中执行此动态查询时,每个 SELECT 语句都会返回我作为相关表行的结果,这些结果在每个循环中都是不同的。

请提供任何解决方案的建议 * 我如何使用以表名作为参数的动态 sql? * 如何使用“动态”光标,以便能够显示动态结果?

谢谢你的建议

【问题讨论】:

'Table' + CONVERT(NVARCHAR(10),@counter) 对这段代码做了什么? 看来您正试图混淆实际的表名,并在 T_TableMapping 中为它们分配 Table# 的名称。如果是这样的话,这样的工作吗? Select owner, table_name, 'Table' || to_char(rownum) from all_tables order by owner, table_name 但是在 SQL 上,下面的代码是一个 SELECT 语句。这个 SELECT 在每个循环上都在变化。 SELECT 的表结果被填充到数据集(在 c# 代码中)所以我需要找到一种方法来做到这一点: SET @sql='SELECT * FROM '+@tableName EXECUTE sp_executesql @sql @RefaelCohen I have a SQL query (a store procedure ) SQL 是许多 RDBMS 的行业标准编程语言。您可能指的是作为 MS SQL Server 产品一部分的 Transact-SQL 或 T-SQL 存储过程。请使用适当的术语以避免混淆。 【参考方案1】:

如果您在这里唯一不知道如何做的是动态使用表名,那么这就是您可以完成的方法

  1  declare
  2     n number;
  3     table_name varchar2(30) := 'dual';
  4  begin
  5     execute immediate 'select count(*) from ' || table_name into n;
  6     dbms_output.put_line(n);
  7* end;
SQL> /
1

【讨论】:

我以“旧方式”解决了这个问题我运行了这个选择语句: SELECT TableName FROM SYS_LookUpTable 为了查看所有相关的表名然后我简单地为每个表名创建一个选择语句是的我知道这不是优雅的方式,而且我知道我写了大约 41 条 select 语句以达到与在 sql server 中获得的结果相同的结果但我没有找到其他方法在 ORACLE 中执行此简单查询 我不会说它在 oracle 中很丑陋。也许说出你想要做的事情,我们可以帮助你以“oracle 方式”实现目标【参考方案2】:

如果您只是试图填充一个将表名混淆为其他内容的表,为什么它会按顺序强制数据库更改上下文并放慢速度?

Create table t_table_mapping as 
(    Select 'P_MAIN_METADATA' "P_MAIN_METADATA", 
      'Table' || to_char(rownum) as "Table", table_name 
     from all_tables)

但是,这并没有考虑架构名称,所以所有者是什么。因此,您需要添加一个 where 子句来限制您要为其执行此操作的特定架构。

【讨论】:

以上是关于当表名是参数时Oracle使用动态sql的主要内容,如果未能解决你的问题,请参考以下文章

如何在存储过程中删除一张表,表名是作为参数传入的

当表名包含“'”时为 Sql Server 2008 构建动态查询

使用动态表名称查询 Oracle 数据库

hibernate映射postgreSQL数据库中的表时,表名是大写的时候为啥hibernate不能映射实体

oracle 动态 sql 使用带括号的参数作为表名

PL/SQL Oracle :- 在传递值时动态 UNPIVOT ORACLE TABLE