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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

数据库

DBMS_SQL包使用

發(fā)布時(shí)間:2024/8/26 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DBMS_SQL包使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

DBMS_SQL package 學(xué)習(xí)

?這個(gè)包提供了一種使用動(dòng)態(tài)sql來(lái)訪問(wèn)數(shù)據(jù)庫(kù)的方法。

第一步:打開(kāi)游標(biāo)

使用函數(shù) function open_cursor return integer;

定義變量 Cur_1 integer; --返回的新游標(biāo)的ID值

語(yǔ)句是Cur_1 := Dbms_Sql.Open_Cursor;

第二步:解析要執(zhí)行的語(yǔ)句

使用過(guò)程procedure parse(c in integer, statement in varchar2,??????????????????language_flag in integer);

語(yǔ)句是Dbms_Sql.Parse(Cur_1, ’sql語(yǔ)句’, Dbms_Sql.V7);

第三步:定義字段變量,其值對(duì)應(yīng)于指定游標(biāo)中某個(gè)位置元素的值(僅用于SELECT語(yǔ)句)

使用過(guò)程procedure define_column(c in integer, position in integer, column in number);

語(yǔ)句是Dbms_Sql.Define_Column(Cur_1, 1, column);

定義第一列為column,可重復(fù)定義多個(gè)列;

第四步:執(zhí)行指定游標(biāo)

使用過(guò)程function execute(c in integer) return integer;--返回行數(shù)

語(yǔ)句是Rows_1 := Dbms_Sql.EXECUTE(Cur_1);

第五步:從指定的游標(biāo)中取出記錄

使用過(guò)程function fetch_rows(c in integer) return integer;--返回行數(shù)

采用If Dbms_Sql.Fetch_Rows(Cur_1) > 0 then 判斷是否取到數(shù)據(jù)了

然后返回游標(biāo)中指定位置的元素,使用過(guò)程procedure column_value(c in integer, position in integer, value out number);

語(yǔ)句是Dbms_Sql.Column_Value(Cur_1, 1, column);

把游標(biāo)中的第一列的值賦值給column,可重復(fù)賦值多個(gè)列;

要加上end if;

最后關(guān)閉游標(biāo)

語(yǔ)句是Dbms_Sql.Close_Cursor(Cur_1);


通常運(yùn)用DBMS_SQL包一般分為幾步:
1. open cursor: 打開(kāi)cursor
2. parse cursor:解析你要執(zhí)行的 SQL語(yǔ)句
3. bind variable:如果要執(zhí)行的SQL語(yǔ)句中包含變量,在此就需要綁定變量
4. execute:執(zhí)行SQL語(yǔ)句
5. close cursor:在執(zhí)行后關(guān)閉此cursor.
如果你還需要返回執(zhí)行SQL的結(jié)果集,還需要使用define_column,define_array等方法。

