闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄥジ鏌熼惂鍝ョМ闁哄矉缍侀、姗€鎮欓幖顓燁棧闂備線娼уΛ娆戞暜閹烘缍栨繝闈涱儐閺呮煡鏌涘☉鍗炲妞ゃ儲鑹鹃埞鎴炲箠闁稿﹥顨嗛幈銊╂倻閽樺锛涢梺缁樺姉閸庛倝宕戠€n喗鐓熸俊顖濆吹濠€浠嬫煃瑜滈崗娑氭濮橆剦鍤曢柟缁㈠枛椤懘鏌eΟ鑽ゅ灩闁搞儯鍔庨崢閬嶆煟韫囨洖浠滃褌绮欓幃锟狀敍濮樿偐鍞甸柣鐔哥懃鐎氼厾绮堥埀顒勬⒑鐎圭媭娼愰柛銊ユ健閵嗕礁鈻庨幋鐘碉紲闂佽鍎虫晶搴g玻濡ゅ懏鈷掑ù锝呮啞閸熺偞銇勯鐐搭棦鐎规洘锕㈤弫鎰板幢濞嗗苯浜炬繛宸簼閸婂灚顨ラ悙鑼虎闁告梹纰嶇换娑㈡嚑椤掆偓閳诲牏鈧娲橀崹鍧楃嵁濮椻偓閹虫粓妫冨☉娆戔偓顓㈡⒒娴e憡鍟炴繛璇х畵瀹曟粌鈽夐埗鍝勬喘椤㈡﹢鎮㈤搹鍦闂備礁鍟块惃婵嬪磻閹剧粯鐓曢柡鍥╁仧娴犳盯鏌i妶鍕槮閾绘牠鏌e鈧ḿ褎绂掑⿰鍕箚妞ゆ劧绲跨粻鎾淬亜閺囶亞绉い銏″哺閸┾偓妞ゆ巻鍋撻柣锝囧厴閹剝鎯旈鎯ф暩婵$偑鍊曠换瀣倿閿曗偓閳诲秵绻濋崶銊у幍濡炪倖姊婚悺鏂库枔濠婂牊鐓涘ù锝囨嚀婵牓鏌熼娑欑叆闁宠鍨垮畷鐓庘攽閸℃ḿ妲楅梻鍌欐祰椤曆兠归悜钘夌疇闁规崘顕х粻鐔兼煥濞戞ê顏€规洘鐓¢弻娑㈠即閵娿儱绠哄銈庡亝濞茬喖寮婚悢鍏煎€绘俊顖濐嚙闂夊秶绱撻崒姘毙㈡繛宸弮瀵寮撮悢铏诡啎闂佸壊鐓堥崰鏍ㄦ叏閵忋倖鈷戦柤濮愬€曢弸鍌炴煕閺傝法鐒搁柍銉︽瀹曟﹢顢欓崲澹洤绠圭紒顔煎帨閸嬫捇鎳犻鈧崵顒傜磽閸屾艾鈧娆㈤敓鐘茬獥婵°倕鎳庣粻浼存煙闂傚鍔嶉柛瀣ф櫊閺岋綁骞嬮敐鍡╂缂佺虎鍘搁崑鎾绘⒒娴h櫣甯涢柛鏃€娲滅划鏃堝醇閺囩偟鐛ラ梺鍝勭▉閸樿偐绮婚弽銊х闁糕剝蓱鐏忣厾绱掗悪鍛ɑ缂佺粯绻堝Λ鍐ㄢ槈濞嗘劖鍊锋俊鐐€ч懙褰掑疾閻樺樊娼栨繛宸簻缁狀噣鏌ら幁鎺戝姕闁哄棛濞€濮婃椽骞栭悙鎻掝瀳濠电姭鍋撻柛妤冨€i敐澶婄疀闁哄娉曢鎺楁煟鎼淬垻鈯曢柨姘亜鎼淬垺灏扮紒缁樼箓閳绘捇宕归鐣屼憾闂備胶纭堕弲娑㈡偋婵犲嫮鐭夌€广儱鎳夐弨浠嬫倵閿濆簼绨介柣銈呭濮婃椽妫冨ù銉ョ墦瀵彃鈽夐姀鈥斥偓宄扳攽閻樺弶澶勯柣鎾崇箰閳规垿鎮欓懠顑胯檸闂侀€炲苯澧い銊ョ墢閸掓帞鎷犲顔藉兊濡炪倖甯掗ˇ鎵偓闈涚焸濮婃椽妫冨☉姘暫濠碘槅鍋呯粙鎺楀疾閸洦鏁嗛柛鏇ㄥ墰閸樹粙姊洪崫鍕殲闁搞劌鐏氶弲鍫曞箻椤旂晫鍘介梺鐟扮仢閸燁偅鏅剁€涙ǜ浜滈柕蹇婃濞堟粎鈧娲樼敮鎺曠亙闂侀€炲苯澧紒鍌氱У閵堬綁宕橀埡浣风敾婵犵數鍋涘Λ妤冩崲閹伴偊鏁傛い蹇撴濡垶鏌i幇闈涘闁稿﹥鍔欓弻锛勪沪閸撗€濮囬梺璇″灡濡啴寮幇鏉垮耿婵☆垵宕靛Σ妤呮⒑鐠囨彃顒㈡い鏃€鐗犲畷鎶筋敋閳ь剙鐣烽幋鐐电瘈闁搞儮鏅涚粊锕€鈹戦埥鍡楃仴闁稿鍔楁竟鏇㈠礂闂傚绠氬銈嗙墬缁海鏁☉娆嶄簻闊洦娲栭弸娑欐叏婵犲嫮甯涢柟宄版嚇閹崇偤濡疯閳ь剙锕娲閳哄啰肖缂備胶濮甸幑鍥偘椤旇法鐤€婵炴垶鐟﹀▍銏ゆ⒑鐠恒劌娅愰柟鍑ゆ嫹濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻橀弻锝夊箣閿濆棭妫勯梺鍝勵儎缁舵岸寮诲☉妯锋婵鐗婇弫楣冩⒑閸涘﹦鎳冪紒缁橈耿瀵鏁愭径濠勵吅闂佹寧绻傚Λ顓炍涢崟顖涒拺闁告繂瀚烽崕搴g磼閼搁潧鍝虹€殿喖顭烽幃銏ゅ礂鐏忔牗瀚介梺璇查叄濞佳勭珶婵犲伣锝夘敊閸撗咃紲闂佺粯鍔﹂崜娆撳礉閵堝棎浜滄い鎾跺Т閸樺鈧鍠栭…鐑藉极閹邦厼绶炲┑鐘插閺夊憡淇婇悙顏勨偓鏍暜婵犲洦鍊块柨鏇炲€哥壕鍧楁煙閹冾暢缁炬崘妫勯湁闁挎繂鎳忛幆鍫焊韫囨稒鈷戦柛娑樷看濞堟洖鈹戦悙璇у伐妞ゆ洩绲剧换婵嗩潩椤撶偘绨婚梻浣呵圭换鎰版儍閻戣棄绠┑鐘崇閻撶喖骞栧ǎ顒€濡芥繛鎳峰喚鐔嗛柣鐔峰簻瀹搞儵宕℃潏銊d簻闁哄倸鐏濋埛鏃傜棯閹规劖顥夐棁澶愭煥濠靛棙鍣洪柟顖氱墦瀹曨垶骞栨担鍏夋嫼闂佸憡绺块崕杈ㄧ墡闂備胶绮〃鍫熸叏閹绢噮鏁嬮柨婵嗘缁♀偓濠殿喗锕╅崕鐢稿煛閸涱喚鍘撻梺鍛婄箓鐎氼剟鍩€椤掆偓閹诧紕绮嬪鍛牚闁割偆鍟块幏娲⒑閸涘﹦鈽夐柨鏇缁骞樼紒妯衡偓鍨叏濮楀棗澧柛銈呮搐閳规垿顢欓悷棰佸闂傚倷绶氬ḿ褔鎮ч崱妞㈡稑鈽夐姀鐘插亶闂備緡鍓欑粔鐢稿煕閹达附鈷掗柛顐ゅ枙閸庢劗鎲搁悧鍫濈瑨缁炬儳娼″娲敆閳ь剛绮旈幘顔藉€块柛顭戝亖娴滄粓鏌熼崫鍕棞濞存粍鍎抽埞鎴︽偐椤愵澀澹曢梻鍌欑贰閸撴瑧绮旂€靛摜涓嶉柡灞诲劜閻撳繘鐓崶銊︾鐞氥儱鈹戦埄鍐ㄧ祷闁绘鎹囧濠氬即閿涘嫮鏉搁梺鍝勬川閸婎偊濮€閵堝棛鍘鹃梺鍝勵槼濞夋洘绂掗姀銈嗙厓閻熸瑥瀚悘鎾煕閳瑰灝鍔︾€规洖宕灃闁告剬鍕枙婵犵绱曢崑鎴﹀磹閺嵮€鏋栭柨鏇炲€搁悙濠冦亜椤撶喎鐏︽い銉ヮ樀閺岋絾鎯旈敍鍕殯闂佺ǹ閰f禍鎯版婵炴潙鍚嬪ḿ娆撴偂閺囥垺鐓欓悗鐢登瑰暩缂佺偓鍎抽妶鎼佸箖濡ゅ懏鏅查幖绮光偓鑼跺焻闂備胶枪缁ㄦ椽宕曢悽绋胯摕婵炴垶鐟﹂崕鐔兼煏韫囨洖孝妞ゎ偄娴风槐鎾存媴娴犲鎽甸柣銏╁灣閸嬨倝鐛箛娑欏亹閻犲洩灏欓宀勬⒑閸︻厼鍔嬮柟绋款煼椤㈡瑩骞掗幋鏃€鏂€闂佺粯蓱椤旀牠寮冲⿰鍛<閺夊牄鍔嶇粈瀣偓娈垮櫘閸嬪棝骞忛悩缁樺殤妞ゆ帊鐒﹂鏇㈡⒒娴h櫣甯涙慨濠傤煼閸╂盯宕奸妷銉︾€悗骞垮劚濡瑩宕h箛鏂剧箚妞ゆ牗鍝庢禒鎺楁煕濮樼厧浜伴柡灞稿墲瀵板嫮鈧綆鍋勯埀顒佸姈閹便劍绻濋崟顓炵闂佺懓鍢查幊妯虹暦椤愶箑唯闁挎棃鏁崑鎾活敊鐏忔牗鏂€闂佹枼鏅涢崯銊︾閻樼粯鐓曢柡鍌氭健閸欏嫭顨ラ悙鑼闁逞屽墾缂嶅棝宕伴弽顓熷珔闁绘柨鍚嬮悡蹇擃熆鐠鸿櫣澧曢柛鏂诲€濋弻銊モ槈濞嗘垶鍒涘┑顔硷龚濞咃綁骞夐幘顔肩妞ゆ劑鍊ゅΣ鐗堜繆閻愵亜鈧牕鈻旈敃鍌氱倞鐟滃繘藝閵娾晜鈷戦梺顐ゅ仜閼活垱鏅堕幘顔界厵妞ゆ梻鍘уΣ缁橆殰椤忓啫宓嗙€规洘锕㈤幃娆擃敄閼恒儳鈧即姊虹拠鎻掝劉妞ゆ梹鐗犲畷鏉课旈崨顓犵暫闂佺ǹ鏈崙褰掑吹閺囩喆浜滈柡鍥殔娴滈箖鎮楃憴鍕闁靛牊鎮傞獮鍐閵堝懍绱堕梺鍛婃处閸嬪懏娼忛崼銉︹拻闁稿本鑹鹃埀顒傚厴閹虫宕滄担绋跨亰濡炪倖鐗楅銏犆洪鍕敤濡炪倖鎸鹃崑鐔兼晬濞嗘挻鈷戦梻鍫氭櫅閻︽粓鏌涘Ο缁樺€愮€规洘鍨块獮姗€骞囨担鐟板厞闂備胶绮崝锕傚礈濞嗘搩鏁傞柨鐕傛嫹
开发学院数据库DB2 DB2 9.5 SQL Procedure Developer 认证考试 735 准... 阅读

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

 2010-10-01 16:36:58 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄧ粯銇勯幒瀣仾闁靛洤瀚伴獮鍥敍濮f寧鎹囬弻鐔哥瑹閸喖顬堝銈庡亝缁挸鐣烽崡鐐嶆棃鍩€椤掑嫮宓佸┑鐘插绾句粙鏌涚仦鎹愬闁逞屽墰閹虫捇锝炲┑瀣╅柍杞拌兌閻ゅ懐绱撴担鍓插剱妞ゆ垶鐟╁畷銉р偓锝庡枟閻撴洘銇勯幇闈涗簼缂佽埖姘ㄧ槐鎾诲礃閳哄倻顦板┑顔硷工椤嘲鐣烽幒鎴旀瀻闁规惌鍘借ⅵ濠电姷鏁告慨顓㈠磻閹剧粯鈷戞い鎺嗗亾缂佸鏁婚獮鍡涙倷閸濆嫮顔愬┑鐑囩秵閸撴瑦淇婇懖鈺冪<闁归偊鍙庡▓婊堟煛鐏炵硶鍋撻幇浣告倯闁硅偐琛ラ埀顒冨皺閺佹牕鈹戦悙鏉戠仸闁圭ǹ鎽滅划鏃堟偨缁嬭锕傛煕閺囥劌鐏犻柛鎰ㄥ亾婵$偑鍊栭崝锕€顭块埀顒佺箾瀹€濠侀偗婵﹨娅g槐鎺懳熺拠鑼舵暱闂備胶枪濞寸兘寮拠宸殨濠电姵纰嶉弲鎻掝熆鐠虹尨宸ョ€规挸妫濆铏圭磼濡搫顫嶇紓浣风劍閹稿啿鐣烽幋锕€绠婚悹鍥у级瀹撳秴顪冮妶鍡樺鞍缂佸鍨剁粋宥夋倷椤掍礁寮垮┑鈽嗗灣閸樠勭妤e啯鍊垫慨妯煎亾鐎氾拷闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄥジ鏌熼惂鍝ョМ闁哄矉缍侀、姗€鎮欓幖顓燁棧闂備線娼уΛ娆戞暜閹烘缍栨繝闈涱儐閺呮煡鏌涘☉鍗炲妞ゃ儲鑹鹃埞鎴炲箠闁稿﹥顨嗛幈銊╂倻閽樺锛涘┑鐐村灍閹崇偤宕堕浣镐缓缂備礁顑嗙€笛囨倵椤掑嫭鈷戦柣鐔告緲閳锋梻绱掗鍛仸鐎规洘鍨块獮鍥偋閸垹骞嶇紓鍌氬€烽悞锕傛晪缂備焦銇嗛崶銊у帗閻熸粍绮撳畷婊堟晝閸屾氨鐓戦梺鍛婂姦閻撳牆岣块弽顓熺厱婵犻潧妫楅悵鏃傛喐閺傝法鏆﹂柟顖炲亰濡茬偓绻涚€电ǹ孝闁靛牏枪椤繘鎼圭憴鍕彴闂佽偐鈷堥崜娑㈩敊婢舵劖鈷戦柣鎾虫捣缁夎櫣绱掗悩宕囧⒌妤犵偛鍟妶锝夊礃閳轰讲鍋撴繝姘參婵☆垯璀﹀Σ濂告煙閼恒儲绀嬫慨濠冩そ濡啫鈽夋潏顭戔偓鍡樼節绾版ǚ鍋撻搹顐㈡灎閻庤娲忛崹浠嬪箖娴犲宸濆┑鐐靛亾鐎氬ジ姊洪懡銈呮瀾闁荤喆鍎抽埀顒佹皑閸忔ê鐣烽婵堢杸婵炴垶鐟ч崢閬嶆⒑缂佹◤顏嗗椤撶喐娅犻柣銏犳啞閻撳繘鏌涢埄鍐炬當闁逞屽墮濠€杈╃磽閹惧顩烽悗锝庝簻缁愭稒绻濋悽闈浶㈤悗姘煎墴閻涱噣宕奸妷锔规嫼缂佺虎鍘奸幊搴ㄋ夊澶嬬厵婵炶尪顔婄花鑺ヤ繆閸欏濮嶇€殿喗鎸抽幃銏ゅ传閸曘劌褰忛梻鍌氬€搁崐鎼佸磹妞嬪孩顐芥慨姗嗗厳缂傛氨鎲稿鍥у疾闂備線娼ч悧鍡椕洪悩璇茬;闁圭偓鍓氬ḿ鈺傘亜閹扳晛鐏╃紒渚囧櫍濮婅櫣绱掑Ο鍦箒闂侀潻缍囩紞渚€鎮伴鈧獮鎺楀箠閾忣偅顥堥柛鈹惧亾濡炪倖甯掗崐缁樼▔瀹ュ鐓ユ繝闈涙椤ョ姷绱掗埦鈧崑鎾绘⒒閸屾艾鈧悂鎮ф繝鍕煓闁硅揪绠戝Ч鍙夌箾閸℃璐╅柣鐔稿閸亪鏌涢鐘茬伄闁哄棭鍋婂娲传閸曨厾鍔圭紓鍌氱С閻掞箓骞堥妸鈺佺劦妞ゆ帒瀚悡鍐煙椤栨粌顣肩痪顓犲亾缁绘繈鍩€椤掍焦缍囬柕濞у懎楠勯梻浣告惈濞层劑宕伴幘璺哄К闁逞屽墮閳规垿顢欓弬銈勭返闂佸憡锕㈢粻鏍х暦閵忋倖鍋ㄩ柛娑樑堥幏铏圭磽閸屾瑧鍔嶉柨姘攽椤曞棛鐣甸柡灞剧洴楠炴﹢寮堕幋婵囨嚈闂備浇顕栭崰妤勬懌濠电偟鍘х换妯讳繆閹间礁围闁搞儮鏅濋弳浼存⒒閸屾瑧顦︽繝鈧潏鈺佸灊妞ゆ牗绮嶉弳婊堟煟閹邦剛鎽犳繛鍛У缁绘盯骞嬮悙瀵告缂佺偓宕橀崑鎰閹惧瓨濯撮悹鎰靛灣缁辨澘鈹戦悙鏉戠祷妞ゆ洦鍙冮崺鈧い鎺戝枤濞兼劖绻涢崣澶屽ⅹ闁伙絿鍏橀、妤呭礃椤忓啰鑳洪梻鍌氬€风粈渚€骞夐敓鐘茬闁哄洢鍨归悿顕€鏌eΟ娆惧殭缂佲偓閸喓绡€闂傚牊绋撴晶娑氣偓瑙勬礀瀵墎鎹㈠☉銏犵闁绘劑鍔庣槐浼存⒑閸濆嫭顥滄俊顐n殜閸╃偤骞嬮敂钘変汗闁哄鐗滈崑鍕储閿熺姵鈷戦弶鐐村閸斿秹鏌eΔ浣虹煂婵″弶鍔欓獮妯尖偓娑櫭鎾寸箾鐎电ǹ孝妞ゆ垵鎳橀獮妤呮偨閸涘ň鎷洪梺闈╁瘜閸樹粙宕甸埀顒€鈹戦悙鑼勾闁稿﹥绻堥獮鍐┿偅閸愨晛鈧鏌﹀Ο渚Ш妞ゆ柨锕铏规喆閸曨剙鍓归梺鍛娒肩划娆忕暦閹剧粯鍋ㄩ柛娑樑堥幏娲⒑閼姐倕鏋戞繝銏★耿楠炲啯绗熼埀顒勫蓟閿濆绠抽柣鎰暩閺嗐倝姊虹拠鈥虫灍妞ゃ劌锕悰顕€寮介妸锕€顎撻梺绋跨箰椤︽壆鈧俺妫勯埞鎴︽倷閼搁潧娑х紓浣瑰絻濞尖€崇暦閺囥垹围濠㈣泛锕ら幆鐐烘⒑闁偛鑻晶瀛樻叏婵犲啯銇濇鐐寸墵閹瑥霉鐎n亙澹曢梺鍝勭▉閸樹粙宕戠€n喗鐓熸俊顖氱仢閸氬湱鈧鎸风欢姘舵偂椤愶箑鐐婇柕濞р偓婵洭姊洪崫鍕櫤闁诡喖鍊垮濠氬Ω閳哄倸浜為梺绋挎湰缁嬫垿顢旈敓锟�婵犵數濮烽弫鍛婃叏閻戣棄鏋侀柛娑橈攻閸欏繘鏌i幋锝嗩棄闁哄绶氶弻娑樷槈濮楀牊鏁鹃梺鍛婄懃缁绘﹢寮婚敐澶婄闁挎繂妫Λ鍕⒑閸濆嫷鍎庣紒鑸靛哺瀵鈽夊Ο閿嬵潔濠殿喗顨呴悧濠囧极妤e啯鈷戦柛娑橈功閹冲啰绱掔紒妯虹伌濠碉紕鏁诲畷鐔碱敍濮橀硸鍟嬮梻浣告啞椤ㄥ牓宕戦悢鍝ヮ浄闁兼祴鏅濈壕钘壝归敐鍛儓妞ゅ骸鐭傞弻娑㈠Ω閵壯冪厽閻庢鍠涢褔鍩ユ径鎰潊闁绘ḿ鏁搁弶鎼佹⒒閸屾艾鈧悂鎮ф繝鍕煓闁圭儤顨嗛崐鍫曟煕椤愮姴鍔滈柛濠勬暬閺岋綁鎮㈤崫鍕垫毉闂佸摜鍠撻崑鐔烘閹烘梹瀚氶柟缁樺笚濞堢粯绻濈喊澶岀?闁轰浇顕ч悾鐑芥偄绾拌鲸鏅┑顔斤耿绾悂宕€n喗鈷戦悹鍥ㄧ叀閸欏嫭绻涙担鍐叉搐缁犵儤绻濇繝鍌滃闁稿鏅涢埞鎴﹀磼濮橆厼鏆堥梺鎶芥敱閸ㄥ綊鎯€椤忓牜鏁囬柣鎰綑椤庢稑鈹戦悙鎻掓倯闁告梹鐗滈幑銏犫槈閵忊€虫濡炪倖宸婚崑鎾绘煛鐎n亜顒㈤柕鍥у椤㈡洟濮€閵忋埄鍞虹紓鍌欐祰妞村摜鏁幒鏇犱航闂備礁鍚嬬粊鎾疾濠婂牆鍚圭€光偓閸曨兘鎷绘繛鎾村焹閸嬫捇鏌嶈閸撴盯宕戝☉銏″殣妞ゆ牗绋掑▍鐘炽亜閺冨洤浜归柡鍡楁閺屻劌鈹戦崱娆忣暫闂佸憡鏌ㄩ悘姘跺Φ閸曨垱鏅滈柣锝呰嫰瀵劑姊虹拠鈥虫珯缂佺粯绻冩穱濠囨嚋闂堟稓绐為柣搴秵閸撴瑧鏁ィ鍐┾拻濞达絿枪椤ュ繘鏌涚€n亝鍣介柟骞垮灲瀹曟﹢顢欓懖鈺嬬幢婵$偑鍊曠换鎰板箠閹邦喚涓嶉柛鎾椻偓閸嬫捇鎮烽弶娆炬闂佸摜濮靛ú婊堟嚍鏉堛劎绡€婵﹩鍓涢悾楣冩⒑缂佹ɑ鐓ラ柛姘儔閸╂盯骞嬮敂钘夆偓鐢告煕閿旇骞栭弽锟犳⒑闂堟稒顥滈柛鐔告尦瀵濡舵径濠勵槰闂佽偐鈷堥崜娆撴偂閻斿吋鍊甸悷娆忓缁€鍐磼鐠囪尙澧︾€殿噮鍋婂畷姗€顢欓懖鈺佸Е婵$偑鍊栫敮鎺斺偓姘€鍥х劦妞ゆ帊鐒﹂ˉ鍫⑩偓瑙勬礃閿曘垽銆佸▎鎾冲簥濠㈣鍨板ú锕傛偂閺囥垺鐓冮柍杞扮閺嬨倖绻涢崼鐕傝€块柡宀嬬秮閹垻绮欓崹顕呮綒婵犳鍠栭敃銉ヮ渻娴犲绠栭柍鈺佸暞閸庣喖鏌嶉埡浣告殲闁伙讣缍佸缁樻媴閾忕懓绗¢梺缁橆殕濞茬喐淇婇崜浣虹煓閻犳亽鍔嶅▓楣冩⒑缂佹ê鐏﹀畝锝堟硶瀵囧焵椤掑嫭鈷戦柟鑲╁仜閸斺偓闂佸憡鍔戦崝搴ㄥΧ椤曗偓濮婂宕掑▎鎴犵崲濠电偘鍖犻崟鍨啍闂婎偄娲﹀ú姗€锝為弴銏$厸闁搞儯鍎遍悘鈺呮煕鐏炶濡介柕鍥у缁犳盯骞樼捄渚澑闂備焦濞婇弨閬嶅垂閸ф钃熼柣鏂垮悑閸ゅ啴鏌嶆潪鐗堫樂缂侇喖鐖煎娲川婵犲啠鎷瑰銈冨妼閿曨亜顕f繝姘櫢闁绘ɑ褰冪粣娑橆渻閵堝棙顥堥柡渚囧枟閹便劑宕堕埡鍐紳婵炶揪绲挎灙闁逞屽墮濠€閬嶅极椤曗偓閹垺淇婇幘铏窛闁逞屽墴濞佳囧箺濠婂懎顥氬┑鍌溓圭痪褔鏌涢锝団槈濠德ゅ亹缁辨帒螖娴d警鏆$紓浣虹帛閻╊垶骞冮埄鍐╁劅闁挎繂娴傞崯瀣⒒娴h櫣銆婇柡鍌欑窔瀹曟粌鈹戠€n亞顔嗛梺鍛婄☉閻°劑鎮¢妷鈺傚€甸柨婵嗘噽娴犳稓绱撳鍡╂疁婵﹤顭峰畷鎺戭潩椤戣棄浜剧€瑰嫭鍣磋ぐ鎺戠倞鐟滄粌霉閺嶎厽鐓忓┑鐐靛亾濞呭棝鏌涙繝鍌涘仴闁哄被鍔戝鎾倷濞村浜鹃柛婵勫劤娑撳秹鏌$仦璇插姕闁绘挻娲熼弻鏇熷緞濡儤鐏堟繝鈷€灞芥珝闁哄矉绱曢埀顒婄岛閺呮繄绮i弮鍫熺厸鐎光偓閳ь剟宕伴弽褏鏆︽繝濠傛-濡查箖鏌i姀鈺佺仭闁烩晩鍨跺濠氭晸閻樻彃绐涘銈嗘濡嫰鍩€椤掍礁濮嶉柡宀嬬磿娴狅妇鎷犻幓鎺濇綆闂備浇顕栭崰鎾诲磹濠靛棛鏆﹂柟鐑樺灍濡插牊鎱ㄥΔ鈧Λ鏃傛閿燂拷闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閹冣挃闁硅櫕鎹囬垾鏃堝礃椤忎礁浜鹃柨婵嗙凹缁ㄧ粯銇勯幒瀣仾闁靛洤瀚伴獮鍥敍濮f寧鎹囬弻鐔哥瑹閸喖顬堝銈庡亝缁挸鐣烽崡鐐嶆棃鍩€椤掑嫮宓佸┑鐘插绾句粙鏌涚仦鎹愬闁逞屽墰閹虫捇锝炲┑瀣╅柍杞拌兌閻ゅ懐绱撴担鍓插剱妞ゆ垶鐟╁畷銉р偓锝庡枟閻撴洘銇勯幇闈涗簼缂佽埖姘ㄧ槐鎾诲礃閳哄倻顦板┑顔硷工椤嘲鐣烽幒鎴旀瀻闁规惌鍘借ⅵ濠电姷鏁告慨顓㈠磻閹剧粯鈷戞い鎺嗗亾缂佸鏁婚獮鍡涙倷閸濆嫮顔愬┑鐑囩秵閸撴瑦淇婇懖鈺冪<闁归偊鍙庡▓婊堟煛鐏炵硶鍋撻幇浣告倯闁硅偐琛ラ埀顒冨皺閺佹牕鈹戦悙鏉戠仸闁圭ǹ鎽滅划鏃堟偨缁嬭锕傛煕閺囥劌鐏犻柛鎰ㄥ亾婵$偑鍊栭崝锕€顭块埀顒佺箾瀹€濠侀偗婵﹨娅g槐鎺懳熺拠鑼舵暱闂備胶枪濞寸兘寮拠宸殨濠电姵纰嶉弲鎻掝熆鐠虹尨宸ョ€规挸妫濆铏圭磼濡搫顫嶇紓浣风劍閹稿啿鐣烽幋锕€绠婚悹鍥у级瀹撳秴顪冮妶鍡樺鞍缂佸鍨剁粋宥夋倷椤掍礁寮垮┑鈽嗗灣閸樠勭妤e啯鍊垫慨妯煎亾鐎氾拷  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鏁愭径濠勵吅闂佹寧绻傞幉娑㈠箻缂佹ḿ鍘遍梺闈涚墕閹冲酣顢旈銏$厸閻忕偠顕ч埀顒佺箓閻g兘顢曢敃鈧敮闂佹寧妫佹慨銈夋儊鎼粹檧鏀介柣鎰▕閸ょ喎鈹戦鈧ḿ褔锝炲┑瀣╃憸搴綖閺囥垺鐓欓柟瑙勫姦閸ゆ瑧鐥幆褍鎮戠紒缁樼洴瀹曞崬螣閾忓湱鎳嗛梻浣告啞閿曨偆妲愰弴鐘愁潟闁规儳顕悷褰掓煕閵夋垵瀚ぐ顖炴⒒娴h鍋犻柛鏂跨焸閹儵宕楅梻瀵哥畾闂佸湱铏庨崰鏍矆閸愨斂浜滈柡鍐ㄥ€哥敮鍓佺磼閹邦厾娲存慨濠冩そ瀹曨偊宕熼崹顐嵮囨⒑閹肩偛濡肩紓宥咃工閻g兘濮€閻樺棙妞介、鏃堝川椤撴稑浜鹃柛顭戝亽濞堜粙鏌i幇顖氱毢濞寸姰鍨介弻娑㈠籍閳ь剛鍠婂澶娢﹂柛鏇ㄥ灡閺呮粓鎮归崶顏勭毢濞寸姵鎮傞幃妤冩喆閸曨剛鈹涚紓浣虹帛缁诲牓鎮伴鑺ュ劅闁靛⿵绠戝▓鐔兼⒑闂堟冻绱¢柛鎰╁妼椤╊剟姊婚崒姘偓鎼併偑閹绢喖纾婚柛鏇ㄥ€嬪ú顏呮櫇闁逞屽墰閸欏懘姊洪崫鍕犻柛鏂垮閺呭爼鏁撻悩鏂ユ嫽闂佺ǹ鏈悷锔剧矈閻楀牄浜滈柡鍥ф閹冲宕戦幘璇插瀭妞ゆ劑鍨虹拠鐐烘倵鐟欏嫭绀冪紒顔芥崌楠炲啴濮€閿涘嫰妾繝銏f硾椤戝洨绮欐笟鈧缁樻媴閻熸澘濮㈢紓浣虹帛閸旀洟鏁冮姀鈩冪秶闁宠桨绶″Λ婊堟⒑缁嬭法绠绘俊顐ユ硶閹广垽宕卞Ο闀愮盎闂佸搫绉查崝搴ㄣ€傞弻銉︾厵妞ゆ牗姘ㄦ晶娑㈡煏閸パ冾伃妞ゃ垺娲熸慨鈧柕蹇嬪灩婵鲸绻濆▓鍨灈闁挎洏鍎遍—鍐寠婢跺本娈鹃梺缁樺灩閻℃棃寮崶銊х闁瑰鍋熼幊鍐煟濠靛鎲炬慨濠勭帛閹峰懘宕ㄩ棃娑氱Ш妞ゃ垺鐗犲畷銊╊敇閸ャ劎鈽夐柍瑙勫灩閳ь剨缍嗘禍鐐烘偩妤e啯鈷戦梺顐ゅ仜閼活垱鏅堕鐐寸厪闁搞儜鍐句紓缂備胶濮甸惄顖炵嵁濡皷鍋撻崹顐e仩闁稿鍔栫换婵堝枈濡椿娼戦梺鎼炲妽婢瑰棝鍩€椤掍胶顣叉繝銏★耿閿濈偠绠涢幘浣规そ椤㈡棃宕熼鍡欏€為梻鍌欑閹测€趁洪敃鍌氱婵ǹ娉涚粻顖炴煕濡ゅ啫浜归柡鈧禒瀣厽闁归偊鍘肩徊鑽ょ磼閻欐瑥鍟伴弳鍡涙煥濠靛棙鍣洪柛瀣ㄥ劜椤ㄣ儵鎮欓弶鎴犱紝婵犳鍠掗崑鎾绘⒑缂佹﹫渚涢柛瀣嚇瀵剟鍩€椤掆偓閳规垿鎮╅崹顐f瘎婵犳鍠栭顓㈠焵椤掍礁鍤柛锝忕到椤曪綁宕奸弴鐐殿啇婵炶揪绲介崢婊堝箯濞差亝鈷戦柛娑橈功缁犳捇鎮楀鐓庡箹妞ゆ柨绻愰埞鎴﹀幢韫囨梹鏉告俊鐐€栧褰掑磿閹惰棄鍌ㄩ柟缁㈠枟閻撴瑦銇勯弮鍥跺殭鐎规挸妫楅埞鎴︽晬閸曨偄骞嬮梺绯曟櫔缁绘繂鐣烽幒鎳虫梹鎷呴崜韫床婵犵數濮烽弫鎼佸磻閻樿绠垫い蹇撴缁躲倕霉閻樺樊鍎忕紒鐘侯潐閵囧嫰骞囬埡浣插亾閺嶎厼姹叉繝濠傜墛閸嬶綁寮堕悙鏉戭€滄い鎺斿枛閺岋綁寮幐搴&闂佸搫鐭夌紞渚€骞冮姀鐘垫殝闁规鍠氬▔鍧楁⒒娴e鈧偓闁稿鎹囬弻銈嗘叏閹邦兘鍋撳Δ鍐棜濠靛倸鎲¢悡鏇㈡倶閻愰潧浜鹃柣銊﹀灩閳ь剚绋掔换鍌濈亙濠德板€曢敃锝囪姳閻戣姤鐓曟俊銈傚亾闁哥喎娼¢幃楣冩倻閼恒儱浜楅柟鍏兼儗閸犳宕撻悽鍛娾拺闁圭ǹ娴风粻鎾绘煙閸愯尙校缂佹梻鍠栧鎾閳锯偓閹锋椽姊洪崨濠勭畵閻庢凹鍓熷鍐测枎閹惧鍘藉┑掳鍊愰崑鎾翠繆椤愶絿銆掗柛鎺撳浮瀹曞ジ濡烽妷褜妲伴梻浣哥-閹虫捇濡靛Ο鑹板С濠电姵纰嶉ˉ濠冦亜閹扳晛鐏柟鍏煎姈缁绘稓鈧數枪閸樻挳鎸婂┑瀣叆闁哄洦顨呮禍楣冩⒒閸パ屾Ч缂佺粯绻冪换婵嬪磼濠婂啠鍙¢梻浣风串缁叉儳顪冩禒瀣摕闁挎稑瀚▽顏堟偣閸ャ劌绲绘い顒€鐗撳铏光偓鍦濞兼劙鏌涢妸銉т虎闁伙絿鍏樺畷锟犳倷閳哄偆娼旈梻浣烘嚀閸氣偓缂佲偓娴e湱顩查柣鎰靛厸缁诲棝鏌曢崼婵嗏偓鍛婄閹屾富闁靛牆楠稿銊╂煕鎼粹槅鐓肩弧鎾炽€掑锝呬壕闂佸搫鏈惄顖炲箖閳轰胶鏆﹂柛銉戔偓閹风増绻濋悽闈浶涢柛瀣尭閵嗘帒顫濋敐鍛婵犳鍠栭敃銊モ枍閿濆洦顫曢柟鐑樺殾閻旂厧鍗抽柣鏃堫棑娴煎矂姊虹拠鈥虫灓闁稿繑蓱娣囧﹪鎮块锝喰ラ梻浣呵归鍡涘箰閹间緤缍栨繝闈涱儐閸嬪倿骞栧ǎ顒€鐏ù婊冨⒔缁辨捇宕掑▎鎴g獥闂佸摜濮靛銊╁礆閹烘鏁嶉柣鎰棘瑜旈弻銊モ攽閸♀晜笑缂備讲鍋撻柛鎰靛枟閻撳啴鏌涘┑鍡楊仼闁哄棙鐟﹂〃銉╂倷閼碱剙顤€婵烇絽娲ら敃顏堝箖濞嗘搩鏁傞柛鏇樺妼娴滈箖鏌″搴″箹缂佲偓婢舵劖鐓欓弶鍫濆⒔閻h京鐥幆褏绉洪柡宀嬬節瀹曞爼濡烽妷褌鎮i梻浣告啞閸ㄨ绻涢埀顒侇殽閻愬澧懣鎰亜閹哄棗浜炬繝纰樷偓鑼煓闁哄矉缍侀獮妯兼崉閻戞ḿ浜梻浣虹帛閹尖晠宕戞繝鍌滄殾闁诡垶鍋婂銊╂⒑缁嬪潡顎楃紒缁橈耿瀵鈽夐姀鐘电潉闂侀€炲苯澧伴柛鎺撳浮楠炴ḿ鎷犻懠鑸垫啺闂備礁鎼ú銏ゅ垂瑜版帗鍊峰┑鐘插閸犳劗鈧箍鍎遍ˇ浠嬪极閸屾稏浜滈柟鎹愭硾琚ラ梺绋款儐閹告悂鍩㈤幘璇插瀭妞ゆ梻鏅禍鑸电節閻㈤潧浠滈柛姘儔閹兘濡搁埡鍌氣偓鍫曟煙閻戞﹩娈曢柍閿嬪灴閺屾稑鈽夊鍫濆缂備胶濮甸幑鍥箖濡も偓椤繈鎮℃惔鈾€鎷ゆ俊鐐€戦崐鏇㈠磹閸︻厽宕叉繝闈涚墕閺嬪牆顭跨捄铏圭伇闁挎稓鍠栧铏圭矙濞嗘儳鍓遍梺鎼炲妼閻忔繈鎮鹃悜钘夌疀闁哄娉曢娲⒑閹稿孩纾甸柛瀣崌閺屾盯濡搁妷銉㈠亾閸︻厽宕叉繛鎴烇供閸熷懏銇勯弮鍥у惞闁告垵缍婂铏圭矙濞嗘儳鍔€缂備胶绮换鍫濐嚕鐠囧樊鍚嬪璺猴梗缁卞爼姊洪崨濠冨闁告挻鐟ラ埢宥夋晲閸モ晝锛濇繛杈剧到閹碱偅鐗庨梻浣虹帛椤ㄥ牊绻涢埀顒傗偓娈垮枦椤曆囶敇閸忕厧绶炲┑鐘插楠炴劕鈹戦悙鑸靛涧缂佽弓绮欓獮澶愬灳閺傘儲鐏侀梺鍝勮閸庢煡鍩涢幋鐘电<閻庯綆鍋勯婊堟煙閻у摜绉柡灞剧洴閹晛鐣烽崶褉鎷伴柣搴㈩問閸犳牠鈥﹀畡閭﹀殨闁圭虎鍠栭~鍛存煟濮椻偓濞佳囧焵椤掑倸浠遍柟顔煎槻楗即宕橀顖樺€濋弻銈嗐偊閸ф鎽电紓浣虹帛缁诲倿锝炲┑瀣垫晣闁绘ɑ褰冪粻銉╂⒒閸屾瑧顦﹂柟璇х節瀹曞綊顢涢悙鑼紮闂佸搫绋侀崑鈧柛瀣尭椤繈鎮欓鈧锟�
