【问题标题】:Executing resulting rows for the result of Dynamic Native SQL query为 Dynamic Native SQL 查询的结果执行结果行
【发布时间】:2016-10-12 15:44:44
【问题描述】:

我正在为此而发疯。我对动态 SQL 还很陌生,所以我可能只是没有向 Google 提出正确的问题,但这就是我正在尝试做的事情......我有一个动态 SQL 查询。当我运行该查询时,它会产生几行。所有这些行(大约 30 行)构成一个联合查询。我可以复制所有这些行并粘贴到一个新查询中并运行 - 工作正常,但我需要做的是在一个查询中运行这一切。我已经查找了使用立即执行和获取的示例,但我似乎无法让他们真正吐出数据......他们最终只是说“成功执行”之类的话,但实际上并没有产生任何结果行.下面 SQL 的结果列名是“qry_txt”——我不想按面值生成它,而是想将它作为查询执行。同样,我可能没有很好地表达这一点,但我基本上是在尝试将 2 个查询(涉及手动复制/粘贴步骤)变成一个查询。希望这是有道理的......

这是我的 SQL:

Select CASE when 
lead(ROWNUM) over(order by ROWNUM) is null then
'SELECT '||''''||T.TABLE_NAME||''''||' as TABLE_NAME,'||''''||T.COLUMN_NAME||''''||' as COLUMN_NAME, cast('|| T.COLUMN_NAME ||' as 
varchar2(100)) as SAMPLE_DATA ||
from rpt.'||T.TABLE_NAME ||' where '||T.COLUMN_NAME||' is not null and ROWNUM=1;'  
else
'SELECT '||''''||T.TABLE_NAME||''''||' as TABLE_NAME,'||''''||T.COLUMN_NAME||''''||' as COLUMN_NAME, cast('|| T.COLUMN_NAME ||' as 
varchar2(100)) as SAMPLE_DATA from rpt.'||T.TABLE_NAME ||' where '||T.COLUMN_NAME||' is not null and ROWNUM=1 union ' end as qry_txt
from all_tab_columns t where T.OWNER='rpt' and T.DATA_TYPE != 'BLOB' and T.DATA_TYPE != 'LONG' and T.TABLE_NAME = 'NME_DMN' 
ORDER BY ROWNUM asc;

【问题讨论】:

  • 您的目标是打开一个游标,该游标返回给调用者,然后获取行(这更容易,可以通过execute immediate 完成)。或者您是否需要一个 PL/SQL 块来获取所有行(这更难,而且几乎肯定会涉及使用 dbms_sql 包的更复杂的路由)?
  • 从我一直在阅读的内容来看,打开光标听起来像是正确的轨道。是的,我需要获取所有行,就好像我正在运行直接选择查询一样。只要我以行结束,我对任何一种方法都持开放态度,但就我能够重复该技术而言,最简单的方法是最好的...... ;)
  • 如果你想打开一个返回给调用者的游标,调用者不能是一个获取数据的 PL/SQL 块(好吧,如果你使用的是 12.1 并且你'愿意变得更复杂)。您可以将游标返回到SQL*Plus 或随后可以获取数据的 C# 应用程序。如果您想要一个 PL/SQL 块来获取所有行,您将需要更复杂的 dbms_sql 路径。我不确定其中哪一个真的适合你。
  • 我想说,如果它不是 oracle 中原生 sql 的一个特性(开箱即用),那么它可能对我不起作用。我遇到的所有 dbms_sql 示例对我来说都失败了。那么,也许打开光标不是答案?您是否看到我可以用来实现我想要的任何其他开箱即用的方法?这是我第一次尝试这样的事情,所以也许这甚至是不可能的。从我在 Google 上看到的结果来看,我是这个星球上第一个尝试这样做的人,所以也许这不可行......
  • 这是非常可行的。使用execute immediate,您可以愉快地将游标返回给应用程序,该应用程序知道如何询问游标以确定列的数量和类型等信息,以便获取数据。 SQL*Plus 知道如何做到这一点,实际上,任何客户端 API(JDBC/ODBC/OLE DB/ 等)也是如此。如果你想编写一个获取数据的 PL/SQL 块,那么你需要编写更复杂的dbms_sql 代码。 execute immediatedbms_sql 都存在“开箱即用”。一个比另一个简单得多。

标签: sql oracle dynamic native


【解决方案1】:

您不能在 SQL 中编写动态查询。您需要使用 PLSQL 块来完成它。请看看你是怎么做到的。 PS:代码未经测试。

declare
  var1 <decalration same of column in select list> ;
  var2 <decalration same of column in select list> ;
  var3 <decalration same of column in select list> ;
  ....
  varn   ;

 begin
  for i in ( SELECT LEAD (ROWNUM) OVER (ORDER BY ROWNUM) COl1
              FROM all_tab_columns t
               WHERE     T.OWNER = 'rpt'
                     AND T.DATA_TYPE != 'BLOB'
                     AND T.DATA_TYPE != 'LONG'
                     AND T.TABLE_NAME = 'NME_DMN'
             ORDER BY ROWNUM ASC)

  Loop

     If i.col1 IS NULL Then

     execute immediate   'SELECT '
                           || ''''
                           || T.TABLE_NAME
                           || ''''
                           || ' as TABLE_NAME,'
                           || ''''
                           || T.COLUMN_NAME
                           || ''''
                           || ' as COLUMN_NAME, cast('
                           || T.COLUMN_NAME
                           || ' as 
                              varchar2(100)) as SAMPLE_DATA ||
                            from rpt.'
                           || T.TABLE_NAME
                           || ' where '
                           || T.COLUMN_NAME
                           || ' is not null and ROWNUM=1' into var1 , var2 ,var3 ....varn;

    Else

       execute immediate  'SELECT '
                           || ''''
                           || T.TABLE_NAME
                           || ''''
                           || ' as TABLE_NAME,'
                           || ''''
                           || T.COLUMN_NAME
                           || ''''
                           || ' as COLUMN_NAME, cast('
                           || T.COLUMN_NAME
                           || ' as 
            varchar2(100)) as SAMPLE_DATA from rpt.'
                           || T.TABLE_NAME
                           || ' where '
                           || T.COLUMN_NAME
                           || ' is not null and ROWNUM=1' into var1 , var2 ,var3 ....varn;

    end if;

  End Loop;             

  exception
   when others then
   dbms_output.put_lin(sqlcode ||'--'||sqlerrm);

End;  

【讨论】:

  • 我运行此程序并收到此错误:查找错误 ORA-06550:第 2 行第 8 列:PLS-00103:在预期以下情况之一时遇到符号“
  • 我只是帮你身体。它不是实际的工作代码。我只是以你可以工作的方式帮助你。我的 cmets 也是内联的。只需按照语法并相应地修改您的代码
  • 恐怕我对您的技术或我目前收到的错误了解不够,无法为我工作。还在尝试...
  • 您可以发布您正在尝试的代码。无论是我还是其他人,一定会帮助你。忘记不要在 Oracle 下标记问题并发布您遇到的错误
  • 我修改了你的代码,现在它运行了,但它只是说“执行成功”它实际上并没有返回行。代码在这里:pastebin.com/XJLnb9Zi
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-17
  • 1970-01-01
  • 2015-08-29
  • 2018-12-31
  • 2017-09-10
  • 2019-11-18
  • 2016-05-03
相关资源
最近更新 更多