日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Oracle入门(十四.18)之使用动态SQL

發(fā)布時(shí)間:2023/12/3 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Oracle入门(十四.18)之使用动态SQL 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、SQL的執(zhí)行流程

數(shù)據(jù)庫中的所有SQL語句都經(jīng)歷了不同的階段:
?解析:預(yù)執(zhí)行“這可能嗎?”檢查包括語法,對(duì)象存在,權(quán)限等
?綁定:獲取語句中引用的任何變量的實(shí)際值
?執(zhí)行:語句被執(zhí)行。

?提取:結(jié)果返回給用戶。

某些階段可能與所有語句無關(guān);例如,提取階段適用于查詢,但不適用于DML。


二、PL / SQL子程序中SQL的執(zhí)行流程

當(dāng)PL / SQL子程序中包含SQL語句時(shí),解析和綁定階段通常是在編譯時(shí)完成的,也就是說,當(dāng)過程,函數(shù)或包體是CREATEd時(shí)。

如果在創(chuàng)建過程時(shí)SQL語句的文本未知,該怎么辦? Oracle服務(wù)器如何解析它? 它不能。 例如,假設(shè)您想要?jiǎng)h除一個(gè)表,但用戶在執(zhí)行時(shí)輸入表名:

CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) IS BEGINDROP TABLE p_table_name; -- cannot be parsed END;


三、動(dòng)態(tài)SQL

您使用動(dòng)態(tài)SQL來創(chuàng)建一個(gè)SQL語句,其中的文本事先不完全知道。
動(dòng)態(tài)SQL:
?構(gòu)造并存儲(chǔ)為子程序內(nèi)的字符串。
?是否包含具有不同列數(shù)據(jù)的SQL語句,或帶有或不帶有占位符(綁定變量)的不同條件。

?使數(shù)據(jù)定義,數(shù)據(jù)控制或會(huì)話控制語句能夠從PL / SQL寫入和執(zhí)行。

(1)本地動(dòng)態(tài)SQL

PL / SQL不支持直接寫在procedure中的DDL語句。 本地動(dòng)態(tài)SQL允許您通過在子程序中構(gòu)建SQL并將其存儲(chǔ)為字符串來解決此問題。 本地動(dòng)態(tài)SQL:
?以PL / SQL語言直接為動(dòng)態(tài)SQL提供本機(jī)支持。

?使數(shù)據(jù)定義,數(shù)據(jù)控制或會(huì)話控制語句能夠從PL / SQL寫入和執(zhí)行。

?使用本機(jī)動(dòng)態(tài)SQL語句(EXECUTE IMMEDIATE)或DBMS_SQL包執(zhí)行。
?提供執(zhí)行直到執(zhí)行時(shí)間結(jié)構(gòu)未知的SQL語句的能力。

?也可以使用OPEN-FOR,FETCH和CLOSE PL / SQL語句。

(2)使用EXECUTE IMMEDIATE語句

在PL / SQL匿名塊或子程序中為原生動(dòng)態(tài)SQL使用EXECUTE IMMEDIATE語句:

EXECUTE IMMEDIATE dynamic_string [INTO {define_variable[, define_variable] ... | record}] [USING [IN|OUT|IN OUT] bind_argument[, [IN|OUT|IN OUT] bind_argument] ... ];?INTO用于單行查詢,并指定檢索列值的變量或記錄。

?USING保存所有綁定參數(shù)。 如果未指定,則默認(rèn)參數(shù)模式為IN。

?dynamic_string是包含SQL語句文本的字符變量或文字。
?define_variable是一個(gè)PL / SQL變量,用于存儲(chǔ)選定的列值。
?record是存儲(chǔ)選定行的用戶定義或%ROWTYPE記錄。

?bind_argument是一個(gè)表達(dá)式,其值在執(zhí)行時(shí)傳遞給動(dòng)態(tài)SQL語句。

?USING子句保存所有綁定參數(shù)。 默認(rèn)參數(shù)模式是IN。

示例1:使用DDL語句的動(dòng)態(tài)SQL

在線構(gòu)建動(dòng)態(tài)聲明:

CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) IS BEGINEXECUTE IMMEDIATE 'DROP TABLE '||p_table_name; END;

在一個(gè)變量中構(gòu)造動(dòng)態(tài)語句:

CREATE PROCEDURE drop_any_table(p_table_name VARCHAR2) ISv_dynamic_stmt VARCHAR2(50); BEGINv_dynamic_stmt := 'DROP TABLE '||p_table_name;EXECUTE IMMEDIATE v_dynamic_stmt; END; BEGINdrop_any_table('EMPLOYEE_NAMES'); END;示例2:使用DML語句的動(dòng)態(tài)SQL

刪除任何表中的所有行并返回計(jì)數(shù):

CREATE FUNCTION del_rows(p_table_name VARCHAR2) RETURN NUMBER IS BEGINEXECUTE IMMEDIATE 'DELETE FROM '||p_table_name;RETURN SQL%ROWCOUNT; END;

調(diào)用該函數(shù):

DECLAREv_count NUMBER; BEGINv_count := del_rows('EMPLOYEE_NAMES');DBMS_OUTPUT.PUT_LINE(v_count|| ' rows deleted.'); END;示例3:使用DML語句的動(dòng)態(tài)SQL

這是一個(gè)將行插入兩列并調(diào)用過程的示例。

CREATE PROCEDURE add_row(p_table_name VARCHAR2,p_id NUMBER, p_name VARCHAR2) IS BEGINEXECUTE IMMEDIATE 'INSERT INTO '||p_table_name||' VALUES (p_id, p_name)'; END; BEGIN add_row('EMPLOYEE_NAMES', 250, 'Chang'); END;示例4:使用本機(jī)動(dòng)態(tài)SQL重新編譯PL / SQL代碼

您可以使用下列ALTER語句重新編譯PL / SQL對(duì)象而不重新創(chuàng)建它們:

ALTER PROCEDURE procedure-name COMPILE; ALTER FUNCTION function-name COMPILE; ALTER PACKAGE package_name COMPILE SPECIFICATION; ALTER PACKAGE package-name COMPILE BODY;

本示例創(chuàng)建一個(gè)過程,用于重新編譯在運(yùn)行時(shí)輸入其名稱和類型的PL / SQL對(duì)象。

CREATE PROCEDURE compile_plsql (p_name VARCHAR2,p_type VARCHAR2,p_options VARCHAR2 := NULL) ISv_stmt VARCHAR2(200); BEGINv_stmt := 'ALTER '||p_type||' '||p_name||' COMPILE'||' '||p_options;EXECUTE IMMEDIATE v_stmt; END; BEGIN compile_plsql('MYPACK','PACKAGE','BODY'); END;


四、使用DBMS_SQL包

(1)DBMS_SQL包的一些過程和功能是:

? OPEN_CURSOR

? PARSE

? BIND_VARIABLE

? EXECUTE

? FETCH_ROWS

? CLOSE_CURSOR

(2)使用帶有DML語句的DBMS_SQL

刪除行的示例:

CREATE OR REPLACE FUNCTION del_rows (p_table_name VARCHAR2) RETURN NUMBER ISv_csr_id INTEGER;v_rows_del NUMBER; BEGINv_csr_id := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_csr_id,'DELETE FROM '||p_table_name, DBMS_SQL.NATIVE);v_rows_del := DBMS_SQL.EXECUTE (v_csr_id);DBMS_SQL.CLOSE_CURSOR(v_csr_id);RETURN v_rows_del; END;

請(qǐng)將本文前面的內(nèi)容與del_rows函數(shù)進(jìn)行比較。 它們功能相同,但更簡(jiǎn)單?

(3)使用帶有參數(shù)化DML語句的DBMS_SQL

再次,將其與本課前面的add_row過程進(jìn)行比較。 你寧愿寫什么?
CREATE PROCEDURE add_row (p_table_name VARCHAR2, p_id NUMBER, p_name VARCHAR2) ISv_csr_id INTEGER;v_stmt VARCHAR2(200);v_rows_added NUMBER; BEGINv_stmt := 'INSERT INTO '||p_table_name||' VALUES ('||p_id||','''||p_name||''')';v_csr_id := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_csr_id,v_stmt, DBMS_SQL.NATIVE);v_rows_added := DBMS_SQL.EXECUTE(v_csr_id);DBMS_SQL.CLOSE_CURSOR(v_csr_id); END;


五、本地動(dòng)態(tài)SQL與DBMS_SQL包的比較

原生動(dòng)態(tài)SQL

?比DBMS_SQL更易于使用
?比DBMS_SQL需要更少的代碼

?通常執(zhí)行速度比DBMS_SQL快,因?yàn)閳?zhí)行的語句較少。


總結(jié)

以上是生活随笔為你收集整理的Oracle入门(十四.18)之使用动态SQL的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。