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

歡迎訪問 生活随笔!

生活随笔

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

数据库

PL/SQL七复合数据结构

發(fā)布時(shí)間:2024/4/17 数据库 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PL/SQL七复合数据结构 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

PL/SQL有兩種復(fù)合數(shù)據(jù)結(jié)構(gòu):記錄和集合。記錄由不同的域組成,集合由不同的元素組成。 記錄: 記錄是PL/SQL的一種復(fù)合數(shù)據(jù)結(jié)構(gòu),scalar數(shù)據(jù)類型和其他數(shù)據(jù)類型只是簡單的在包一級進(jìn)行預(yù)定義,但復(fù)合數(shù)據(jù)類型在使用前必須被定義,記錄之所以被稱為復(fù)合數(shù)據(jù)類型是因?yàn)樗捎蜻@種由數(shù)據(jù)元素的邏輯組所組成。域可以是scalar數(shù)據(jù)類型或其他記錄類型,它與c語言中的結(jié)構(gòu)相似,記錄也可以看成表中的數(shù)據(jù)行,域則相當(dāng)于表中的列,在表和虛擬表(視圖或查詢)中非常容易定義和使用,行或記錄中的每一列或域都可以被引用或單獨(dú)賦值,也可以通過一個(gè)單獨(dú)的語句引用記錄所有的域。在存儲過程或函數(shù)中記錄也可能有參數(shù)。 創(chuàng)建記錄:顯示定義和隱式定義;一旦記錄被定義后,聲明或創(chuàng)建定義類型的記錄變量,然后才是使用該變量。隱式聲明是在基于表的結(jié)構(gòu)或查詢上使用%TYPE屬性,隱式聲明是一個(gè)更強(qiáng)有力的工具,這是因?yàn)閿?shù)據(jù)變量是動(dòng)態(tài)創(chuàng)建的 顯示定義:顯示定義記錄是在PL/SQL程序塊中創(chuàng)建記錄變量之前的聲明部分定義: TYPE record_type IS RECORD(field_definition_list); Field_definition_list是由逗號分隔的列表,語法如下: Field_name data_type_and_size [NOT NULL][{:=|DEFAULT} default_value] DECLARE TYPE stock_quote_rec IS RECORD (symbol stock.symbol %TYPE, bid NUMBER(10, 4), ask NUMBER(10, 4), volumn NUMBER NOT NULL:=0, exchange VARCHAR2(6) DEFAULT 'NASDAQ' ); real_time_quote stock_quote_rec; variable 域定義時(shí)的%TYPE屬性用于引用數(shù)據(jù)庫中的表或視圖的數(shù)據(jù)類型和大小,而在此之前程序不知道類型和大小。在上面的例子中記錄域在編譯時(shí)將被定義為與列SYMBOL相同的數(shù)據(jù)類型和大小,當(dāng)代碼中要使用來自數(shù)據(jù)庫中的數(shù)據(jù)時(shí),在變量或域定義中最好使用%TYPE來定義。 隱士定義:我們不用描述記錄的每一個(gè)域,這是因?yàn)槲覀儾恍枰x記錄的結(jié)構(gòu),不需要使用TYPE,相反在生命記錄變量時(shí)用%ROWTYPE命令定義與數(shù)據(jù)庫表,試圖,游標(biāo)有相同結(jié)構(gòu)的記錄,與TYPE命令相同的是它是一種定義獲得數(shù)據(jù)庫記錄的好方法。 CURSOR xactions_cur(acct_no IN VARCHAR2) IS SELECT action, timestamp, holding FROM portfolios WHERE account_nbr = 'acct_no';xaction_info xactions_cur%ROWTYPE; variableDECLARE CURSOR xactionS_cur IS SELECT action, timestamp, holding FROM portfolios WHERE account_nbr = '37';BEGIN FOR xaction_rec in xactions_cur LOOP IF xaction_rec.holding = 'orcl' THEN notify_shareholder; END IF END LOOP; END 使用記錄: 用戶可以給記錄賦值、將值傳遞給其他程序。記錄作為一種復(fù)合數(shù)據(jù)結(jié)構(gòu)意味作他有兩個(gè)層次可用。用戶可以引用整個(gè)記錄,使用select intofetch轉(zhuǎn)移所有域,也可以將整個(gè)記錄傳遞給一個(gè)程序或?qū)⑺杏虻闹蒂x給另一個(gè)記錄。在更低的層次,用戶可以處理記錄內(nèi)單獨(dú)的域,用戶可以給單獨(dú)的域賦值或者在單獨(dú)的域上運(yùn)行布爾表達(dá)式,也可以將一個(gè)或更多的域傳遞給另一個(gè)程序。 引用記錄:記錄由域組成,訪問記錄中的域使用點(diǎn)(.)符號,我們使用上面的例子看看 DECLARE TYPE stock_quote_rec IS RECORD( symbol stock.symbol%TYPE, bid NUMBER(10, 4), ask NUMBER(10, 4), volumn NUMBER NOT NULL := 0, exchange VARCHAR2(6) DEFAULT 'NASDQA' );TYPE detailed_quote_rec IS RECORD( quote stock_quote_rec, timestamp DATE, bid_size NUMBER, ask_size NUMBER, last_tick VARCHAR2(4) );real_time_detail detail_quote_rec;BEGIN real_time_detail.bin_size:=1000; real_time_detail.quote.volumn:=156700; log_quote(real_time_detail.quote); 給記錄賦值: 使用SELECT INTO: 使用SELECT INTO給記錄賦值要將記錄或域放在INTO子串中,INTO子串中的變量與SELECT中列的位置相對應(yīng)。 DECLARE stock_info1 stocks%ROWTYPE; stock_info2 stocks%ROWTYPE; BEGIN SELECT symbol, exchange INTO stock_info1.symbol, stock_info1.exchange FROM stocks WHERE symbol = 'ORCL';SELECT * INTO stock_info2 FROM stocks WHERE symbol = 'ORCL'; END 使用FETCH: 如果SQL語句返回多行數(shù)據(jù)或者希望使用帶參數(shù)的游標(biāo),那么就要使用游標(biāo),這種情況下使用FETCH語句代替INSTEAD INTO是一個(gè)更簡單、更有效率的方法,但在安全性較高的包中FETCH的語法如下: FETCH cursor_name INTO variable; DECLARE CURSOR stock_cur(symbol_in VARCHAR2) IS SELECT symbol, exchange, begin_date FROM stock WHERE symbol = UPPER(symbol_in);stock_info stock_cur%ROWTYPEBEGIN OPEN stock_cur('ORCL'); FETCH stock_cur INTO stock_info; 使用賦值語句將整個(gè)記錄復(fù)制給另一個(gè)記錄是一項(xiàng)非常有用的技術(shù),不過記錄必須精確地被聲明為相同的類型,不能是基于兩個(gè)不同的TYPE語句來獲得相同的結(jié)構(gòu)。 DECLARE TYPE stock_quote_rec IS RECORD( symbol stocks.symbols%TYPE, bid NUMBER(10, 4), ask NUMBER(10, 4), volumn NUMBER ); TYPE stock_quote_too IS RECORD( symbol stocks.symbols%TYPE, bid NUMBER(10, 4), ask NUMBER(10, 4), volumn NUMBER ); stock_one stocks_quote_rec; stock_two stocks_quote_rec;stock_also stock_rec_too;BEGIN stock_one.symbol:='orcl'; stock_one.volumn:=12334400; stock_two:=stock_one; // correct stock_also:=stock_one; // incorrect, the data type is wrong stock_also.symbol:=stock_one.symbol; stock_also.volumn:=stock_one.volumn; END 記錄不能用于INSERT語句和將記錄直接用于比較,下面兩種情況是錯(cuò)誤的: INSERT INTO stocks VALUES(stock_record); IF stock_rec1 > stock_rec2 THEN 集合:集合與其他語言中的數(shù)組相似,在ORACLE7.3及以前的版本中只有一種集合稱為PL/SQL表,這種類型的集合依然保留,就是索引(INDEX_BY)表,與記錄相似,集合在定義的時(shí)候必須使用TYPE語句,然后才是創(chuàng)建和使用這種類型的變量 集合的類型:index_by表,嵌套表,VARRAY這三種類型的集合之間由許多差異,包括數(shù)據(jù)綁定、稀疏性(sparsity)、數(shù)據(jù)庫中的存儲能力都不相同。綁定涉及到集合中元素?cái)?shù)量的限制,VARRAY集合中的元素的數(shù)量是有限Index_by和嵌套表則是沒有限制的。稀疏性描述了集合的下標(biāo)是否有間隔,Index_by表總是稀疏的,如果元素被刪除了嵌套表可以是稀疏的VARRAY類型的集合則是緊密的,它的下標(biāo)之間沒有間隔 Index_by表不能存儲在數(shù)據(jù)庫中,但嵌套表和VARRAY可以被存儲在數(shù)據(jù)庫中。 雖然這三種類型的集合有很多不同之處,但他們也由很多相似的地方: ·???????? 都是一維的類似數(shù)組的結(jié)構(gòu) ·???????? 都有內(nèi)建的方法 ·???????? 訪問由點(diǎn)分隔 集合的創(chuàng)建: Index_by TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY BINRAY_INTEGER; Eg. DECLARE TYPE symbol_tab_typ IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER; symbol_tab symbol_tab_typ; BEGIN 嵌套表:嵌套表非常類似于Index_by表,創(chuàng)建的語法也非常相似。使用TYPE語句,只是沒有INDEX BY BINARY_INTEGER子串 TYPE type_name IS TABLE OF element_type [NOT NULL] VARRAY: TYPE type_name IS [VARRAY|VARRAYING] (max_size) OF element_type [NOT NULL] 使用集合:像記錄一樣,集合可以在兩個(gè)層面上使用 o??? 操作整個(gè)集合 o??? 訪問集合中的 單個(gè)元素 第一種情況使用集合名,第二種情況使用下標(biāo)collection(subscript) 初始化、刪除、引用集合: 使用集合之前必須要初始化,對于Index_by表初始化是自動(dòng)進(jìn)行的,但是對于嵌套表和VARRAY就必須使用內(nèi)建的構(gòu)造函數(shù)。如果重新調(diào)用,嵌套表和VARRAY自動(dòng)置NULL,這不只是元素置NULL,而是整個(gè)集合置NULL。給集合內(nèi)的元素賦值需要使用下標(biāo)符號。將一個(gè)集合的值賦給另一個(gè)集合,只需要簡單的使用賦值操作符 Index_by: DECLARE TYPE symbol_tab_typ IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER; TYPE account_tab_typ IS TABLE OF accounts%ROWTYPE INDEX BY BINARY_INTEGER; symbol_tab symbol_tab_typ; account_tab account_tab_typ; new_acct_tab account_tab_typ; BEGIN SELECT * INTO account_tab(147) FROM accounts WHERE account_nbr = 147; SELECT * INTO account_tab(-3) FROM accounts WHERE account_nbr = 3003; IF account_tab(147).balance < 500 THEN change_maintenance_fee(147); END IF new_acct_tab:=account_tab; symbol_tab(1):='ORCL'; symbol_tab(2):='CSCO'; symbol_tab(3):='SUN';publish_portfolio(symbol_tab); 嵌套表和VARRAY構(gòu)造函數(shù)初始化,構(gòu)造函數(shù)和集合的名字相同,同時(shí)有一組參數(shù),每個(gè)參數(shù)對應(yīng)一個(gè)元素,如果參數(shù)為NULL,那么對應(yīng)的元素就被初始化為NULL,如果創(chuàng)建了元素,但沒有填充數(shù)據(jù),那么元素將保持null值,可以被引用,但不能保持?jǐn)?shù)據(jù)。如果元素沒有初始化,那么就不能引用該元素。 DECLARE TYPE stock_list IS TABLE OF stock.symbol%TYPE; TYPE top10_list IS VARRAY(10) OF stock.symbol%TYPE; biotech_stocks stock_list; tech_10 top10_list;BEGIN biotech_stocks(1):='AMGN'; // this is illegal, becuase biotech_stocks do not been initialize IF biotech_stocks IS NULL THEN biotech_stocks:=('AMGN', 'BGEN', 'IMCL', 'GERN', 'CAR'); END IF;tech_10:=top10_list('ORCL', 'CSCO', 'MSFT', 'INTC', 'SUNW', 'IBM', NULL, NULL); IF tech_10(7) IS NULL THEN tech_10(7):='CPQ'; END IF tech_10(8):='DELL'; END 在這個(gè)例子中,嵌套表BIOTECH_STOCKS初始化有5個(gè)元素,VARRAY tech_10集合最多能有10 個(gè)元素,但構(gòu)造函數(shù)只創(chuàng)建了8個(gè)元素,其中還有兩個(gè)元素是NULL值,在程序中給他們賦值。 初始化基于記錄的集合,就必須將記錄傳遞給構(gòu)造函數(shù),注意不能只是簡單的將記錄的域傳遞給構(gòu)造函數(shù)。例如: DECLARE TYPE stock_quote_rec IS RECORD( symbol stock.symbol%TYPE, bid NUMBER(10, 4), ask NUMBER(10, 4), volumn NUMBER NOT NULL:=0 ); TYPE stock_tab_typ IS TABLE OF stock_quote_rec; quote_list stock_tab_typ; single_quote stock_quote_rec;BEGIN single_quote.symbol:='OPCL'; single_quote.bid:=100; single_quote.ask:=101; single_quote.volumn:=230000; quote_list:=stock_tab_typ(single_quote); // legal quote_list:=stock_tab_typ('CSCO', 43, 323, 323000); // illegal DBMS_OUTPUT.LINE(quote_list(1).bid); END 集合的方法:除了構(gòu)造函數(shù)外,集合還有很多內(nèi)建函數(shù),這些函數(shù)稱為方法。調(diào)用方法的語法如下:collection.method,下面為oracle中集合的方法:
方法 描述 使用限制
COUNT 返回集合中元素的個(gè)數(shù) ?
DELETE 刪除集合中所有元素 ?
DELETE() 刪除元素下標(biāo)為x的元素,如果xnull,則集合保持不變 VARRAY非法
DELETE(,) 刪除元素下標(biāo)從XY的元素,如果X>Y集合保持不變 VARRAY非法
EXIST() 如果集合元素x已經(jīng)初始化,則返回TRUE, 否則返回FALSE ?
EXTEND 在集合末尾添加一個(gè)元素 Index_by非法
EXTEND() 在集合末尾添加x個(gè)元素 Index_by非法
EXTEND(,) 在集合末尾添加元素nx個(gè)副本 Index_by非法
FIRST 返回集合中的第一個(gè)元素的下標(biāo)號,對于VARRAY集合始終返回1 ?
LAST 返回集合中最后一個(gè)元素的下標(biāo)號, 對于VARRAY返回值始終等于COUNT. ?
LIMIT 返回VARRY集合的最大的元素個(gè)數(shù),對于嵌套表和對于嵌套表和Index_bynull Index_by集合無用
NEXT() 返回在元素x之后及緊挨著它的元素的值,如果該元素是最后一個(gè)元素,則返回null. ?
PRIOR() 返回集合中在元素x之前緊挨著它的元素的值,如果該元素是第一個(gè)元素,則返回null ?
TRIM 從集合末端開始刪除一個(gè)元素 對于index_by不合法
TRIM() 從集合末端開始刪除x個(gè)元素 index_by不合法
關(guān)于集合之間的比較: 集合不能直接比較,要比較兩個(gè)集合,可以設(shè)計(jì)一個(gè)函數(shù),該函數(shù)返回一個(gè)標(biāo)量數(shù)據(jù)類型。 IF stock_list > stock_list2 --非法 IF sort_collection(stock_list1) > sort_collection(stock_list2) THEN --合法

轉(zhuǎn)載于:https://www.cnblogs.com/garinzhang/archive/2012/06/27/2566511.html

總結(jié)

以上是生活随笔為你收集整理的PL/SQL七复合数据结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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