我可以在SQL开发者的网格中显示动态SQL select语句的结果吗?

我可以在SQL开发者的网格中显示动态SQL select语句的结果吗?,sql,oracle-sqldeveloper,Sql,Oracle Sqldeveloper,在Oracle的SQL Developer中,我可以在脚本输出窗格中执行动态SQL select语句,如下所示: script var tabName = 'all_users'; sqlcl.setStmt('select * from ' + tabName); sqlcl.run(); / 现在,我想知道是否可以执行动态select语句,以便其结果显示在结果网格中。SqlDev是用Java实现的,其中包括Nashorn脚本引擎。因此,基本上可以在Nashorn脚本中执行JDB

在Oracle的SQL Developer中,我可以在脚本输出窗格中执行动态SQL select语句,如下所示:

script
  var tabName = 'all_users';
  sqlcl.setStmt('select * from ' + tabName);
  sqlcl.run();
/

现在,我想知道是否可以执行动态select语句,以便其结果显示在结果网格中。

SqlDev是用Java实现的,其中包括Nashorn脚本引擎。因此,基本上可以在Nashorn脚本中执行JDBC。这里有一种方法

粘贴

进入工作表

打开代码大纲面板。键入arbori,或打开以下querySQL.arbori文件:

include "std.arbori"

prelude: runOnce -> {
    var ConnectionResolver = Java.type('oracle.dbtools.db.ConnectionResolver');  
    var connectionList = ConnectionResolver.getConnectionNames();
    var conn = ConnectionResolver.getConnection('IdeConnections%23local_hr');
}

queries: [node) column -> {
    var node = tuple.get('node');
    var table = target.input.substring(
            target.src[node.from].begin,
            target.src[node.to-1].end
        );    
    var query = 'select * from ' + table;
    var ps = conn.createStatement();
    var rs = ps.executeQuery(query);
    while( rs.next() )
        print(rs.getString(1));

}
它将每个表的第一列输出到标准java输出


,因此需要一些反向工程来获得SqlDev脚本输出面板的句柄并将结果传递到该面板。

动态SQL可以使用返回ref游标排序的函数、多态表函数18c+或Oracle数据盒带在Oracle SQL开发人员网格中显示,这些函数需要自定义PL/SQL包和类型

返回Ref游标的函数 如中所述,返回ref光标的函数的输出可以显示在“输出变量”窗口中。答案中的示例使用了静态SQL,但很容易使其成为动态的:

create or replace function refcursor_function return sys_refcursor as
  c sys_refcursor;
begin
  open c for 'select * from all_objects';
  return c;
end;
/
缺点是获取结果比普通查询需要更多的点击次数,而且输出变量网格的功能不如常规结果网格强大。如果您只需要一个窗口来查看、复制和粘贴,那么输出变量就足够了。但它不允许任何高级GUI功能

多态表函数 自Oracle18c以来,您可以创建一个多态表函数,该函数接受输入并具有变量输出。您必须对如何处理表和列进行编程,但如果您只需要简单的传递逻辑,就没有那么困难了。请参阅我的答案,以获取一个查询示例,该查询返回表中不包括特定列的每一列。据任何程序所知,结果都是常规SQL,并且可以在任何网格GUI中工作

Oracle数据盒带 我的开源程序可以在SQL中运行动态SQL。下载并安装包和类型后,可以编写一条SQL语句来生成另一条SQL语句。如果需要使用PL/SQL生成查询,则可能需要使用PL/SQL WITH函数。与多态表函数一样,结果看起来像普通SQL,可以在任何网格中工作

select * from table(method4.dynamic_query(
    q'[
        --Query that builds another query.
        select replace(
            q'!
                select * from #TABLE_NAME#
            !', '#TABLE_NAME#', table_name) sql_statement
        from
        (
            --Enter your script here that returns a table name to select from.
            select 'ALL_USERS' table_name
            from dual
        )
    ]'
));

你可能想添加一些关于你到底想做什么以及为什么要做的细节;这可能有助于缩小可能的解决方案。

我认为您可以将动态sql封装在流水线表函数中,并使用表运算符围绕它创建一个视图。这假设动态sql语句总是返回相同的数字,列的名称和数据类型。返回ref游标的函数需要再点击几下鼠标,这就是我问这个问题的原因。我已经能够在shell、dbms_输出、甚至Excel等地方打印动态SQL文本,然后将其复制/粘贴到SQL编辑器中。所以这里没有真正的好处。其他方法乍一看非常好,但Oracle在函数的第一次调用时解析动态SQL文本一次,然后不识别SQL文本是否在子序列调用时发生了更改。因此,这些也不太适合我的目的。别误会我的意思,我非常感谢你花时间回答我的问题。@RenéNyffenegger我不确定PTF解决方案,但我只是修改了Method4,以强制在每次执行时进行硬解析。这个程序以前就有这个功能,但在所有四个功能中并没有始终如一地使用它。SQL语句的清除看起来确实很有希望。但是给我一些时间来评估一下,我可能在下周不会再讨论这个问题了。你的工作给我留下了深刻的印象,到目前为止,这似乎是在sql developer中显示动态sql语句结果的唯一方法。不幸的是,执行dbms_shared_pool.purge是您的解决方案的核心,它需要非标准权限,而不是在我工作的所有环境中授予这些权限。虽然我非常喜欢您的解决方案,但我认为它是SQL developer几乎提供并可以提供的功能的一种变通方法。总之,我等待一个真正的SQL开发人员解决方案,所以我还没有接受您的宝贵贡献作为我问题的答案。
select * from table(method4.dynamic_query(
    q'[
        --Query that builds another query.
        select replace(
            q'!
                select * from #TABLE_NAME#
            !', '#TABLE_NAME#', table_name) sql_statement
        from
        (
            --Enter your script here that returns a table name to select from.
            select 'ALL_USERS' table_name
            from dual
        )
    ]'
));