2015-02-24 17 views
8

Tôi đang sử dụng Oracle 10.2.Tại sao tôi nhận được PLS-00302: thành phần phải được khai báo khi nó tồn tại?

Tôi đang làm việc trong một số tập lệnh để di chuyển một số đối tượng ORACLE từ một SCHEMA (S1) sang một SCHEMA (S1) khác (S2). Tôi đang tạo các chức năng với vai trò DBA. Khi di chuyển, một trong các chức năng của tôi trở nên không hợp lệ, nhưng tôi không hiểu tại sao. mã của nó đi dọc theo những dòng:

MY_FUNC

CREATE OR REPLACE FUNCTION S2."MY_FUNC" RETURN VARCHAR2 IS 
    something VARCHAR2; 
    othervar VARCHAR2 (50):= 'TEST'; 
BEGIN 
    something := S2.MY_FUNC2(); 
    /*some code*/ 
    return othervar; 
END; 
/

Nếu tôi sử dụng MY_FUNC2 mà không có lược đồ, Nó hoạt động:
something := MY_FUNC2(); thay vì something := S2.MY_FUNC2();

My_FUNC2

CREATE OR REPLACE FUNCTION S2."MY_FUNC2" RETURN VARCHAR2 IS 
     something BOOLEAN; 
     othervar VARCHAR2 (50) := 'TEST2';   
    BEGIN 
     /*some code*/ 
     return othervar; 
    END; 
    /

MY_FUNC2 có một từ đồng nghĩa như thế này:

CREATE OR REPLACE PUBLIC SYNONYM "MY_FUNC2" FOR "S2"."MY_FUNC2" 

MY_FUNC biên dịch với các lỗi:

PLS-00.302: thành phần 'MY_FUNC2' phải được khai báo

tôi không hiểu tại sao tôi nhận được lỗi này, khi các hàm của tôi nằm trong lược đồ khác (S1) họ đã có chính xác cấu trúc tương tự và từ đồng nghĩa đã được tạo chính xác giống nhau (nhưng chỉ vào S1) và MY_FUNC biên dịch tốt.

Tôi đã không tạo các hàm và từ đồng nghĩa này ban đầu. Có thể tôi thiếu một số đặc quyền trong S2, vì vậy MY_FUNC có thể hoạt động bình thường không?

+0

bạn có đang gọi hàm từ s1 hoặc s2 không? – Aramillo

+0

Nếu bạn thực hiện cuộc gọi từ s1, bạn cần cấp đặc quyền thực thi cấp quyền cho s2.MY_FUNC2 thành s1. – Aramillo

+0

theo như tôi hiểu điều này không phải là về cuộc gọi, nó thậm chí không biên dịch. Vì vậy, chỉ để đảm bảo, bởi vì nó không rõ ràng từ câu hỏi của bạn. Bạn đã đăng nhập là sys hay s2? Trước tiên bạn đã tạo MY_FUNC2, sau đó tạo từ đồng nghĩa công khai, sau đó là MY_FUNC? NẾU bạn là SYS hoặc S2 với việc tạo đặc quyền đồng nghĩa công khai và đã làm theo thứ tự này thì không có lý do gì để biên dịch (ngoại trừ my_func đã khai báo varchar2; không có độ chính xác) – Martina

Trả lời

12

Bạn có thể gặp lỗi đó nếu bạn có một đối tượng có cùng tên với lược đồ. Ví dụ:

create sequence s2; 

begin 
    s2.a; 
end; 
/

ORA-06550: line 2, column 6: 
PLS-00302: component 'A' must be declared 
ORA-06550: line 2, column 3: 
PL/SQL: Statement ignored 

Khi bạn tham khảo S2.MY_FUNC2 tên đối tượng đang được giải quyết vì vậy nó không cố gắng để đánh giá S2 như một tên schema. Khi bạn chỉ gọi nó là MY_FUNC2 thì không có sự nhầm lẫn, vì vậy nó hoạt động.

Tài liệu explains name resolution. Phần đầu tiên của tên đối tượng đủ điều kiện - S2 ở đây - được đánh giá là một đối tượng trên lược đồ hiện tại trước khi nó được đánh giá là một lược đồ khác.

Nó có thể không phải là một chuỗi; các đối tượng khác có thể gây ra lỗi tương tự. Bạn có thể kiểm tra sự tồn tại của các đối tượng có cùng tên bằng cách truy vấn từ điển dữ liệu.

select owner, object_type, object_name 
from all_objects 
where object_name = 'S2'; 
+0

Cảm ơn Alex! Điều này có vẻ hợp lý, họ có một View có cùng tên so với Schema. Có cách nào để làm cho Oracle giải thích S2 như một lược đồ chứ không phải là dạng xem? – Dzyann

+0

@Dzyann - không theo các quy tắc tìm kiếm đó. Tại sao bạn có nó đủ điều kiện ở tất cả mặc dù; nếu bạn đang đề cập đến một cái gì đó trong cùng một lược đồ không có lợi ích thực sự để tiền tố tất cả mọi thứ với tên lược đồ? –

+0

Ban đầu tôi chỉ không thể hiểu tại sao điều này làm việc trong một lược đồ và không phải là lược đồ khác. Ngoài ra sau khi hiểu được vấn đề, tôi nhận ra điều này cũng sẽ xảy ra từ các lược đồ khác. Gọi MY_FUNC2 từ S1 không thành công vì Oracle tìm thấy SYNONYM đầu tiên cho Chế độ xem S2, thay vì lược đồ S2. Về cơ bản, vì tôi không thể buộc oracle giải thích S2 là một lược đồ, tôi nghĩ cách để đi là thay đổi tên của S2 View và PUBLIC SYNONYM của nó. – Dzyann

2

Tôi đến đây vì tôi gặp vấn đề tương tự.
Vấn đề đối với tôi là quy trình được xác định trong phần thân gói, nhưng không phải trong tiêu đề gói.
Tôi đã thực hiện chức năng của mình bằng câu lệnh BEGIN END bị mất.

+0

Ban phước cho bạn :) Tôi đã có cùng một vấn đề, quên gói SPEC –

+0

tôi gặp phải tình huống tương tự, nhưng trong một mã di sản. Thủ tục này có nghĩa là một địa phương, vô hình với thế giới bên ngoài. Giải pháp là tìm một số thủ tục cha mẹ sẽ gọi nó. Lần này, thủ tục cha được khai báo trong tiêu đề –

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