核心提示:开始之前关于本系列这六个 DB2 SQL Procedure Developer 教程讨论 SQL Procedural Language 的所有基本构造和方法,讲解如何在存储过程、UDF 和触发器中使用 SQL Procedural Language,DB2 9.5 SQL Procedure Developer 认

开始之前

关于本系列

这六个 DB2 SQL Procedure Developer 教程讨论 SQL Procedural Language 的所有基本构造和方法,讲解如何在存储过程、UDF 和触发器中使用 SQL Procedural Language,包括错误处理和部署。还讨论一些 DB2 9.5 高级特性,比如乐观锁、层次化查询和声明的全局临时表。本系列讨论如何调用存储过程、UDF 和触发器,以及如何在过程和函数之间共享数据。它介绍 DB2 开发工具,包括 IBM Data Studio。这些教程为您准备考试的每个部分提供坚实的基础。但是,您不应该仅仅依靠这些教程准备考试。

关于本教程

本教程深入讲解 UDF,重点讨论 SQL 函数。这是共分六部分的系列中的第三个教程,本系列帮助您准备 IBM DB2 9.5 SQL Procedure Developer 认证考试(考试 735)。

目标

在完成本教程之后,您应该能够:

掌握函数的正确使用方法

使用 CREATE FUNCTION 语句创建 SQL 函数

掌握 SQL 函数体的正确结构

从 SQL 函数返回值和表

调用函数

前提条件

要想参加 DB2 9.5 SQL Procedure Developer 考试,您必须先通过 DB2 9 基础(730 考试)。可以使用 "DB2 9 基础" 教程系列准备此考试。

本教程是为初级和中级 DB2 程序员撰写的。您应该基本了解关系数据库的工作方式以及数据库和数据库编程构造。此外,还应该熟悉 DB2 Command Line Processor (CLP) 的使用方法,了解 SQL 的基本知识。

系统需求

要想运行本教程中的示例,需要访问 DB2 9.5 数据库服务器和 DB2 提供的 SAMPLE 数据库。(可以通过 DB2 Command Line Processor 执行命令 db2sampl 来创建 SAMPLE 数据库)。

什么是函数?

在 DB2 中,函数是一组封装的指令,用来执行一个特定的操作;可以使用一个或多个输入参数来定制操作,可以使用一个或多个输出参数来返回结果。有四种函数类型:

标量函数

聚合函数

表函数

行函数

DB2 提供许多健壮的内置函数,这些函数在 SYSIBM 模式中定义。可用的内置函数包括标量函数(比如 UCASE())、聚合函数(比如 AVG())、操作符函数(比如 “+”)和转换函数(比如 DECIMAL())。通常在查询的选择列表和 FROM 子句中调用函数。

标量函数

标量函数 是返回一个标量值的函数。可以使用标量函数执行简单任务,也可以在标量函数中使用通过函数输入参数提供的值进行复杂的数学计算。标量函数的示例包括内置函数 LENGTH() 和 SUBSTR()。

在 SQL 语句中支持表达式的任何地方都可以引用标量函数。当在查询谓词中使用时,标量函数可以改进总体性能,因为函数的逻辑作为引用它的 SQL 语句的组成部分在服务器上直接执行。另外,当在服务器上对一组候选行应用标量函数时,它可以起到过滤器的作用,限制必须返回给客户机的行数。但是,标量函数也有其局限性。例如,根据设计,标量函数只能返回一个值,无法返回多个值和结果集。另外,在标量函数中不支持事务管理。因此,在标量函数体中无法执行提交和回滚操作。

标量函数通常用来执行基本的数学计算和操作字符串。

聚合函数

聚合函数(也称为列函数)也返回一个标量值,这个值是一组输入值的计算结果。通常情况下,这组输入值来自表中的一列,或来自 VALUES 子句中的元组。聚合函数的示例包括内置函数 MAX() 和 MIN()。

表函数

表函数 向引用它的 SQL 语句返回一个表。只能在 SELECT 语句的 FROM 子句中引用表函数。但是,在能够应用于只读视图的任何操作(例如,联结、分组操作以及 UNION 和 INTERSECT 等集操作)中,都可以使用表函数返回的表。

表函数可以发出操作系统调用、从文件中读取数据以及通过网络访问数据。另外,SQL 表函数还可以用来封装修改表数据的 SQL 语句。(外部表函数不能封装 SQL 语句)。但是,与标量函数一样,在表函数中不支持事务管理。因此,在表函数体中无法执行提交和回滚操作。

表函数通常用来封装复杂但常用的子查询,以及为非关系数据提供表格式接口。例如,用户定义的外部表函数可以读取电子表格并生成一个数据表,然后可以把生成的数据表直接插入基表或者通过查询访问它。

行函数

行函数 返回单一表行。行函数只能供用户定义的结构化类型使用;不能单独使用行函数,也不能在抽象数据类型的上下文之外的 SQL 语句中使用。

通常,行函数用于把结构化类型属性映射到由内置数据类型值组成的行,以便能够在查询或 SQL 操作中访问结构化类型属性。例如,假设数据库有一个用户定义的结构化数据类型 'Manager',此类型扩展另一个结构化数据类型 'Employee',其中包含 'Employee' 和 'Manager' 特有的属性。如果希望在查询中引用属性值,那么可以创建一个行函数,它把属性值转换为查询可以引用的数据行。

用户定义的函数

UDF 是用来扩展和增强 DB2 内置函数提供的功能的特殊对象。顾名思义,UDF 是由具有适当权力和/或特权的数据库用户创建的。与 DB2 内置函数不同,UDF 可以使用系统调用和 DB2 的管理 API,因此能够在系统、应用程序和数据库之间进行更多的协作。可以创建五种 UDF:

有源(或模板)

SQL 标量、表或行

外部标量

外部表

OLE DB 外部表

通过执行 CREATE FUNCTION SQL 语句创建(或重新创建)UDF。这个语句有几种形式,应该使用的形式由要创建的函数的类型决定。

有源(或模板)函数

有源函数是从一个已经向数据库注册的函数(称为源函数)构造出的 UDF。有源函数在本质上可以是标量、列或表函数,还可以用它们覆盖 +、-、* 和 / 等操作符。在调用有源函数时,传递给它的所有参数被转换为底层源函数所需的数据类型,然后执行源函数本身。执行完成时,源函数对产生的结果执行必要的转换,并把控制返回给调用 UDF 的 SQL 语句。有源函数最常见的用途是,让用户定义的不同数据类型有选择地继承内置数据类型的某些语义。

通常,如果以现有函数作为源的 UDF 的目的是向用户定义数据类型提供该函数的支持,那么 UDF 和有源函数使用相同的名称。这使用户能够用一个用户定义的不同类型调用相同的函数,而不需要额外的函数定义。一般情况下,多个函数可以使用相同的函数名,只要每个函数的签名都有些差异即可。

用来创建有源函数的 CREATE FUNCTION 语句形式的基本语法如下:

清单 1. 用来创建有源函数的 CREATE FUNCTION 语句

 CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
  RETURNS [OutputDataType]
  <SPECIFIC [SpecificName]>
  SOURCE [SourceFunction] <([DataType] ,...)>
  <AS TEMPLATE>

其中:

FunctionName 指定要创建的有源函数的名称。

ParameterName 指定一个或多个函数参数的名称。

InputDataType 指定 ParameterName 所识别的参数所需的数据类型。

OutputDataType 指定函数返回的数据的类型。

SpecificName 指定分配给这个 UDF 的特定名称。这个名称可以用来引用或删除函数;但是,不能用来调用函数。

SourceFunction 指定用来创建这个有源函数的现有函数。

DataType 指定现有函数的每个参数期望接收的数据类型。

在使用这种形式的 CREATE FUNCTION 语句时,如果指定了 SPECIFIC 子句,就会给创建的 UDF 分配一个惟一的名称。创建函数之后,可以通过在特殊形式的 DROP SQL 语句 (DROP SPECIFIC FUNCTION [SpecificName]) 中引用这个特定名称来删除函数。但是,如果不给 UDF 分配特定名称,那么必须在 DROP FUNCTION 语句中提供函数名和函数的签名(即放在圆括号中的所有函数参数的数据类型列表)。

如果指定 AS TEMPLATE 子句,那么会生成一个函数模板。函数模板是一个不完整的函数,它定义了要返回的数据类型,但是不包含可执行代码。在联邦系统中,函数模板被映射到一个数据源(例如 Oracle 或 SQL Server)函数,这样就可以从联邦数据库调用数据源函数。只能在指定为联邦服务器的数据库服务器上注册函数模板。

因此,如果基于内置数据类型 INTEGER 创建了一个名为 YEAR 的数据类型,希望创建一个有源函数 AVG(),它应该接收并返回 YEAR 值,而且它基于内置函数 AVG()(此函数接收并返回 INTEGER 值),那么可以执行下面的 CREATE FUNCTION 语句:

 CREATE FUNCTION AVG(YEAR) RETURNS YEAR
  SOURCE SYSIBM.AVG(INTEGER)

SQL 函数

SQL 函数是只使用过程式 SQL 语句构造的 UDF。SQL 函数可以是标量函数,也可以返回一行或整个表。

用来创建 SQL 函数的 CREATE FUNCTION 语句形式的基本语法如下:

清单 2. 用来创建 SQL 函数的 CREATE FUNCTION 语句

 CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
  RETURNS [[OutputDataType] |
    TABLE ( [ColumnName] [ColumnDataType] ,... ) |
    ROW ( [ColumnName] [ColumnDataType] ,... )]
  <SPECIFIC [SpecificName]>
  <LANGUAGE SQL>
  <DETERMINISTIC | NOT DETERMINISTIC>
  <EXTERNAL ACTION | NO EXTERNAL ACTION>
  <CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA>  
  <STATIC DISPATCH>  
  <CALLED ON NULL INPUT>    
  [SQLStatements] | RETURN [ReturnStatement]   

其中:

FunctionName 指定要创建的 SQL 函数的名称。

ParameterName 指定一个或多个函数参数的名称。

InputDataType 指定 ParameterName 所识别的参数所需的数据类型。

OutputDataType 指定函数返回的数据的类型。

ColumnName 指定函数返回的一列或多列的名称(如果此函数返回表或行的话)。

ColumnDataType 指定 ColumnName 所识别的列返回的数据类型。

SpecificName 指定分配给这个 UDF 的特定名称。这个名称可以用来引用或删除函数;但是,不能用来调用函数。

SQLStatements 指定在调用函数时执行的一个或多个 SQL 语句。这些语句组合成一个动态复合 SQL 语句。

ReturnStatement 指定用于返回调用函数的应用程序的 RETURN SQL 语句。(如果 SQL 函数体由动态复合语句组成,那么它必须包含至少一个 RETURN 语句;在调用函数时,必须执行一个 RETURN 语句。如果函数是表函数或行函数,那么只能包含一个 RETURN 语句,而且此语句必须是使用的最后一个语句)。

可以看到,这种形式的 CREATE FUNCTION 语句包含几个在前一种形式中没有出现的子句。在许多情况下,这些子句传达的信息不太直观,所以我们先详细讨论这些子句,然后再看一个示例。

<LANGUAGE SQL> 指定函数是用 SQL 编写的。

<DETERMINISTIC | NOT DETERMINISTIC> 表示在用相同的参数值调用函数时,函数是否总是返回相同的标量值、表或行(DETERMINISTIC 代表确定性函数,NOT DETERMINISTIC 表示非确定性函数)。如果没有指定这两个子句,那么在用相同的参数值调用函数时函数可能返回不同的结果。

<EXTERNAL ACTION | NO EXTERNAL ACTION> 表示函数执行的操作是否会改变不由 DB2 管理的对象的状态(EXTERNAL ACTION 表示会改变,NO EXTERNAL ACTION 表示不改变)。外部操作包括发送电子邮件或在外部文件中写记录等。如果没有指定这两个子句,那么意味着函数可能执行某种外部操作。

<CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA> 表示在 UDF 体中编写的 SQL 语句的类型。有三个值可用:

CONTAINS SQL:UDF 体包含的可执行 SQL 语句既不读数据,也不修改数据。

READS SQL DATA:UDF 体包含的可执行 SQL 语句读数据,但是不修改数据。

MODIFIES SQL DATA:UDF 体包含的可执行 SQL 语句既可以读数据,也可以修改数据。

<STATIC DISPATCH> 表示在函数解析时 DB2 根据函数参数的静态类型(声明的类型)选择函数。

<CALLED ON NULL INPUT> 表示无论任何参数是否包含 null 值,都调用此函数。

因此,如果希望创建一个名为 JULIAN_DATE() 的标量 SQL 函数,用于将 DB2 日期转换为儒略日期(自公元前 4713 年 1 月 1 日以来的天数),那么可以执行下面的 CREATE FUNCTION 语句:

清单 3. 标量 SQL 函数

 CREATE FUNCTION julian_date(in_date DATE)
  RETURNS CHAR(7)
  LANGUAGE SQL
  RETURN RTRIM(CHAR(YEAR(in_date))) ||
   SUBSTR(DIGITS(DAYOFYEAR(in_date)), 8)    

外部标量函数

外部标量函数是用 C、C++ 或 Java™ 等高级编程语言编写的返回单一值的函数。创建和实现有源函数或 SQL 函数的过程非常简单,但创建和使用外部标量函数(或任何外部函数)的过程就复杂多了。要想创建任何外部函数,必须执行以下步骤:

使用支持的高级编程语言编写 UDF 体。

编译 UDF。

链接 UDF 以创建库(或动态链接库)。

调试 UDF 并重复第 2 到第 4 步,直到解决所有问题。

