【问题标题】:Create procedure where table owner, name and row is passed as parameter创建表所有者、名称和行作为参数传递的过程
【发布时间】:2022-01-05 06:43:25
【问题描述】:

我正在尝试在 Oracle PL/SQL 中创建一个过程,我将表所有者的名称、表名和列名传递给过程,以便我可以将其打印到屏幕上。

程序的基础是:

CREATE PROCEDURE table_printer(owner VARCHAR, table_name VARCHAR, column_name VARCHAR)
IS
...

我的基本想法是将其传递给过程中的 CURSOR,但我了解到您无法真正做到这一点,而且我似乎无法找到它的动态方式。

我的最佳结果是遍历给定参数的光标并打印出每一行。

感谢您的帮助!

【问题讨论】:

  • 当您说“将其打印到屏幕上”时,您指的是 UI 还是控制台?通常,一个过程只能向调用者提供一个结果(可能是 JSON 结果?),以便 UI 可以显示它。
  • 简单的dbms_output.put_line();

标签: sql oracle plsql


【解决方案1】:

我会想到一个返回的函数,例如ref 游标,实际上可以在其他地方使用。使用dbms_output.put_line,您只能将它与支持它的工具一起使用(例如 SQL*Plus 或 SQL Developer);在其他工具(例如 Oracle Apex 或 Forms)中,您不会看到 任何东西

这是一个示例:动态 SQL。 dbms_assert用于防止SQL注入。

SQL> create or replace function f_test
  2    (par_owner in varchar2, par_table_name in varchar2, par_column_name in varchar2)
  3    return sys_refcursor
  4  is
  5    l_str varchar2(200);
  6    rc    sys_refcursor;
  7  begin
  8    l_str := 'select ' || dbms_assert.simple_sql_name (par_column_name) ||
  9             ' from '  || dbms_assert.schema_name     (par_owner)       ||'.'||
 10                          dbms_assert.sql_object_name (par_table_name);
 11    open rc for l_str;
 12    return rc;
 13  end;
 14  /

Function created.

SQL> select f_test('SCOTT', 'DEPT', 'DNAME') result from dual;

RESULT
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

DNAME
--------------
ACCOUNTING
RESEARCH
SALES
OPERATIONS


SQL>

[编辑:如果必须是dbms_output.put_line,那么...]

SQL> set serveroutput on
SQL>
SQL> create or replace procedure p_test
  2    (par_owner in varchar2, par_table_name in varchar2, par_column_name in varchar2)
  3  is
  4    l_str   varchar2(200);
  5    rc      sys_refcursor;
  6    --
  7    l_dname dept.dname%type;
  8  begin
  9    l_str := 'select ' || dbms_assert.simple_sql_name (par_column_name) ||
 10             ' from '  || dbms_assert.schema_name     (par_owner)       ||'.'||
 11                          dbms_assert.sql_object_name (par_table_name);
 12    open rc for l_str;
 13    loop
 14      fetch rc into l_dname;
 15      exit when rc%notfound;
 16      dbms_output.put_line(l_dname);
 17    end loop;
 18  end;
 19  /

Procedure created.

SQL> exec p_test('SCOTT', 'DEPT', 'DNAME');
ACCOUNTING
RESEARCH
SALES
OPERATIONS

PL/SQL procedure successfully completed.

SQL>

【讨论】:

  • 这个答案真的很好,但我真的需要把所有东西都放在一个程序中。这就是我的“任务”。
  • 基本上我现在正在寻找的整个想法是,如何在我想要迭代的同一过程中迭代我刚刚明确创建的游标(使用 open for 语句)。
  • 如果你坚持... OK;看看编辑后的答案。
  • 嘿!非常感谢您的回答。我会把它标记为已解决,因为基本上你回答了我的问题。在整个主题中,我只剩下一个大问号。因此,当您创建该过程时,您必须创建一个类型,在该类型中您准确指明了稍后要使用的表和列。如果我对表、所有者和列名一无所知,那么在这种情况下,类型应该如下所示:l_dname p_owner.p_table.p_column%type;
  • 我建议的第一个选项使用(弱)引用游标,它不关心列名或其数据类型。正如你所说你不想要那个选项,我继续进行程序。 Ref cursor 仍然可以(就像以前一样),但是 - 为了显示它从表中获取的值,您必须将这些值 放入某物 - 一个本地声明的变量,并且它必须有一些数据类型。如果您将其声明为例如l_dname varchar2(255);,您很可能能够将许多值放入其中(因为 Oracle 会执行隐式转换)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2023-03-20
相关资源
最近更新 更多