下面根據(jù)不同情況進(jìn)行詳細(xì)展示:
在做展示之前,先準(zhǔn)備一些基礎(chǔ)數(shù)據(jù)
Sql代碼??
  • create?table?demo?(a?number,b?number,c?number);??
  • begin??
  • ??for?i?in?1?..?15?loop??
  • ????insert?into?demo??
  • ????values??
  • ??????(round(dbms_random.value,?2)?*?100,??
  • ???????round(dbms_random.value,?2)?*?100,??
  • ???????round(dbms_random.value,?2)?*?100);??
  • ??end?loop;??
  • ??commit;??
  • end;??
  • ?

    基礎(chǔ)數(shù)據(jù)完成之后,下面開(kāi)始對(duì)一些具體情況進(jìn)行分析:
    1.執(zhí)行一般的select語(yǔ)句
    ?? 首先先介紹最常用情況:
    Sql代碼??
  • create?or?replace?procedure?define_column(no?in?number)?is??
  • ??cursor_name??????integer?:=?dbms_sql.open_cursor;?--在初始化參數(shù)時(shí),就可以打開(kāi)cursor;??
  • ??row_process??????integer;??
  • ??v_b?number;??
  • begin??
  • ??--解析要執(zhí)行的SQL.??
  • ??dbms_sql.parse(cursor_name,??
  • ?????????????????'select?*?from?demo?where?a=?:no',??
  • ?????????????????dbms_sql.native);??
  • ??--如果要執(zhí)行的SQL中不需要參數(shù),則可以省略掉bind_variable--??
  • ??dbms_sql.bind_variable(cursor_name,?'no',?no);??
  • ??/*如果需要返回查詢語(yǔ)句的結(jié)果,則必須在exec之前使用define_column函數(shù)定義返回字段;define_column函數(shù)的第一個(gè)參數(shù)是最初定義的cursor?name,第二個(gè)參數(shù)是指需要返回的字段在查詢結(jié)果中處于第幾列,在此例中返回的字段是查詢結(jié)果中的第二列,即b列;第三個(gè)參數(shù)就是接收返回結(jié)果需要的變量*/??
  • ??dbms_sql.define_column(cursor_name,?2,?v_b);??
  • ??--必須定義一個(gè)參數(shù)接收exec的結(jié)果??
  • ??row_process?:=?dbms_sql.execute(cursor_name);??
  • ??loop??
  • ????if?dbms_sql.fetch_rows(cursor_name)?>?0?then??
  • ??????--將前面定義的字段返回給變量v_b--??
  • ??????dbms_sql.column_value(cursor_name,?2,?v_b);??
  • ??????dbms_output.put_line('B?is?'?||?v_b);??
  • ????else??
  • ??????exit;??
  • ????end?if;??
  • ??end?loop;??
  • ??--數(shù)據(jù)處理完成后記得要將cursor關(guān)閉??
  • ??dbms_sql.close_cursor(cursor_name);??
  • exception??
  • ??when?others?then??
  • ????dbms_sql.close_cursor(cursor_name);??
  • end;??
  • ?

    2.使用define_array方法得到查詢結(jié)果
    ??? 前面已經(jīng)分析了如何使用define_column方法得到查詢結(jié)果,但有時(shí)我們想要一次得到多行查詢結(jié)果,此時(shí)我們就需要使用define_array方法,此方法常用于DML操作,稍后會(huì)有例子對(duì)此介紹,現(xiàn)在先來(lái)看一下如果使用define_array.

    Sql代碼??
  • create?or?replace?procedure?define_array?is??
  • ??c??????NUMBER;??
  • ??d??????NUMBER;??
  • ??/*DBMS_SQL.NUMBER_TABLE類(lèi)型實(shí)際就是type?NUMBER_TABLE?is?table?of?number?index?by?binary_integer;*/??
  • ??n_tab??DBMS_SQL.NUMBER_TABLE;??
  • ??n_tab1?DBMS_SQL.NUMBER_TABLE;??
  • ??indx???NUMBER?:=?1;??
  • BEGIN??
  • ??c?:=?DBMS_SQL.OPEN_CURSOR;??
  • ??DBMS_SQL.PARSE(c,??
  • ?????????????????'select?*?from?demo?where?rownum<13?order?by?1',??
  • ?????????????????DBMS_SQL.NATIVE);??
  • ??/*在此需要特別介紹一下define_array函數(shù)的第一個(gè)參數(shù)是已經(jīng)打開(kāi)的cursor名稱,?第二個(gè)參數(shù)是指需要返回的字段在查詢結(jié)果中處于第幾列,第三個(gè)參數(shù)就是接收返回結(jié)果需要的變量,與define_column不同的是此變量是table,而不是普通的字段類(lèi)型;第四個(gè)參數(shù)表示一次可以返回的行數(shù);第五個(gè)參數(shù)是指n_tab的index從哪個(gè)數(shù)值開(kāi)始,此數(shù)值是遞增的.在此例中index是從1開(kāi)始的,一次得到9行結(jié)果集,則有n_tab(1)到n_tab(9),如果循環(huán)再得到新的結(jié)果集,則index繼續(xù)增長(zhǎng)n_tab(10)....*/??
  • ??DBMS_SQL.DEFINE_ARRAY(c,?1,?n_tab,?9,?indx);??
  • ??DBMS_SQL.DEFINE_ARRAY(c,?2,?n_tab1,?9,?indx);??
  • ??d?:=?DBMS_SQL.EXECUTE(c);??
  • ??loop??
  • ????d?:=?DBMS_SQL.FETCH_ROWS(c);??
  • ????dbms_output.put_line('fetch?rows?is?'?||?d);??
  • ????EXIT?WHEN?d?<?9;??
  • ????DBMS_SQL.COLUMN_VALUE(c,?1,?n_tab);??
  • ????DBMS_SQL.COLUMN_VALUE(c,?2,?n_tab1);??
  • ????for?i?in?1?..?d?loop??
  • ??????dbms_output.put_line(n_tab(i)?||?','?||?n_tab1(i));??
  • ????end?loop;??
  • ??END?LOOP;??
  • ??DBMS_SQL.CLOSE_CURSOR(c);??
  • EXCEPTION??
  • ??WHEN?OTHERS?THEN??
  • ????IF?DBMS_SQL.IS_OPEN(c)?THEN??
  • ??????DBMS_SQL.CLOSE_CURSOR(c);??
  • ????END?IF;??
  • END;??
  • ?

    3.使用variable_value顯示DML后的返回結(jié)果(單條記錄)
    ?? 以上我們介紹了如何使用DBMS_SQL包來(lái)處理數(shù)據(jù)查詢,如果我們把查詢語(yǔ)句更換成DML語(yǔ)句,則可以完成各種DML操作。
    ? 在PL/SQL中我們可以使用returning方法返回DML操作結(jié)果,在DBMS_SQL包中可不可以實(shí)現(xiàn)呢?答案當(dāng)然是可以,用variable_value方法就可以實(shí)現(xiàn)。下面就分別用兩個(gè)例子來(lái)展示如何實(shí)現(xiàn),一個(gè)是返回單條記錄,另一個(gè)是返回多條記錄。

    (1)返回單條記錄
    Sql代碼??
  • procedure?single_insert(c1?in?number,?c2?in?number,?r?out?number)?is??
  • ??
  • ??cursor_name?number?:=?dbms_sql.open_cursor;??
  • ??n???number;??
  • begin??
  • ??dbms_sql.parse(cursor_name,??
  • ?????????????????'insert?into?demo?values?(:a,:b)?returning?:a*:b?into?:r',??
  • ?????????????????dbms_sql.native);??
  • ??dbms_sql.bind_variable(cursor_name,?'a',?c1);??
  • ??dbms_sql.bind_variable(cursor_name,?'b',?c2);??
  • ??dbms_sql.bind_variable(cursor_name,?'r',?r);??
  • ??n?:=?dbms_sql.execute(cursor_name);??
  • ??--使用variable_value函數(shù)得到DML操作returning的結(jié)果集??
  • ??dbms_sql.variable_value(cursor_name,?'r',?r);??
  • ??dbms_output.put_line(r);??
  • ??dbms_sql.close_cursor(cursor_name);??
  • exception??
  • ??when?others?then??
  • ????dbms_sql.close_cursor(cursor_name);??
  • end;??
  • ?
    (2)返回多條記錄
    結(jié)合define_array使用,可以更好的完成DML操作。

    Sql代碼??
  • create?or?replace?package?DBMS_SQL_DEMO?as??
  • ??
  • ??procedure?multi_insert;??
  • ???
  • end;??
  • /??
  • ??
  • create?or?replace?package?body?DBMS_SQL_DEMO?as??
  • ??
  • ??procedure?multi_insert_priv(c1?in?dbms_sql.Number_Table,??
  • ??????????????????????????????c2?in?dbms_sql.Number_Table,??
  • ??????????????????????????????r??out?dbms_sql.Number_Table)?is??
  • ???
  • ????cursor_name?number?:=?dbms_sql.open_cursor;??
  • ????n???????????number;??
  • ??begin??
  • ????dbms_sql.parse(cursor_name,??
  • ???????????????????'insert?into?demo?values?(:a,:b)?returning?:a*:b?into?:r',??
  • ???????????????????dbms_sql.native);??
  • ????--使用bind_array函數(shù)將number_table類(lèi)型的變量賦值給綁定變量??
  • ????dbms_sql.bind_array(cursor_name,?'a',?c1);??
  • ????dbms_sql.bind_array(cursor_name,?'b',?c2);??
  • ????dbms_sql.bind_array(cursor_name,?'r',?r);??
  • ????n?:=?dbms_sql.execute(cursor_name);??
  • ????--使用variable_value函數(shù)將returning的結(jié)果集賦值給number_table類(lèi)型的變量??
  • ????dbms_sql.variable_value(cursor_name,?'r',?r);??
  • ????dbms_sql.close_cursor(cursor_name);??
  • ??exception??
  • ????when?others?then??
  • ??????dbms_sql.close_cursor(cursor_name);??
  • ??end;??
  • ??
  • ??procedure?multi_insert?is??
  • ????c1??????????dbms_sql.Number_Table;??
  • ????c2??????????dbms_sql.Number_Table;??
  • ????cursor_name?number?:=?dbms_sql.open_cursor;??
  • ????n???????????number;??
  • ????r???????????dbms_sql.Number_Table;??
  • ????indx????????number?:=?1;??
  • ????d???????????number;??
  • ??begin??
  • ????dbms_sql.parse(cursor_name,?'select?*?from?demo',?dbms_sql.native);??
  • ????dbms_sql.define_array(cursor_name,?1,?c1,?5,?indx);??
  • ????dbms_sql.define_array(cursor_name,?2,?c2,?5,?indx);??
  • ????n?:=?dbms_sql.execute(cursor_name);??
  • ????loop??
  • ??????d?:=?dbms_sql.fetch_rows(cursor_name);??
  • ??????exit?when?d?=?0;??
  • ??????dbms_sql.column_value(cursor_name,?1,?c1);??
  • ??????dbms_sql.column_value(cursor_name,?2,?c2);??
  • ??????multi_insert_priv(c1,?c2,?r);??
  • ??????for?i?in?1?..?r.count?loop??
  • ????????dbms_output.put_line(r(i));??
  • ??????end?loop;??
  • ????end?loop;??
  • ??exception??
  • ????when?others?then??
  • ??????dbms_sql.close_cursor(cursor_name);??
  • ??end;??
  • ??
  • end;??
  • / ?
  • 總結(jié)

    以上是生活随笔為你收集整理的DBMS_SQL包使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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