英文:
Get count of all table records individually from each schema in a database
问题
在我的Oracle数据库中,假设有3个模式A、B、C。
假设在每个模式中,我都有确切的三个表P、Q、R。
如何获取所有3个模式中表P、Q、R的记录计数,并将其输出到一个单独的表格中?
从这个单独的表格中选择*应该给出数据库中所有模式的所有表格的计数。
模式名称 | P | Q | R |
---|---|---|---|
A | 5 | 6 | 7 |
B | 2 | 5 | 4 |
C | 8 | 6 | 4 |
在我的需求中,有1000多个模式,每个模式都有100多个表,但每个模式中的表数量、表名和表列类型都完全相同。
英文:
In my oracle database, say there are 3 schemas A,B,C.
Say in each schema, i have exact three tables P,Q,R.
how to get the count of P,Q,R table records from all 3 schemas like below output into a seperate table?
Select * from this seperate table should give counts of all tables from all schemas in a database.
Schemaname | P | Q | R |
---|---|---|---|
A. | 5 | 6 | 7 |
B. | 2 | 5 | 4 |
C. | 8 | 6 | 4 |
in my requirement, there are more than 1000 schemas each having more than 100 tables , but the count of tables and table names , table column types exactly are same in each schema
答案1
得分: 1
为了在单次运行中执行此操作,您必须能够访问所有涉及的用户。一种选择是使用特权用户(例如 sys
)并执行类似以下操作:
SQL> show user
USER is "SYS"
SQL> set serveroutput on
在我的数据库中由用户 scott
和 mike
共享的表(如果您确保表集相等,可以简化查询,使用 P、Q 和 R):
SQL> select table_name
2 from dba_tables
3 where owner = 'SCOTT'
4 intersect
5 select table_name
6 from dba_tables
7 where owner = 'MIKE';
TABLE_NAME
--------------------------------------------------------------------------------
SALGRADE
EMP
DEPT
TEST
BONUS
TABLESAMPLE
6 rows selected.
使用动态 SQL 计算每个模式中每个表的行数的PL/SQL过程。我只是显示结果;您可能更希望将结果存储到某个表中以供将来分析:
SQL> declare
2 l_str varchar2(200);
3 l_cnt_1 number;
4 l_cnt_2 number;
5 begin
6 dbms_output.put_Line(rpad('TABLE NAME', 30, ' ') || ' SCOTT ' || ' MIKE ');
7 for cur_r in (select table_name
8 from dba_tables
9 where owner = 'SCOTT'
10 intersect
11 select table_name
12 from dba_tables
13 where owner = 'MIKE'
14 )
15 loop
16 l_str := 'select count(*) from scott.' || cur_r.table_name;
17 execute immediate l_str into l_cnt_1;
18 l_str := 'select count(*) from mike.' || cur_r.table_name;
19 execute immediate l_str into l_cnt_2;
20
21 dbms_output.put_line(rpad(cur_r.table_name, 30, ' ') ||
22 to_char(l_cnt_1, '999G990') ||
23 to_char(l_cnt_2, '999G990'));
24 end loop;
25 end;
26 /
TABLE NAME SCOTT MIKE
SALGRADE 5 5
EMP 14 14
DEPT 4 4
TEST 2 0
BONUS 0 0
TABLESAMPLE 0 2
PL/SQL procedure successfully completed.
或者,如果您定期收集统计信息并且表不经常更新(插入/删除行),您可以检查 dba_tables
视图中的 num_rows
列值:
SQL> select owner, table_name, num_rows
2 from dba_tables
3 where table_name in (select table_name from dba_tables where owner = 'SCOTT'
4 intersect
5 select table_name from dba_tables where owner = 'MIKE')
6 order by table_name, owner;
OWNER TABLE_NAME NUM_ROWS
--------------- ------------------------------ ----------
MIKE BONUS 0
SCOTT BONUS 0
MIKE DEPT 4
SCOTT DEPT 4
MIKE EMP 14
SCOTT EMP 14
MIKE SALGRADE 5
SCOTT SALGRADE 5
MIKE TABLESAMPLE 1
SCOTT TABLESAMPLE 0
MIKE TEST 0
SCOTT TEST 2
12 rows selected.
英文:
In order to do that in a single run, you have to have access to all users being involved. One option is to use a privileged user (such as sys
) and do something like this:
SQL> show user
USER is "SYS"
SQL> set serveroutput on
Tables shared by users scott
and mike
in my database (you'd use P, Q and R, if you're absolutely sure that table set is equal, you can simplify the query):
SQL> select table_name
2 from dba_tables
3 where owner = 'SCOTT'
4 intersect
5 select table_name
6 from dba_tables
7 where owner = 'MIKE';
TABLE_NAME
--------------------------------------------------------------------------------
SALGRADE
EMP
DEPT
TEST
BONUS
TABLESAMPLE
6 rows selected.
PL/SQL procedure which uses dynamic SQL to count rows in each table in each schema. I'm simply displaying the result; you'd probably rather want to store the result into some table for future analysis.
SQL> declare
2 l_str varchar2(200);
3 l_cnt_1 number;
4 l_cnt_2 number;
5 begin
6 dbms_output.put_Line(rpad('TABLE NAME', 30, ' ') || ' SCOTT ' || ' MIKE ');
7 for cur_r in (select table_name
8 from dba_tables
9 where owner = 'SCOTT'
10 intersect
11 select table_name
12 from dba_tables
13 where owner = 'MIKE'
14 )
15 loop
16 l_str := 'select count(*) from scott.' || cur_r.table_name;
17 execute immediate l_str into l_cnt_1;
18 l_str := 'select count(*) from mike.' || cur_r.table_name;
19 execute immediate l_str into l_cnt_2;
20
21 dbms_output.put_line(rpad(cur_r.table_name, 30, ' ') ||
22 to_char(l_cnt_1, '999G990') ||
23 to_char(l_cnt_2, '999G990'));
24 end loop;
25 end;
26 /
TABLE NAME SCOTT MIKE
SALGRADE 5 5
EMP 14 14
DEPT 4 4
TEST 2 0
BONUS 0 0
TABLESAMPLE 0 2
PL/SQL procedure successfully completed.
SQL>
Alternatively, if you regularly gather statistics and tables aren't updated frequently (rows inserted/deleted), you could check num_rows
column value in dba_tables
view:
SQL> select owner, table_name, num_rows
2 from dba_tables
3 where table_name in (select table_name from dba_tables where owner = 'SCOTT'
4 intersect
5 select table_name from dba_tables where owner = 'MIKE')
6 order by table_name, owner;
OWNER TABLE_NAME NUM_ROWS
--------------- ------------------------------ ----------
MIKE BONUS 0
SCOTT BONUS 0
MIKE DEPT 4
SCOTT DEPT 4
MIKE EMP 14
SCOTT EMP 14
MIKE SALGRADE 5
SCOTT SALGRADE 5
MIKE TABLESAMPLE 1
SCOTT TABLESAMPLE 0
MIKE TEST 0
SCOTT TEST 2
12 rows selected.
SQL>
答案2
得分: 1
最简单的方法:
SELECT 'A' as schemaname,
(SELECT count(*) FROM A.P) as P,
(SELECT count(*) FROM A.Q) as Q,
(SELECT count(*) FROM A.R) as R
UNION ALL
SELECT 'B' as schemaname,
(SELECT count(*) FROM B.P) as P,
(SELECT count(*) FROM B.Q) as Q,
(SELECT count(*) FROM B.R) as R
UNION ALL
SELECT 'C' as schemaname,
(SELECT count(*) FROM C.P) as P,
(SELECT count(*) FROM C.Q) as Q,
(SELECT count(*) FROM C.R) as R;
对于更多的模式和超过100个表格,您可能希望以编程方式生成查询。使用Python比SQL或PL/SQL可能更容易。
schemas = ["A", "B", "C"]
tables = ["P", "Q", "R"]
" UNION ALL ".join([f"SELECT '{s}' as schemaname, " + ", ".join([f"(SELECT count(*) FROM {s}.{t}) as {t}" for t in tables]) for s in schemas])
英文:
Most straightforward:
SELECT 'A' as schemaname,
(SELECT count(*) FROM A.P) as P,
(SELECT count(*) FROM A.Q) as Q,
(SELECT count(*) FROM A.R) as R
UNION ALL
SELECT 'B' as schemaname,
(SELECT count(*) FROM B.P) as P,
(SELECT count(*) FROM B.Q) as Q,
(SELECT count(*) FROM B.R) as R
UNION ALL
SELECT 'C' as schemaname,
(SELECT count(*) FROM C.P) as P,
(SELECT count(*) FROM C.Q) as Q,
(SELECT count(*) FROM C.R) as R;
With more schemas and >100 tables you probably want to programmatically generate the query. It's probably easier with something like Python than SQL or PL/SQL.
schemas = ["A", "B", "C"]
tables = ["P", "Q", "R"]
" UNION ALL ".join([f"SELECT '{s}' as schemaname, " + ", ".join([f"(SELECT count(*) FROM {s}.{t}) as {t}" for t in tables]) for s in schemas]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论