ทำไมเราไม่สามารถเขียนคำสั่ง ddl ลงในบล็อก PL / SQL ได้โดยตรง


11

ทำไมเราไม่สามารถเขียนคำสั่ง ddl ได้โดยตรงใน PL / SQL block เช่นเมื่อฉันเขียน

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

แต่,

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

ทำไมคนที่สองถึงทำสำเร็จ


คำตอบ:


7

ตามที่ระบุไว้ในเอกสาร :

SQL แบบไดนามิกเท่านั้นที่สามารถดำเนินการคำสั่งประเภทต่อไปนี้ภายในหน่วยโปรแกรม PL / SQL:

  • คำสั่ง data definition language (DDL) เช่น CREATE, DROP, GRANT และ REVOKE

การดำเนินงานคือTRUNCATEDDL

เมื่อใช้EXECUTE IMMEDIATEงานโปรดจำไว้ว่าDDLการดำเนินการใด ๆ ที่คุณดำเนินการโดยนัยจะเป็นการCOMMITทำธุรกรรมปัจจุบัน


1

DDL ภายในรหัส PL / SQL เป็นข้อยกเว้นมากกว่าความต้องการที่แท้จริง การแยกวิเคราะห์สามารถดูเป็นการตรวจสอบโครงสร้างซึ่งหายไปหากโครงสร้างของคุณเปลี่ยนไปจากการดำเนินการ ขั้นตอนมีวัตถุประสงค์เพื่อแยกวิเคราะห์อีกครั้งวัตถุอื่น ๆ (ตารางหรือรหัส pl / sql อื่น ๆ มุมมอง ฯลฯ ) แต่ละครั้งขึ้นอยู่กับการเปลี่ยนแปลงวัตถุมันควรจะคอมไพล์ใหม่ ดังนั้นการแยกวิเคราะห์โค้ดของบางอย่างที่มากกว่าโครงสร้างการเปลี่ยนแปลงจึงไม่สามารถตรวจสอบและรวบรวมได้ พิจารณากรณี

DROP TABLE T1;

ในช่วงเวลาในการแยกวิเคราะห์จะพบตารางและขั้นตอนการคอมไพล์สำเร็จ แต่ในการประมวลผลครั้งที่ 1 ตารางจะถูกดร็อปและโค้ดของคุณไม่ถูกต้องอีกต่อไป (ครั้งถัดไปที่ตาราง DROP จะทำให้เกิดข้อผิดพลาด) ในทำนองเดียวกันการเปลี่ยนแปลงใด ๆ ในตาราง DDL จะสร้างความต้องการในการคอมไพล์ซ้ำดังนั้นการสูญเสียความได้เปรียบของการแยกวิเคราะห์รหัส

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.