把包含 UDF 的库存储在服务器工作站上。另外,必须修改包含 UDF 的库文件的系统权限,让所有用户都可以执行它。例如,在 UNIX 环境中,使用 chmod 命令让一个文件可由所有用户执行;在 Windows 环境中,使用 attrib 完成此任务。

使用适当形式的 CREATE FUNCTION SQL 语句向 DB2 数据库注册 UDF。

完成这些步骤之后,就可以按照使用任何标量函数或表函数的方式使用生成的 UDF。

一定要注意一点:因为外部标量函数是用高级编程语言编写的,而不是 SQL,所以提供给函数参数的每个值必须由 SQL 数据类型转换为适当的高级编程语言数据类型,然后才能使用。(如果函数的参数之一需要用户定义的数据类型,那么应该先把参数值转换为适当的内置数据类型,然后再传递给外部函数)。同样,函数返回的任何值必须由高级编程语言数据类型转换为适当的 SQL 数据类型,然后才能返回它。另外,如果在外部函数中动态地分配了内存,那么应该在函数返回之前释放内存。

用来注册(已经按以上说明创建的)外部标量函数的 CREATE FUNCTION 语句形式的基本语法如下:

清单 4. 用来注册外部标量函数的 CREATE FUNCTION 语句

 CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
  RETURNS [OutputDataType]
  <SPECIFIC [SpecificName]>
  EXTERNAL <NAME [ExternalName] | [Identifier]>  
  LANGUAGE [C | JAVA | CLR | OLE]
  PARAMETER STYLE [DB2GENERAL | JAVA | SQL]
  <DETERMINISTIC | NOT DETERMINISTIC>
  <FENCED | NOT FENCED>
  <RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT>
  <NO SQL | CONTAINS SQL | READS SQL DATA>  
  <STATIC DISPATCH>  
  <EXTERNAL ACTION | NO EXTERNAL ACTION>
  <SCRATCHPAD <[100 | [SPSize]]> | NO SCRATCHPAD>  
  <DBINFO | NO DBINFO>  

其中:

FunctionName 指定要创建的外部标量函数的名称。

ParameterName 指定一个或多个函数参数的名称。

InputDataType 指定 ParameterName 所识别的参数所需的数据类型。

OutputDataType 指定函数返回的数据的类型。

SpecificName 指定分配给这个 UDF 的特定名称。这个名称可以用来引用或删除函数;但是,不能用来调用函数。

ExternalName 指定包含要注册的外部函数的可执行代码的库和函数。(稍后详细讨论这个名称的构造方式)。

Identifier 指定包含要注册的外部函数的可执行代码的库,但是这只适用于用 C 或 C++ 编写的函数。DB2 Database Manager 会寻找与库同名的函数。

SPSize 指定用作暂存(scratchpad)区域的内存量(以字节为单位)。

可以看到,这种形式的 CREATE FUNCTION 语句包含几个前面没有出现过的子句。同样,在许多情况下,这些子句传达的信息不太直观,所以我们先详细讨论这些新子句,然后再看一个示例。

EXTERNAL <NAME [ExternalName] | [Identifier]> 子句指定两个信息:包含要注册的 UDF 的可执行代码的库,以及库中的函数。用来编写外部 UDF 体的高级编程语言决定如何提供这两个名称。例如,如果外部 UDF 是用 C 或 C++ 编程语言开发的,那么可以以四种方式指定包含函数体的库和函数:

'LibraryName'

'LibraryName ! FunctionName'

'AbsolutePath'

'AbsolutePath ! FunctionName'

如果提供库名而不是绝对路径,那么 DB2 会在 /sqllib/function 和 /sqllib/function/unfenced 子目录中寻找指定的库名。(在 Windows 操作系统上,DB2 会在 LIBPATH 或 PATH 环境变量指定的目录路径中寻找函数)。另一方面,如果提供了绝对路径,DB2 就在指定的位置寻找库。(如果既没有提供库名,也没有提供绝对路径,DB2 就会在默认子目录中寻找与要注册的 UDF 同名的库和函数)。如果提供了函数名,DB2 就会在指定的库中寻找指定的函数名;如果没有提供函数名,DB2 就会寻找与指定的库同名的函数。

LANGUAGE [C | JAVA | CLR | OLE] 子句用来指定 UDF 体遵守的高级编程语言约定。有四个值可用:

C:DB2 按照处理 C 函数的方式调用 UDF。(这个 UDF 必须遵守由标准 ANSI C 定义的 C 语言调用和链接约定)。

JAVA:DB2 按照处理 Java 类中的方法的方式调用 UDF。

CLR:DB2 按照处理 .NET 类中的方法的方式调用 UDF。(目前,只对在 Windows 操作系统上运行的 UDF 支持 LANGUAGE CLR)。

