Biến ràng buộc không được phép trong các câu lệnh DDL. Vì vậy, các câu lệnh sau sẽ gây ra lỗi:
-
Ví dụ # 1:Câu lệnh DDL . Sẽ gây ra ORA-01027:các biến liên kết không được phép cho các hoạt động định nghĩa dữ liệu
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42;
-
Ví dụ # 2:Câu lệnh DDL . Sẽ gây ra ORA-00904::mã định danh không hợp lệ
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name;
-
Ví dụ # 3:Câu lệnh SCL . Sẽ gây ra ORA-02248:tùy chọn không hợp lệ cho ALTER SESSION
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option;
Vấn đề
Để hiểu tại sao điều này xảy ra, chúng ta cần xem Cách xử lý các câu lệnh SQL động.
Thông thường, một chương trình ứng dụng nhắc người dùng về văn bản của câu lệnh SQL và các giá trị của các biến máy chủ được sử dụng trong câu lệnh. Sau đó, Oracle phân tích cú pháp câu lệnh SQL. Nghĩa là, Oracle kiểm tra câu lệnh SQL để đảm bảo nó tuân theo các quy tắc cú pháp và tham chiếu đến các đối tượng cơ sở dữ liệu hợp lệ. Phân tích cú pháp cũng liên quan đến việc kiểm tra quyền truy cập cơ sở dữ liệu , dự trữ tài nguyên cần thiết và tìm đường dẫn truy cập tối ưu.
Phần nhấn mạnh do người trả lời thêm vào
Lưu ý rằng bước phân tích cú pháp xảy ra trước ràng buộc bất kỳ biến nào với câu lệnh động. Nếu bạn xem xét bốn ví dụ trên, bạn sẽ nhận ra rằng không có cách nào để trình phân tích cú pháp đảm bảo tính hợp lệ về mặt cú pháp của các câu lệnh SQL động này mà không cần biết các giá trị cho các biến liên kết.
- Ví dụ # 1 :Trình phân tích cú pháp không thể biết giá trị ràng buộc có hợp lệ hay không. Điều gì xảy ra nếu thay vì
USING 42
, lập trình viên đã viếtUSING 'forty-two'
? - Ví dụ # 2 :Trình phân tích cú pháp không thể biết nếu
:col_name
sẽ là một tên cột hợp lệ. Điều gì sẽ xảy ra nếu tên cột bị ràng buộc là'identifier_that_well_exceeds_thirty_character_identifier_limit'
? - Ví dụ # 3 :Giá trị cho
NLS_CALENDAR
được xây dựng trong các hằng số (cho một phiên bản Oracle nhất định?). Trình phân tích cú pháp không thể biết liệu biến bị ràng buộc có giá trị hợp lệ hay không.
Vì vậy, câu trả lời là bạn không thể ràng buộc các phần tử lược đồ như tên bảng, tên cột trong SQL động. Bạn cũng không thể liên kết các hằng số tích hợp sẵn .
Giải pháp
Cách duy nhất để đạt được động tham chiếu đến các phần tử / hằng số lược đồ là sử dụng nối chuỗi trong các câu lệnh SQL động.
-
Ví dụ số 1:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
-
Ví dụ số 2:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
-
Ví dụ số 3:
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';