Sql 如何在oracle存储过程的输出中包括命名表的计数?

Sql 如何在oracle存储过程的输出中包括命名表的计数?,sql,oracle,stored-procedures,Sql,Oracle,Stored Procedures,我有一个存储过程,它将行选择到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

我有一个存储过程,它将行选择到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
user\u tables
中的
table\u name
列包含DB表的名称,我希望在输出中包含这些表的计数;因此,
out\u 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         |
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;
其中
simons\u dogs
等。。是实际表的名称


我的第一个想法是在过程中有一个表变量,并循环插入其中的用户表,然后在我的select中加入它;但我无法确定如何使用多列表变量。

您需要使用动态SQL,请参阅

您将需要两个查询:

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

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

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

| 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         |
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;

动态SQL,请参见需要行数近似值还是精确行数?精确行数。我的问题不是我无法获得计数,而是我无法将其放入输出光标。我可以看到一个近似计数(很容易从统计数据中提取),但在运行时,对于没有pk或唯一idx的大型表,精确计数会变得难看。这可能属于“你真的需要这个吗?”类别。如何将内部查询的结果收集到输出游标中?我刚刚更新了答案,建议使用函数来实现这一点。我想,要做到这一点。现在,当我运行我的SP时,我得到了“ORA-00933:SQL命令未正确结束”。啊,这里有一个错误的引用。我会找到答案的。谢谢