如何在執行前驗證 Oracle 動態 SQL 的語法?
問題陳述
你想要在執行前驗證 SQL 的語法。
解決方案:DBMS_SQL 預設包允許動態執行 SQL。它屬於 SYS 所有,已使用 AUTHID CURRENT_USER 關鍵字進行定義,因此它使用呼叫者的許可權執行。我們可以利用 DBMS_SQL.PARSE 函式來驗證語法。
我們將首先定義一個函式,以接受 SQL 語句作為引數並解析 SQL 語句。
/* * --------------------------------------------------------------------------- * Function : check_syntax * Input : sql statement * Output : Number * --------------------------------------------------------------------------- */ FUNCTION check_syntax ( p_query IN CLOB ) RETURN INTEGER IS l_cursor NUMBER := dbms_sql.open_cursor; BEGIN BEGIN DBMS_SQL.PARSE (l_cursor, p_query, DBMS_SQL.native); EXCEPTION WHEN OTHERS THEN DBMS_SQL.CLOSE_CURSOR (l_cursor); RETURN -1; END; DBMS_SQL.CLOSE_CURSOR (l_cursor); RETURN 0; END check_syntax;
在上述函式中,l_cursor 是使用 open_cursor 函式開啟的。然後使用 DBMS_SQL.PARSE 解析已給出的 SQL 語句,如果 SQL 語法有問題,那麼它將返回 -1。現在我們將透過傳遞示例 SQL 來執行此函式。
示例 1:將有效的 SQL 傳遞給函式
DECLARE l_rc VARCHAR2(100); l_sql_stmnt CLOB; BEGIN l_sql_stmnt := 'SELECT 1 FROM DUAL' ; l_rc := my_package.check_syntax(l_sql_stmnt); IF l_rc = 0 THEN dbms_output.put_line(' ** SQL Validation Pass - ' || l_sql_stmnt); ELSE dbms_output.put_line(' ** SQL Validation Fail - ' || l_sql_stmnt); END IF; END;
輸出
** SQL Validation Pass - SELECT 1 FROM DUAL
示例 2:將無效的 SQL 傳遞給函式
DECLARE l_rc VARCHAR2(100); l_sql_stmnt CLOB; BEGIN l_sql_stmnt := 'SELECT 1 FROM DUALED' ; l_rc := my_package.check_syntax(l_sql_stmnt); IF l_rc = 0 THEN dbms_output.put_line(' ** SQL Validation Pass - ' || l_sql_stmnt); ELSE dbms_output.put_line(' ** SQL Validation Fail - ' || l_sql_stmnt); END IF; END;
輸出
** SQL Validation Fail - SELECT 1,2,4 FROM DUALED
資料結構
網路
RDBMS
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP