0

我有一个存储过程,可以将行选择到 out 游标中,如下所示:

PROCEDURE GetUserTables(
    out_cur    OUT SYS_REFCURSOR
)
AS
BEGIN
    OPEN out_cur FOR
        SELECT u.user_id, u.user_name, ut.table_name
          FROM users u
          JOIN user_tables ut ON ut.user_id = u.user_id
      ORDER BY u.user_name, ut.table_name;
END

中的table_nameuser_tables包含数据库表的名称,我想在输出中包含这些表的计数;所以out_cur会包含这样的东西:

| user_id | user_name | table_name   | row_count |
+---------+-----------+--------------+-----------+
| 1       | Simon     | simons_dogs  | 1         |
| 1       | Simon     | simons_cats  | 0         |
| 2       | Jenny     | jennys_dogs  | 2         |
| 3       | Ellie     | ellies_dogs  | 3         |
| 3       | Ellie     | ellies_cats  | 1         |
| 3       | Ellie     | ellies_birds | 5         |

where simons_dogsetc.. 是实际表的名称。

我的第一个想法是在过程中有一个表变量,并循环插入 user_tables ,然后在我的选择中加入它;但我不知道如何拥有一个多列表变量。

4

1 回答 1

1

您将需要使用动态 SQL,请参阅http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm

您将需要两个查询:

  • 在外部查询中,您需要查询您有兴趣查询的表名。

  • 内部的“count(*)”查询将被构造为一个字符串,嵌入表的名称。虽然通常应该使用绑定变量,但它们不能用于查询的表名(或列名)部分。

这是正常的方法,但似乎不适合您提供的示例代码。在这种情况下,您可以创建一个接受表名的函数,并在函数内部使用动态 SQL 来执行 count(*),如下所示:

function count_rows(p_table_name in varchar2) return integer is
  l_count integer;
begin
  execute immediate 'select count(*) from ' || p_table_name into l_count;
  return l_count;
end;

并像使用

select table_name, count_rows(table_name) as row_count
from user_tables;
于 2013-10-11T14:09:23.303 回答