यदि आप प्रति कॉलम एक परिणाम-सेट पंक्ति के साथ ठीक हैं तो आप अनुकूलित कर सकते हैं यह XML मैजिक ट्रिक :
select owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as c
from all_tab_columns
where owner = '<your table owner>'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2');
... उन सभी डेटा प्रकारों को सूचीबद्ध करना जिनकी आपको गणना करने में सक्षम होने की आवश्यकता है; वास्तव में बहिष्कृत . करना है वे जो distinct
को संभाल नहीं सकते CLOB की तरह, लेकिन जैसा कि आपके पास नेस्टेड टेबल आदि हो सकते हैं, संभवतः उन लोगों को सूचीबद्ध करना आसान होगा जिन्हें आप करते हैं चाहते हैं और गिनने में सक्षम होने की उम्मीद करते हैं।
dbms_xmlgen()
कॉल उस select count(distinct ...) ...
क्वेरी, जो प्रभावी रूप से गतिशील रूप से एक XML संरचना में निर्मित होती है, और फिर आप XMLQuery()
के साथ उसमें से गिनती निकाल सकते हैं (बहिष्कृत extractvalue()
. के बजाय लिंक किए गए उत्तर में)।
एक बहुत ही त्वरित डेमो के रूप में:
create table t42 (id number, str varchar2(20));
insert into t42 values (1, 'Test');
insert into t42 values (2, 'Test');
insert into t42 values (3, 'Test 2');
insert into t42 values (3, null);
select owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as c
from all_tab_columns
where owner = 'MY_SCHEMA'
and table_name = 'T42'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2', 'NCHAR', 'NVARCHAR2');
OWNER TABLE_NAME COLUMN_NAME C
--------------- --------------- --------------- ----------
MY_SCHEMA T42 ID 3
MY_SCHEMA T42 STR 2
count()
फ़ंक्शन नल को अनदेखा करता है, इसलिए उन्हें गिनने के लिए आपको उन्हें परिवर्तित करना होगा, उदा। के साथ
count(case when <your_column> is null then 1 end)
आप इसे यहां या तो दूसरे XMLQuery खंड के साथ शामिल करते हैं:
select owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as distinct_count,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(case when "' || column_name || '" is null then 1 end) as c '
|| 'from "' || owner || '"."' || table_name || '"'))
returning content)) as null_count
from all_tab_columns
where owner = 'MY_SCHEMA'
and table_name = 'T42'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2',
'NCHAR', 'NVARCHAR2');
OWNER TABLE_NAME COLUMN_NAME DISTINCT_COUNT NULL_COUNT
--------------- --------------- --------------- -------------- ----------
MY_SCHEMA T42 ID 3 0
MY_SCHEMA T42 STR 2 1
या एक एकल XMLTable के साथ जो जेनरेट किए गए XML से दोनों कॉलम मान निकालता है, जिसे एक साथ दोनों गणना करने के लिए संशोधित किया गया है:
select a.owner, a.table_name, a.column_name,
x.distinct_count, x.null_count
from
(
select owner, table_name, column_name,
dbms_xmlgen.getxml(
'select count(distinct "' || column_name || '") as c1,'
|| 'count(case when "' || column_name || '" is null then 1 end) as c2 '
|| 'from "' || owner || '"."' || table_name || '"') as xml_clob
from all_tab_columns
where owner = 'MY_SCHEMA'
and table_name = 'T42'
and data_type in ('NUMBER', 'DATE', 'TIMESTAMP', 'CHAR', 'VARCHAR2',
'NCHAR', 'NVARCHAR2')
) a
cross join xmltable (
'/ROWSET/ROW'
passing xmltype(a.xml_clob)
columns distinct_count number path 'C1',
null_count number path 'C2'
) x;
OWNER TABLE_NAME COLUMN_NAME DISTINCT_COUNT NULL_COUNT
--------------- --------------- --------------- -------------- ----------
MY_SCHEMA T42 ID 3 0
MY_SCHEMA T42 STR 2 1