2

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

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

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

4

2 回答 2

1

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

粘贴

select REGIONS,
COUNTRIES,
LOCATIONS,
DEPARTMENTS,
JOBS,
EMPLOYEES,
JOB_HISTORY,
TM_USER_INFO,
USER_ROLES,
PAYMENT_PRICE_SHOP,
SHOP_USER from dual

进入你的工作表。

打开“代码大纲”面板。键入“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 脚本输出面板的句柄并将结果传输到那里。

于 2020-12-11T19:41:08.140 回答
1

动态 SQL 可以使用返回引用游标(排序)的函数、多态表函数 (18c+) 或 Oracle Data Cartridge(需要自定义 PL/SQL 包和类型)显示在 Oracle SQL Developer 网格中。

返回参考光标的函数

本答案中所述,返回引用光标的函数的输出可以显示在“输出变量”窗口中。答案中的示例使用了静态 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 功能。

多态表函数

从 Oracle 18c 开始,您可以创建一个接受输入并具有可变输出的多态表函数。您必须对如何处理表和列进行编程,但如果您只需要简单的传递逻辑,这并不难。有关从表中返回每一列(不包括特定列)的查询示例,请参见我的答案。就任何程序所知,结果都是“常规”SQL,并且可以在任何网格 GUI 中工作。

Oracle 数据盒

我的开源程序Method4可以在 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
        )
    ]'
));

您可能想要添加一些关于您到底想要做什么以及为什么要执行的详细信息;这可能有助于缩小可能的解决方案。

于 2020-12-12T04:53:40.503 回答