как параметризовать имя столбца и имя таблицы внутри тела пакета oracle - PullRequest
0 голосов
/ 30 января 2020

- КОД ПАКЕТА - подзапрос с минимальной функцией агрегата не работает. он не может найти таблицу. мне не очень понятно, как сделать паретеризацию имени столбца и таблицы, чтобы оно работало.

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

1 Ответ

0 голосов
/ 31 января 2020

Вы сказали, что это не работает:

(SELECT MIN(p_DATE_COLUMN)FROM p_TABLE_NAME)

Верно - вам понадобятся динамические c 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...