OLE:DB2 按照处理 OLE 自动化对象公开的方法的方式调用 UDF。(这个 UDF 必须遵守 OLE Automation Programmer's Reference 中描述的 OLE 自动化数据类型和调用机制)。

PARAMETER STYLE [DB2GENERAL | JAVA | SQL] 子句指定执行调用的应用程序在向 UDF 传递值时应该采用的参数传递方式。有三种参数传递方式:

DB2GENERAL:按照调用 Java 方法的调用约定传递和返回值。(只能对用 Java 编写的外部 UDF 使用此方式)。

JAVA:按照符合 Java 语言和 SQL 规范的调用约定传递和返回值。(只能对用 Java 编写的外部 UDF 使用此方式)。

SQL:按照符合 C 语言调用和链接约定、OLE 自动化对象公开的方法或 .NET 对象的公共静态方法的调用约定传递和返回值。(只能对用 C/C++、OLE 或 .NET 编写的外部 UDF 使用此方式)。

<FENCED | NOT FENCED> 子句指定外部 UDF 是否足够 “可靠”,可以在 DB2 Database Manager 操作环境的进程/内存空间中运行(NOT FENCED 表示可以,FENCED 表示不可以)。如果指定 FENCED 子句(或这两个子句都未指定),那么 DB2 Database Manager 就不允许函数访问它的内部资源。

<NO SQL | CONTAINS SQL | READS SQL DATA> 子句指定在外部 UDF 体中编写的 SQL 语句的类型。有三个值可用:

NO SQL:外部 UDF 体不包含任何 SQL,或者包含不可执行的 SQL 语句。(不可执行的 SQL 语句包括 INCLUDE 和 WHENEVER 语句等)。

CONTAINS SQL:UDF 体包含的可执行 SQL 语句既不读数据,也不修改数据。

READS SQL DATA:UDF 体包含的可执行 SQL 语句读数据,但是不修改数据。

<SCRATCHPAD <[100 | [SPSize]]> | NO SCRATCHPAD> 子句指定是否为 UDF 分配作为持久存储区域的内存(SCRATCHPAD 表示分配,NO SCRATCHPAD 表示不分配)。如果指定了 SCRATCHPAD 子句,DB2 就会在首次调用此函数时分配适当数量的内存。在创建和填充暂存区域之后,会在各次函数调用之间保留它的内容 —— UDF 在一次调用中对暂存区域所做的任何修改都会保留到下一次调用。

<DBINFO | NO DBINFO> 子句表示在调用函数时是否把 DB2 掌握的信息作为额外参数传递给 UDF(DBINFO 表示传递,NO DBINFO 表示不传递)。如果指定了 DBINFO 子句,那么 DB2 会传递一个数据结构,其中包含的信息包括当前连接的数据库的名称、应用程序运行时授权 ID、调用此函数的数据库服务器的版本、发布版本和修订级别以及服务器使用的操作系统。

因此,如果希望注册一个名为 CENTER() 的外部标量函数,它接受两个值(一个 INTEGER 值和一个 DOUBLE 值)并返回一个 DOUBLE 值,它存储在 /home/db2inst1/myfuncs 目录中的 “double” 库中,那么可以执行下面的 CREATE FUNCTION 语句:

清单 5. 外部标量函数

 CREATE FUNCTION center(INT, DOUBLE)
  RETURNS DOUBLE
  EXTERNAL NAME '/home/db2inst1/myfuncs/double'
  LANGUAGE C
  PARAMETER STYLE SQL
  DETERMINISTIC
  NO SQL

外部表函数

与外部标量函数一样,外部表函数是用高级编程语言编写的。外部标量函数返回一个标量值,而外部表函数在每次调用时返回一个数据集。外部表函数的强大之处在于,它们能够让几乎任何数据源看起来像是 DB2 基表。另外,在联结操作、分组操作、集操作(例如 UNION)和能够应用于只读视图的任何其他操作中,都可以使用外部表函数返回的数据集。

用来注册外部表函数的 CREATE FUNCTION 语句形式的基本语法如下:

清单 6. 用来注册外部表函数的 CREATE FUNCTION 语句

 CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
  RETURNS TABLE ( [ColumnName] [ColumnDataType] ,... )
  <SPECIFIC [SpecificName]>
  EXTERNAL <NAME [ExternalName] | [Identifier]>  
  LANGUAGE [C | JAVA | CLR | OLE]
  PARAMETER STYLE [DB2GENERAL | SQL]
  <DETERMINISTIC | NOT DETERMINISTIC>
  <FENCED | NOT FENCED>
  <RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT>
  <NO SQL | CONTAINS SQL | READS SQL DATA>  
  <STATIC DISPATCH>  
  <EXTERNAL ACTION | NO EXTERNAL ACTION>
  <SCRATCHPAD <[100 | [SPSize]]> | NO SCRATCHPAD>  
  <DBINFO | NO DBINFO> 

其中:

FunctionName 指定要创建的外部表函数的名称。

ParameterName 指定一个或多个函数参数的名称。

InputDataType 指定 ParameterName 所识别的参数所需的数据类型。

ColumnName 指定函数返回的一列或多列的名称。

ColumnDataType 指定 ColumnName 所识??的列返回的数据类型。

SpecificName 指定分配给这个 UDF 的特定名称。这个名称可以用来引用或删除函数;但是,不能用来调用函数。

ExternalName 指定包含要注册的外部函数的可执行代码的库和函数。

Identifier 指定包含要注册的外部函数的可执行代码的库,但是这只适用于用 C 或 C++ 编写的函数。DB2 Database Manager 会寻找与库同名的函数。

SPSize 指定用作 scratchpad 区域的内存量(以字节为单位)。

因此,如果希望注册一个名为 EMPDATA() 的外部表函数,它接受两个长度可变的字符串值,返回一个包含职员信息的数据集(信息取自一个 ASCII 文件),它存储在 /home/db2inst1/myfuncs 目录中的 “EMPDATA” 库中,那么可以执行下面的 CREATE FUNCTION 语句:

清单 7. 外部表函数

 CREATE FUNCTION empdata (VARCHAR(30), VARCHAR(255))
  RETURNS TABLE (empid INT, lname CHAR(20), fname CHAR(20))
  EXTERNAL NAME '/home/db2inst1/myfuncs/EMPDATA'
  LANGUAGE C
  PARAMETER STYLE SQL
  DETERMINISTIC
  NOT FENCED  
  NO SQL
  NO EXTERNAL ACTION

OLE DB 外部表函数

Microsoft OLE DB 是一组应用程序编程接口 (API),用于访问各种数据源。数据源由数据本身、相关联的数据库管理系统 (DBMS)、运行 DBMS 的平台以及用来访问此平台的网络组成。OLE DB 可以为 OLE Component Object Model (COM) 环境中的所有数据源类型提供访问。

除了 CLI/ODBC 提供的功能之外,OLE DB 定义的接口还可以访问无法通过 SQL 访问的数据。OLE DB 通过定义一组标准接口来促进应用程序集成,这些接口包含与语义相关的函数,应用程序可以通过这些函数访问其他应用程序的服务。接口是用于组件-对象交互的二进制标准,每个接口包含一组函数,它们为实现接口的对象(提供者)和使用接口的客户机(消费者)之间的交互定义一个 “合同”。有两类 OLE DB 提供者:OLE DB 数据提供者,它们本身拥有数据并以行集的形式公开表格式的数据;OLE DB 服务提供者,它们本身不拥有数据,而是通过 OLE DB 接口产生和消费数据来封装某些服务。

与外部表函数一样,外部 OLE DB 表函数是用高级编程语言编写的。但是,对于 OLE DB 表函数,可以使用一个通用的内置 OLE DB 消费者访问任何 OLE DB 提供者来访问数据;只需注册一个 OLE DB 表函数并作为数据源引用适当的 OLE DB 提供者。不需要编写额外的代码。与外部表函数一样,在联结操作、分组操作、集操作(例如 UNION)和能够应用于只读视图的任何其他操作中,都可以使用外部 OLE DB 表函数返回的表。例如,可以定义一个 OLE DB 表函数,它返回来自 Microsoft Access 数据库或 Microsoft Exchange 地址簿的表;然后创建一个报告,报告无缝地组合来自这个 OLE DB 表和 DB2 数据库的数据。

一定要注意一点:要想对 DB2 数据库使用 OLE DB 表函数,必须安装 OLE DB 2.0 或更高版本,这可以从 Microsoft 获得。关于系统需求和特定数据源可用的 OLE DB 提供者的更多信息,请查阅数据源的文档。

用来注册 OLE DB 外部表函数的 CREATE FUNCTION 语句形式的基本语法见清单 8。

清单 8. 用来注册 OLE DB 外部表函数的 CREATE FUNCTION 语句

 CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
  RETURNS TABLE ( [ColumnName] [ColumnDataType] ,... )
  <SPECIFIC [SpecificName]>
  EXTERNAL <NAME [ExternalName]>  
  LANGUAGE OLEDB
  <DETERMINISTIC | NOT DETERMINISTIC>
  <RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT> 
  <EXTERNAL ACTION | NO EXTERNAL ACTION>
  <CARDINALITY [NumRows]>  

其中:

FunctionName 指定要创建的 OLE DB 外部表函数的名称。

ParameterName 指定一个或多个函数参数的名称。

InputDataType 指定 ParameterName 所识别的参数所需的数据类型。

ColumnName 指定函数返回的一列或多列的名称。

ColumnDataType 指定 ColumnName 所识别的列返回的数据类型。

SpecificName 指定分配给这个 UDF 的特定名称。这个名称可以用来引用或删除函数;但是,不能用来调用函数。

ExternalName 为要注册的函数指定引用的外部表和 OLE DB 提供者。指定外部表和 OLE DB 提供者的语法如下:

 '[Server]!<Rowset>' 

 '!<Rowset>![ConnectString] <!COLLATING_SEQUENCE = [N | Y]>' 

其中:

Server 指定由 CREATE SERVER SQL 语句定义的数据源的本地名称。

Rowset 指定 OLE DB 提供者公开的行集(表)。

ConnectString 指定一个连接字符串,其中包含通过 OLE DB 提供者连接数据源所需的初始化属性。此字符串由一系列关键字=值 对组成,与 CLI/ODBC 函数 SQLDriverConnect() 使用的连接字符串相似。

注意:<!COLLATING_SEQUENCE = [N | Y]> 子句指定是否使用与 DB2 相同的比较次序访问数据源。

NumRows 指定函数返回的行数的估计值。(此值只用于优化)。

因此,如果希望注册一个名为 ORDERS() 的 OLE DB 外部表函数,从一个 Microsoft Access 数据库获取订单信息,那么可以执行清单 9 所示的 CREATE FUNCTION 语句:

清单 9. OLE DB 外部表函数

 CREATE FUNCTION orders()
  RETURNS TABLE (orderid   INTEGER,
          customerid  CHAR(5),
          employeeid  INTEGER,
          orderdate  TIMESTAMP,
          requiredate TIMESTAMP,
          shipdate   TIMESTAMP,
          shipcharges DECIMAL(19,4))
  LANGUAGE OLEDB
  EXTERNAL NAME '!orders!Provider=Microsoft.Jet.OLEDB.3.51;
    Data Source=c:sqllibsamplesoledbnwind.mdb'

SQL 函数的结构

在前面,您已经看到 SQL 函数由以下部分组成:

函数名

一系列参数声明(如果有参数的话)

函数返回值的声明

一个或多个函数选项

函数体

图 1 给出用来定义每个部分的 CREATE FUNCTION 语句元素。

图 1. SQL 函数的结构

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

每个 SQL 函数的定义以关键字 “CREATE FUNCTION” 开头,然后是函数名(在 图 1 中由 CREATE FUNCTION 语句中的第一项表示)。完全限定的函数名加上所有参数的名称和基本数据类型,就构成了函数签名。在同一个数据库模式中,不能有两个函数签名完全相同的函数。

接下来是参数声明(在 图 1 中由第二项表示)。可以在这里定义在调用函数时用来传递数据的一个或多个变量。(函数也可以没有参数)。

在参数声明后面,必须指定函数将返回的信息的种类(在 图 1 中由第三项表示)。SQL 函数可以返回任何内置数据类型,但是 LONG VARCHAR、LONG VARGRAPHIC 和 XML 除外。它们还可以返回表或单一行。

接下来,指定函数的属性(在 图 1 中由第四项表示)。最重要的属性是用来编写函数体的语言,在这里就是 SQL。在这里可以指定的其他属性包括:在用相同的参数调用函数时函数是否总是返回相同的值(DETERMINISTIC),是否执行任何外部操作(EXTERNAL ACTION),数据访问级别(CONTAINS SQL、READS SQL DATA 或 MODIFIES SQL DATA)。

最后是函数体(在 图 1 中由第五项表示)。函数体可以是单一 SQL 语句,也可以是复合 SQL 语句。可以在函数体中使用的语句由函数的属性决定。表 1 列出在不同的数据访问级别上可以在 SQL 函数体中使用的 SQL 语句。(以粗体显示的 SQL 语句是 SQL PL 语句)。

表 1. 可以在 SQL 函数体中使用的 SQL 语句

SQL 语句CONTAINS SQLREADS SQL DATAMODIFIES SQL DATA
CALLYesYesYes
DELETENoNoYes
FOR Yes Yes Yes
GET DIAGNOSTICSYesYesYes
IF Yes Yes Yes
INSERTNoNoYes
ITERATE Yes Yes Yes
LEAVE Yes Yes Yes
MERGENoNoYes
SELECTNoYesYes
SET variableYesYesYes
SIGNALYesYesYes
VALUESNoYesYes
WHILE Yes Yes Yes

下面通过一些示例解释这个结构。

单语句 SQL 标量函数

顾名思义,单语句 SQL 函数的函数体只包含一个 SQL 语句。单语句 SQL 标量函数是返回一个标量值的单语句 SQL 函数。

图 2 给出的单语句 SQL 标量函数用来显示当前的月份名称。

图 2. 单语句 SQL 标量函数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 2 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.THIS_MONTH()。

函数的返回值,这是一个长度可变的字符串(VARCHAR),最大长度为 25 个字符。

分配给函数的惟一名称,在这里是 SQLFUNC.THIS_MONTH。如果在同一个数据库模式中有多个名称相同但签名不同的函数,这个惟一名称就非常有用。

指出用来编写函数体的语言是 SQL。

指出在用相同的参数调用时函数不一定总是返回相同的值。

指出函数不执行任何外部操作。

指出函数包含的 SQL 语句既不读数据也不修改数据。

函数体以及 RETURN 语句,此语句把控制返回给调用函数的用户或应用程序。在此示例中,函数体使用当前时间调用内置函数 MONTHNAME(),从而获得当前月份的名称。

图 3 给出一个单语句 SQL 标量函数,用于删除字符串前后的空格。此函数与 图 2 所示函数的不同之处是它接受一个输入参数值。

图 3. 单语句 SQL 标量函数,有一个输入参数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 3 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.STRIP_LTBLANKS()。

函数所需的输入参数,在这里是一个长度可变的字符串(VARCHAR),最大长度为 1024 个字符。

函数的返回值,这是一个长度可变的字符串(VARCHAR),最大长度为 1024 个字符。

分配给函数的惟一名称,在这里是 SQLFUNC.STRIP_LTBLANKS。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

函数体以及 RETURN 语句。在此示例中,函数体调用内置函数 LTRIM() 和 RTRIM(),从而删除字符串前后的空格。

单语句 SQL 表函数

单语句 SQL 表函数的函数体由一个 SQL 语句组成,它向引用它的 SQL 语句返回一个表。单语句 SQL 表函数与单语句 SQL 标量函数的差异是 RETURNS 子句的编写方式不同;并不声明要返回一个标量数据类型的值,而是定义作为函数结果的临时表的列。图 4 给出一个单语句 SQL 表函数,它返回的结果集包含男性职员的工资信息。

图 4. 单语句 SQL 表函数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 4 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.MALE_SALARIES()。

函数的返回值,这是一个包含职员编号、姓氏和工资信息的临时表。

分配给函数的惟一名称,在这里是 SQLFUNC.MALE_SALARIES。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

函数体以及 RETURN 语句,此语句把控制返回给调用函数的用户或应用程序。在此示例中,函数体是一个查询,它从 EMPLOYEE 表中获取所有男性职员的职员编号、姓氏和工资信息。

图 5 给出一个单语句 SQL 表函数,它返回的结果集包含工资高于指定工资的所有职员的工资信息。此函数与 图 4 所示函数的不同之处在于它接受一个输入参数值。

图 5. 单语句 SQL 表函数,有一个输入参数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 5 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.TOP_SALARIES()。

函数所需的输入参数,在这里是一个小数值(DECIMAL),其刻度为 9,精度为 2。

函数的返回值,这是一个包含职员编号、姓氏和工资信息的临时表。

分配给函数的惟一名称,在这里是 SQLFUNC.TOP_SALARIES。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

函数体以及 RETURN 语句。在此示例中,函数体是一个查询,它从 EMPLOYEE 表中获取工资高于指定的最低工资的所有职员的职员编号、姓氏和工资信息。

复合语句 SQL 标量函数

复合 SQL 语句是一种可以把多个 SQL 语句组合成一个可执行块的特殊机制。尽管复合语句中使用的每个 SQL 语句都可以单独执行,但是把它们组合在一起会减少处理它们所需的开销;DB2 把复合语句编译为单一 SQL 语句。复合 SQL 语句本身适合用来创建简短的脚本,执行控制流非常简单但数据流很大的小型逻辑工作单元。在 SQL 函数体中使用(与支持的 SQL PL 语句结合使用)时,可以执行更复杂的逻辑。图 6 给出一个 SQL 标量函数,其函数体包含一个复合 SQL 语句。此函数用于查明本月的最后一天是星期几。

图 6. 复合语句 SQL 标量函数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 6 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.LAST_DAY_OF_MONTH()。

函数的返回值,这是一个长度可变的字符串(VARCHAR),最大长度为 24 个字符。

分配给函数的惟一名称,在这里是 SQLFUNC.LAST_DAY_OF_MONTH。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

关键字 BEGIN ATOMIC,它表示一个复合 SQL 语句块的开头。

函数体,它由构成复合 SQL 语句块的几个 SQL 语句组成。

RETURN 语句,此语句把控制返回给调用函数的用户或应用程序。在此示例中,RETURN 语句使用在函数体中构造的一个日期字符串调用内置函数 DAYNAME() 并返回结果。

关键字 END,它表示一个复合 SQL 语句块结束。

图 7 给出一个复合语句 SQL 标量函数,它用于把华氏温度转换为摄氏温度。此函数与 图 6 所示函数的不同之处在于它接受一个输入参数值。

图 7. 复合语句 SQL 标量函数,有一个输入参数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 7 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.CONV_F_TO_C()。

函数所需的输入参数,在这里是一个单精度浮点值,它代表一个华氏温度值。

函数的返回值,在这里是一个单精度浮点值,它代表一个摄氏温度值。

分配给函数的惟一名称,在这里是 SQLFUNC.CONV_F_TO_C。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

关键字 BEGIN ATOMIC,它表示一个复合 SQL 语句块的开头。

函数体,它由构成复合 SQL 语句块的几个 SQL 语句组成。

RETURN 语句。在此示例中,RETURN 语句返回在函数体中生成的摄氏温度值。

关键字 END,它表示一个复合 SQL 语句块结束。

复合语句 SQL 表函数

复合语句 SQL 表函数的函数体由一个复合 SQL 语句组成,它向引用它的 SQL 语句返回一个表。与单语句 SQL 表函数一样,复合语句 SQL 表函数与 SQL 标量函数的差异是 RETURNS 子句的编写方式不同;并不声明要返回一个标量数据类型的值,而是定义作为函数结果的临时表的列。图 8 给出一个复合语句 SQL 表函数,它返回的结果集包含工资高于所有职员平均工资的所有职员的工资信息。

图 8. 复合语句 SQL 表函数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 8 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.TOP_SALARIES()。

函数的返回值,这是一个包含职员编号、姓氏和工资信息的临时表。

分配给函数的惟一名称,在这里是 SQLFUNC.TOP_SALARIES。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

关键字 BEGIN ATOMIC,它表示一个复合 SQL 语句块的开头。

函数体,它由构成复合 SQL 语句块的几个 SQL 语句组成。

RETURN 语句,此语句把控制返回给调用函数的用户或应用程序。在此示例中,RETURN 语句返回一个查询的结果,此查询从 EMPLOYEE 表中获取工资高于表中平均工资的所有职员的职员编号、姓氏和工资信息。

关键字 END,它表示一个复合 SQL 语句块结束。

图 9 给出一个复合语句 SQL 表函数,它返回的结果集包含在指定部门中工作的本月过生日的所有职员的信息。此函数与 图 8 所示函数的不同之处在于它接受一个输入参数值。

图 9. 复合语句 SQL 表函数,有一个输入参数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

组成 图 9 中的 CREATE FUNCTION 语句的元素如下:

函数名,即 SQLFUNC.BDAY_THIS_MONTH()。

函数所需的输入参数,在这里是一个长度可变的字符串(VARCHAR),最大长度为 3 个字符。

函数的返回值,这是一个包含职员编号、姓氏、部门和生日信息的临时表。

分配给函数的惟一名称,在这里是 SQLFUNC.BDAY_THIS_MONTH。

函数的属性,比如用来构造函数体的语言、在用相同的参数值调用时函数是否总是返回相同的值、函数是否执行任何外部操作以及所需的数据访问级别。

关键字 BEGIN ATOMIC,它表示一个复合 SQL 语句块的开头。

函数体,它由构成复合 SQL 语句块的几个 SQL 语句组成。

RETURN 语句。在此示例中,RETURN 语句返回一个查询的结果,此查询从 EMPLOYEE 表中获取在指定部门中工作的本月过生日的所有职员的职员编号、姓氏、部门和生日信息。

关键字 END,它表示一个复合 SQL 语句块结束。

SQL Procedural Language (SQL PL) 语句

SQL Procedural Language (SQL PL) 是在 DB2 Version 7 中引入的一组 SQL 语句,它们提供围绕传统 SQL 查询和操作实现控制流逻辑所需的过程式构造。在此之后,SQL PL 又有所改进,当前的 SQL PL 语句集和语言特性支持用 SQL 进行全面的高级编程。

SQL PL 的语法很简单,支持变量、条件语句、循环语句、控制转移语句、错误管理语句和结果集操作语句。另外,在复合语句 SQL 函数中可以使用 SQL PL 语句的一个子集。可以在复合语句 SQL 函数体中使用的 SQL PL 语句包括:

与变量相关的语句

DECLARE [Variable] DEFAULT [Value]

DECLARE [Condition]

SET (assignment-statement)

条件语句

IF

循环语句

FOR

WHILE

控制转移语句

CALL

ITERATE

LEAVE

RETURN

错误管理语句

SIGNAL

图 10 给出的复合语句 SQL 标量函数包含几个 SQL PL 语句。

图 10. 包含 SQL PL 语句的 SQL 标量函数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

在 图 10 所示 SQL 函数中使用的 SQL PL 语句如下:

DECLARE [Variable] 语句,用于创建将在函数体中使用的一个或多个局部变量。

SET 语句,用于给变量赋值。

一个用户定义的标签(名为 loop_label),在这里此标签与一个 WHILE 循环相关联,在 WHILE 循环中用来实现分支。

WHILE 语句,用于实现循环。

IF 语句,它与 ELSEIF 和 ELSE 语句结合使用以执行条件处理。

ITERATE 语句,用于转到指定的标签。

LEAVE 语句,用于跳出循环。

RETURN 语句,用于向调用函数的用户或应用程序返回一个标量值或结果值。

SQL 函数中的错误处理

在理想情况下,SQL 函数中的错误处理,它捕捉和处理在函数范围内可能发生的任何错误和/或警告,然后把错误的相关信息返回给调用函数的用户或应用程序。最容易的错误处理方法是使用 SIGNAL SQL 语句。此语句的基本语法如下:

 SIGNAL [Condition_Value]
  SET MESSAGE_TEXT = [Message]   

 SIGNAL SQLSTATE <VALUE> [SQLSTATE_Value]
  SET MESSAGE_TEXT = [Message]   

其中:

Condition_Value 表示在包含 SIGNAL 语句的复合语句中声明的一个条件。

SQLSTATE_Value 指定一个包含五个字符的字符串常量,它代表 SQLSTATE 值。

Message 指定一个最多 70 个字符的字符串,它描述遇到的错误或警告。

例如,图 11 给出一个复合语句 SQL 标量函数,它把一个 DECIMAL 值转换为 DATE 值,其中包含捕捉和处理错误的代码。在此函数中,为 SQLSTATE 22007 定义一个条件 —— 这个 SQLSTATE 值表示日期无效(由图 11 中的第一项表示),如果输入值是 0,就使用 SIGNAL 语句把警告或错误告知调用函数的用户或应用程序(由图 11 中的第二项表示)。

图 11. 包含流控制语句的 SQL 标量函数

DB2 9.5 SQL Procedure Developer 认证考试 735 准备,第 3 部分

调用 SQL 函数

调用 SQL 函数的方式在一定程度上取决于函数返回值的类型。如果函数是标量函数,就可以在 SELECT、VALUES 或 SET 语句中调用它。例如,可以通过执行下面的 VALUES 语句调用 图 3 所示的单语句 SQL 标量函数:

VALUES sqlfunc.strip_ltblanks(' This is a test. '),

在执行这个 VALUES 语句时,提供的字符串前后的空格被删除,返回 “This is a test” 值。

另一方面,如果函数是表函数,那么必须在 SELECT 语句的 FROM 子句中引用它。例如,可以通过执行下面的 SELECT 语句调用 图 9 所示的复合语句 SQL 表函数:

SELECT * FROM TABLE(sqlfunc.bday_this_month('A00'))

在执行这个 SELECT 语句时,返回一个结果集,其中包含在 'A00' 部门中工作的本月过生日的所有职员的职员编号、姓氏、部门和生日信息。

结束语

在本教程中,您学习了如何使用 UDF 扩展 DB2 提供的内置功能。还了解了四种可用的函数类型(标量、聚合、表和行)以及可以创建的五种 UDF 类型(有源、SQL、外部标量、外部表和 OLE DB 表)。还了解了 SQL 函数是只使用 SQL 构造的,根据定义方式不同,它们可以返回标量值、单一行或整个表。每个 SQL 函数由五个基本部分组成:

函数名

一系列参数声明(如果有参数的话)

函数返回值的声明

一个或多个函数选项

函数体

函数体可以是单一 SQL 语句,也可以是复合 SQL 语句。复合 SQL 语句是一种可以把多个 SQL 语句组合成一个可执行块的特殊机制;使用关键字 BEGIN ATOMIC 和 END 表示复合 SQL 语句块的开头和结尾。

在本教程中,还了解了 SQL 函数中的错误处理,它捕捉和处理在函数范围内可能发生的任何错误和/或警告,然后把错误的相关信息返回给调用函数的用户或应用程序。通常使用 SIGNAL SQL 语句实现错误处理。

如果函数是标量函数,就可以在 SELECT、VALUES 或 SET 语句中调用它;如果函数是表函数,那么必须在 SELECT 语句的 FROM 子句中引用它。您现在应该能够在任何 DB2 数据库环境中构造和部署 SQL 函数了。

Tags:DB SQL Procedure

编辑录入:爽爽 [复制链接] [打 印]
[]
  • 好
  • 好的评价 如果觉得好,就请您
      0%(0)
  • 差
  • 差的评价 如果觉得差,就请您
      0%(0)
更多精彩
    赞助商链接

    热点阅读
      焦点图片
        最新推荐
          精彩阅读