带有 min 聚合函数的子查询不起作用。它找不到该表。我不太清楚如何参数化列和表名称以使其工作。
CREATE OR REPLACE PACKAGE TEST_PKG IS
PROCEDURE SP_METRICS
(
p_ENVIRONMENT IN VARCHAR2,
p_DATABASE IN VARCHAR2,
p_SCHEMA IN VARCHAR2,
p_TABLE_NAME IN VARCHAR2,
p_DATE_COLUMN IN VARCHAR2,
o_TABLE_BASELINE OUT SYS_REFCURSOR
);
END TEST_PKG;
程序代码:
CREATE OR REPLACE PACKAGE BODY TEST_PKG AS
PROCEDURE SP_METRICS
(
p_ENVIRONMENT IN VARCHAR2,
p_DATABASE IN VARCHAR2,
p_SCHEMA IN VARCHAR2,
p_TABLE_NAME IN VARCHAR2,
p_DATE_COLUMN IN VARCHAR2,
o_TABLE_BASELINE OUT SYS_REFCURSOR
) AS
BEGIN
OPEN o_TABLE_BASELINE FOR
SELECT
t.num_rows BASELINE_ROW_COUNT,
NVL(max(
(
SELECT
round( (nvl(SUM(e.bytes),0) / 1048576),2)
FROM
dba_extents e
WHERE
e.segment_type LIKE '%TABLE%'
AND e.owner = t.owner
AND e.segment_name = t.table_name
GROUP BY
e.owner,e.segment_name
)
),0) BASELINE_TABLE_SIZE,
NVL( SUM( (
SELECT
round( (nvl(SUM(extd.bytes),0) / 1048576),2)
FROM
dba_extents extd
WHERE
extd.segment_type like ('%INDEX%')
AND indx.owner = extd.owner
AND indx.index_name = extd.segment_name
AND indx.tablespace_name = extd.tablespace_name
GROUP BY
extd.owner,extd.segment_name
) ),0) BASELINE_INDEX_SIZE,
(SELECT MIN(p_DATE_COLUMN)FROM p_TABLE_NAME)--THIS DOES NOT WORK- SAY UNDEFINED TABLE
FROM
all_indexes indx RIGHT JOIN
dba_all_tables t ON indx.table_owner = t.owner AND indx.table_name = t.table_name
WHERE t.owner = p_SCHEMA
AND t.table_name = p_TABLE_NAME
GROUP BY
SYSDATE,
'EDW',
t.owner,
t.table_name,
t.num_rows;
END SP_METRICS;
END TEST_PKG;
这就是我传递值的方式:
var c refcursor;
execute USER.TEST_PKG.SP_METRICS('DEV', 'EDW', 'DW', 'SAIL_DIM','SAIL_DATE' :c);
print c;
你说这行不通:
(SELECT MIN(p_DATE_COLUMN)FROM p_TABLE_NAME)
正确 - 您将需要动态 SQL。关于代码复杂性,我建议您动态执行此查询并在过程中使用结果。简化版:
SQL> create or replace procedure p_test (p_table_name in varchar2,
2 p_date_column in varchar2)
3 is
4 l_min_date date;
5 begin
6 execute immediate 'select min(' || p_date_column || ') from ' ||
7 dbms_assert.sql_object_name(p_table_name) into l_min_date;
8
9 dbms_output.put_line(l_min_date);
10 end;
11 /
Procedure created.
SQL> set serveroutput on
SQL>
SQL> exec p_test('emp', 'hiredate');
17.12.80
PL/SQL procedure successfully completed.
SQL>
您可以对代码执行相同的操作(
l_min_date
用于第31行):
SQL> CREATE OR REPLACE PROCEDURE sp_metrics(
2 p_environment IN VARCHAR2,
3 p_database IN VARCHAR2,
4 p_schema IN VARCHAR2,
5 p_table_name IN VARCHAR2,
6 p_date_column IN VARCHAR2,
7 o_table_baseline OUT SYS_REFCURSOR
8 )
9 AS
10 l_min_date date;
11 BEGIN
12 execute immediate 'select min(' || p_date_column || ') from ' ||
13 dbms_assert.sql_object_name(p_table_name) into l_min_date;
14
15 OPEN o_table_baseline FOR SELECT t.num_rows baseline_row_count,
16 nvl(MAX((SELECT round((nvl(SUM(e.bytes),0)/ 1048576),2)
17 FROM dba_extents e
18 WHERE e.segment_type LIKE '%TABLE%'
19 AND e.owner = t.owner
20 AND e.segment_name = t.table_name
21 GROUP BY e.owner,e.segment_name
22 )),0)baseline_table_size,
23 nvl(SUM((SELECT round((nvl(SUM(extd.bytes),0)/ 1048576),2)
24 FROM dba_extents extd
25 WHERE extd.segment_type LIKE('%INDEX%')
26 AND indx.owner = extd.owner
27 AND indx.index_name = extd.segment_name
28 AND indx.tablespace_name = extd.tablespace_name
29 GROUP BY extd.owner,extd.segment_name
30 )),0)baseline_index_size,
31 l_min_date
32 FROM all_indexes indx
33 RIGHT JOIN dba_all_tables t ON indx.table_owner = t.owner
34 AND indx.table_name = t.table_name
35 WHERE t.owner = p_schema
36 AND t.table_name = p_table_name
37 GROUP BY SYSDATE,
38 'EDW',
39 t.owner,
40 t.table_name,
41 t.num_rows;
42
43 END sp_metrics;
44 /
Procedure created.
SQL>