使用内部数据检索 Oracle 元数据
Retrieve Oracle Metadata with Internal Data
我正在尝试编写一个 PL/SL 过程,它同时使用 table.It 的元数据和内部数据,如下所示:
table1 (ABC varchar2(50),wsx varchar2(50));
table2 (ABC number(50),dv varchar2(50));
table3 (ABC varchar2(10),wsds varchar2(50));
table4 (ABC varchar2(20),wfsdg varchar2(50));
table5 (ABC number(50),wsxsfd varchar2(50));
所有五个 table 都有一个同名的列 'ABC'
。
假设 table1 有 3 行
('JOHN.TEDA','avdv'),('MARK.LEE','fesf'),('JOHN.DEA','fwfd')
等table也有这样的数据
现在使用列名作为输入('ABC') 我应该得到输出
附上。
我们可以从 user_tab_columns
中获取列信息。
最大长度表示列中现有数据的最大长度::
select max(length(ABC)) from table1
我在加入两者时遇到问题
表格不具有参考性。
您无法直接使用 SQL 实现此目的。您需要 PL/SQL + 立即执行才能完成这项工作。
- 使用您预期的列创建 table
- 然后使用
for each
循环计算每列的最大长度。
我已尝试使用 Oracle 中的 PIPELINED 函数复制您提到的场景。希望这有帮助。
CREATE OR REPLACE TYPE fun_obj
IS
OBJECT
(
tab_name VARCHAR2(100),
colname VARCHAR2(100),
datatyp VARCHAR2(100),
datlen NUMBER,
nullable VARCHAR2(1),
LEN NUMBER );
/
CREATE OR REPLACE
FUNCTION test_max_count(
colname IN VARCHAR2)
RETURN fun_tab PIPELINED
AS
tab fun_obj:=fun_obj(NULL,NULL,NULL,NULL,NULL,NULL);
lvlen NUMBER;
BEGIN
FOR I IN
(SELECT DISTINCT table_name,
OWNER,
COLUMN_NAME,
DATA_TYPE,
DATA_LENGTH,
NULLABLE,
NULL AS MAX_LEN
FROM all_tab_columns
WHERE column_name = colname
)
LOOP
tab.tab_name:=i.table_name;
tab.colname :=i.COLUMN_NAME;
tab.datatyp :=i.DATA_TYPE;
tab.datlen :=i.DATA_LENGTH;
tab.nullable:=i.NULLABLE;
EXECUTE IMMEDIATE 'SELECT MAX(LENGTH('||i.column_name||')) FROM '||I.OWNER||'.'||I.TABLE_NAME INTO lvlen;
tab.len:=lvlen;
PIPE ROW(tab);
END LOOP;
END;
/
------------------------------------To Execute----------------------------------
SELECT * FROM TABLE(test_max_count('abc'));
CREATE OR REPLACE PROCEDURE test2 ( p_column_name IN varchar )
IS
CURSOR GET_DATA (COL VARCHAR )IS
SELECT TABLE_NAME ,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,NULLABLE
FROM
user_tab_columns where COLUMN_NAME = COL;
a_table varchar2(50);
B_COL varchar2(50);
a_max varchar2(50);
BEGIN
FOR C IN GET_DATA(p_column_name) LOOP
a_table := c.table_name;
B_COL := C.COLUMN_NAME;
EXECUTE IMMEDIATE 'SELECT MAX(LENGTH('||B_COL||')) FROM '||a_table into a_max ;
insert into received_Data values (c.table_name,C.COLUMN_NAME,C.DATA_TYPE,C.DATA_LENGTH,C.NULLABLE,a_max);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR (-20001,
p_column_name || ':$:' || SQLERRM, TRUE) ;
END test2;
/
CREATE TABLE RECEIVED_DATA
( TABLE_NAME VARCHAR2(50 BYTE),
COLUMN_NAME VARCHAR2(50 BYTE),
DATA_TYPE VARCHAR2(50 BYTE),
DATA_LENGTH VARCHAR2(50 BYTE),
IS_NULL VARCHAR2(50 BYTE),
MAX_LENGTH VARCHAR2(50 BYTE));
我正在尝试编写一个 PL/SL 过程,它同时使用 table.It 的元数据和内部数据,如下所示:
table1 (ABC varchar2(50),wsx varchar2(50));
table2 (ABC number(50),dv varchar2(50));
table3 (ABC varchar2(10),wsds varchar2(50));
table4 (ABC varchar2(20),wfsdg varchar2(50));
table5 (ABC number(50),wsxsfd varchar2(50));
所有五个 table 都有一个同名的列 'ABC'
。
假设 table1 有 3 行
('JOHN.TEDA','avdv'),('MARK.LEE','fesf'),('JOHN.DEA','fwfd')
等table也有这样的数据
现在使用列名作为输入('ABC') 我应该得到输出 附上。
我们可以从 user_tab_columns
中获取列信息。
最大长度表示列中现有数据的最大长度::
select max(length(ABC)) from table1
我在加入两者时遇到问题
您无法直接使用 SQL 实现此目的。您需要 PL/SQL + 立即执行才能完成这项工作。
- 使用您预期的列创建 table
- 然后使用
for each
循环计算每列的最大长度。
我已尝试使用 Oracle 中的 PIPELINED 函数复制您提到的场景。希望这有帮助。
CREATE OR REPLACE TYPE fun_obj
IS
OBJECT
(
tab_name VARCHAR2(100),
colname VARCHAR2(100),
datatyp VARCHAR2(100),
datlen NUMBER,
nullable VARCHAR2(1),
LEN NUMBER );
/
CREATE OR REPLACE
FUNCTION test_max_count(
colname IN VARCHAR2)
RETURN fun_tab PIPELINED
AS
tab fun_obj:=fun_obj(NULL,NULL,NULL,NULL,NULL,NULL);
lvlen NUMBER;
BEGIN
FOR I IN
(SELECT DISTINCT table_name,
OWNER,
COLUMN_NAME,
DATA_TYPE,
DATA_LENGTH,
NULLABLE,
NULL AS MAX_LEN
FROM all_tab_columns
WHERE column_name = colname
)
LOOP
tab.tab_name:=i.table_name;
tab.colname :=i.COLUMN_NAME;
tab.datatyp :=i.DATA_TYPE;
tab.datlen :=i.DATA_LENGTH;
tab.nullable:=i.NULLABLE;
EXECUTE IMMEDIATE 'SELECT MAX(LENGTH('||i.column_name||')) FROM '||I.OWNER||'.'||I.TABLE_NAME INTO lvlen;
tab.len:=lvlen;
PIPE ROW(tab);
END LOOP;
END;
/
------------------------------------To Execute----------------------------------
SELECT * FROM TABLE(test_max_count('abc'));
CREATE OR REPLACE PROCEDURE test2 ( p_column_name IN varchar )
IS
CURSOR GET_DATA (COL VARCHAR )IS
SELECT TABLE_NAME ,COLUMN_NAME,DATA_TYPE,DATA_LENGTH,NULLABLE
FROM
user_tab_columns where COLUMN_NAME = COL;
a_table varchar2(50);
B_COL varchar2(50);
a_max varchar2(50);
BEGIN
FOR C IN GET_DATA(p_column_name) LOOP
a_table := c.table_name;
B_COL := C.COLUMN_NAME;
EXECUTE IMMEDIATE 'SELECT MAX(LENGTH('||B_COL||')) FROM '||a_table into a_max ;
insert into received_Data values (c.table_name,C.COLUMN_NAME,C.DATA_TYPE,C.DATA_LENGTH,C.NULLABLE,a_max);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR (-20001,
p_column_name || ':$:' || SQLERRM, TRUE) ;
END test2;
/
CREATE TABLE RECEIVED_DATA
( TABLE_NAME VARCHAR2(50 BYTE),
COLUMN_NAME VARCHAR2(50 BYTE),
DATA_TYPE VARCHAR2(50 BYTE),
DATA_LENGTH VARCHAR2(50 BYTE),
IS_NULL VARCHAR2(50 BYTE),
MAX_LENGTH VARCHAR2(50 BYTE));