Tại sao chúng ta không thể viết câu lệnh ddl trực tiếp vào khối PL / SQL


11

Tại sao chúng ta không thể viết các câu lệnh ddl trực tiếp trong khối PL / SQL, ví dụ như khi tôi viết

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    truncate table table_name; // error
END test;
/

Nhưng,

CREATE OR REPLACE PROCEDURE test IS
BEGIN
    execute immediate 'truncate table table_name'; // works fine
END test;
/

Tại sao cái thứ hai thực hiện thành công?

Câu trả lời:


7

Như đã nói trong tài liệu :

Chỉ SQL động mới có thể thực thi các loại câu lệnh sau trong các đơn vị chương trình PL / SQL:

  • Các câu lệnh ngôn ngữ định nghĩa dữ liệu (DDL) như CREATE, DROP, GRANT và REVOKE

Một TRUNCATEhoạt động là DDL.

Khi sử dụng EXECUTE IMMEDIATE, hãy nhớ rằng bất kỳ DDLhoạt động nào bạn thực hiện sẽ ngầm định COMMITgiao dịch hiện tại.


1

DDL bên trong mã PL / SQL là ngoại lệ nhiều hơn nhu cầu thực. Phân tích cú pháp có thể được xem như xác minh cấu trúc, bị mất nếu cấu trúc của bạn thay đổi khi thực hiện. Các thủ tục dự định sẽ được phân tích cú pháp một lần nữa các đối tượng khác (bảng hoặc mã pl / sql khác, dạng xem, v.v.). Mỗi lần thay đổi đối tượng, nó sẽ được biên dịch lại. Vì vậy, làm cho mã được phân tích cú pháp của một cái gì đó thay đổi cấu trúc không thể được xác minh và như vậy được biên dịch. Xem xét trường hợp

DROP TABLE T1;

Trong thời gian phân tích cú pháp, bảng sẽ được tìm thấy và thủ tục thành công được biên dịch nhưng trong lần thực hiện đầu tiên, bảng bị hủy và mã của bạn không còn hiệu lực nữa (lần sau DROP TABLE sẽ xảy ra lỗi). Tương tự, bất kỳ thay đổi nào đối với bảng DDL sẽ tạo ra nhu cầu biên dịch lại, do đó làm mất lợi thế của phân tích mã.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.