2012-01-10 23 views
6

Giả sử bạn có một gói PL/SQL với một loại RECORD định nghĩa:Metadata về PL/SQL loại hồ sơ gói cấp

CREATE OR REPLACE PACKAGE TEST_PACKAGE AS 

    TYPE PERSON_RECORD_TYPE IS RECORD 
    (
     first_name VARCHAR2(1000), 
     last_name VARCHAR2(1000) 
    ); 

END; 

Có cách nào để có được một danh sách các lĩnh vực chứa trong TEST_PACKAGE.PERSON_RECORD_TYPE? Ví dụ: có bất kỳ chế độ xem ALL_* nào với thông tin này không?

Tôi không quan tâm đến lược đồ loại bản ghi ngoại lệ, chỉ gói loại bản ghi ngoại lệ.

+0

được các lĩnh vực từ bên trong cùng một gói? – tbone

+0

@tbone: Không nhất thiết. Tôi muốn lấy các trường từ một gói khác. –

+1

"lấy chúng" nghĩa là sử dụng chúng như thế nào? Bạn có thể đưa ra một số mã giả của những gì bạn đang cố gắng thực hiện trong gói khác này không? – tbone

Trả lời

1

Dưới đây là một số câu hỏi tương tự về việc truy xuất thông tin từ mã gói.

Find package global variables from data dictionary

Get Package Methods and Parameters from Oracle

Tôi coi đây là một vấn đề tương tự như cái đầu tiên. Bạn không thể truy cập các trường đó thông qua chế độ xem. Có giải pháp văn bản nguồn phân tích cú pháp, điều này rất xấu hoặc bạn có thể cần giải pháp cho vấn đề này.

Dù sao, tôi nghĩ rằng đó là điều gì đó sai trong kiến ​​trúc của bạn nếu bạn cần điều này.

+0

sẽ không tốt hơn như một bình luận hơn là một câu trả lời? – Ollie

+0

@Ollie Tôi đã chỉnh sửa lại câu trả lời để có một chút hữu ích ... –

2

Nếu PERSON_RECORD_TYPE được sử dụng làm đối số hoặc loại kết quả của một số thủ tục hoặc hàm, bạn có thể truy vấn ALL_ARGUMENTS. Thông tin được mã hóa một chút ở đó (hệ thống phân cấp bao gói đa cấp các bản ghi và các bộ sưu tập được mã hóa trong các cột POSITION, SEQUENCE và DATA_LEVEL), tuy nhiên nó có mặt.

Tôi không nghĩ một câu hỏi như vậy chỉ đến kiến ​​trúc sai. Để tạo mã PLSQL tự động, đây là yêu cầu hoàn toàn hợp pháp, không may với sự hỗ trợ ngôn ngữ PLSQL rất yếu.

0

jOOQ's code generator nội bộ sử dụng các truy vấn sau đây để chắc chắn tất cả mức gói PL/SQL RECORD loại:

SELECT 
    "x"."TYPE_OWNER", 
    "x"."TYPE_NAME", 
    "x"."TYPE_SUBNAME","a".subprogram_id, 
    "a"."ARGUMENT_NAME" "ATTR_NAME", 
    "a"."SEQUENCE" "ATTR_NO", 
    "a"."TYPE_OWNER" "ATTR_TYPE_OWNER", 
    nvl2("a"."TYPE_SUBNAME", "a"."TYPE_NAME", NULL) "package_name", 
    COALESCE("a"."TYPE_SUBNAME", "a"."TYPE_NAME", "a"."DATA_TYPE") "ATTR_TYPE_NAME", 
    "a"."DATA_LENGTH" "LENGTH", 
    "a"."DATA_PRECISION" "PRECISION", 
    "a"."DATA_SCALE" "SCALE" 
FROM "SYS"."ALL_ARGUMENTS" "a" 
JOIN (
    SELECT 
    "a"."TYPE_OWNER", 
    "a"."TYPE_NAME", 
    "a"."TYPE_SUBNAME", 
    MIN("a"."OWNER") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "OWNER", 
    MIN("a"."PACKAGE_NAME") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "PACKAGE_NAME", 
    MIN("a"."SUBPROGRAM_ID") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "SUBPROGRAM_ID", 
    MIN("a"."SEQUENCE") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "SEQUENCE", 
    MIN("next_sibling") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "next_sibling", 
    MIN("a"."DATA_LEVEL") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "DATA_LEVEL" 
    FROM (
    SELECT 
     lead("a"."SEQUENCE", 1, 99999999) OVER (
     PARTITION BY "a"."OWNER", "a"."PACKAGE_NAME", 
        "a"."SUBPROGRAM_ID", "a"."DATA_LEVEL" 
     ORDER BY "a"."SEQUENCE" ASC 
    ) "next_sibling", 
     "a"."TYPE_OWNER", 
     "a"."TYPE_NAME", 
     "a"."TYPE_SUBNAME", 
     "a"."OWNER", 
     "a"."PACKAGE_NAME", 
     "a"."SUBPROGRAM_ID", 
     "a"."SEQUENCE", 
     "a"."DATA_LEVEL", 
     "a"."DATA_TYPE" 
    FROM "SYS"."ALL_ARGUMENTS" "a" 
    WHERE "a"."OWNER" IN ('TEST')  -- Possibly replace schema here 
    ) "a" 
    WHERE ("a"."TYPE_OWNER" IN ('TEST') -- Possibly replace schema here 
    AND "a"."OWNER"   IN ('TEST') -- Possibly replace schema here 
    AND "a"."DATA_TYPE"  = 'PL/SQL RECORD') 
    GROUP BY 
    "a"."TYPE_OWNER", 
    "a"."TYPE_NAME", 
    "a"."TYPE_SUBNAME" 
) "x" 
ON (("a"."OWNER", "a"."PACKAGE_NAME", "a"."SUBPROGRAM_ID") 
= (("x"."OWNER", "x"."PACKAGE_NAME", "x"."SUBPROGRAM_ID")) 
AND "a"."SEQUENCE" BETWEEN "x"."SEQUENCE" AND "next_sibling" 
AND "a"."DATA_LEVEL" = ("x"."DATA_LEVEL" + 1)) 
ORDER BY 
    "x"."TYPE_OWNER" ASC, 
    "x"."TYPE_NAME" ASC, 
    "x"."TYPE_SUBNAME" ASC, 
    "a"."SEQUENCE" ASC 

Trong trường hợp của bạn, kết quả sẽ là một cái gì đó như:

TYPE_NAME  TYPE_SUBNAME  ATTR_NAME ATTR_TYPE_NAME LENGTH 
---------------------------------------------------------------------- 
TEST_PACKAGE PERSON_RECORD_TYPE FIRST_NAME VARCHAR2   1000 
TEST_PACKAGE PERSON_RECORD_TYPE LAST_NAME VARCHAR2   1000 

hạn chế hiện tại:

  • Truy vấn sẽ chỉ tìm thấy những loại đang được tái bị lên men bởi ít nhất một loại và/hoặc thủ tục khác ở đâu đó. Đây là giới hạn được kế thừa từ chế độ xem từ điển ALL_ARGUMENTS trong truy vấn.
  • %ROWTYPE loại không được trả về chính xác vì loại hàng không được tham chiếu từ các cột TYPE_NAME/TYPE_SUBNAME.

biết thêm thông tin ở đây: https://blog.jooq.org/2016/11/08/use-jooq-to-read-write-oracle-plsql-record-types

Các vấn đề liên quan