我可以在SQL开发者的网格中显示动态SQL select语句的结果吗?
在Oracle的SQL Developer中,我可以在脚本输出窗格中执行动态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
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
)
]'
));