HelloWorld 善戰(zhàn)者,求之于勢(shì),不責(zé)于人;故能擇人而任勢(shì)。

          知止而后有定,定而后能靜,靜而后能安,安而后能慮,慮而后能得。物有本末,事有終始。知所先后,則近道矣。

            BlogJava :: 首頁(yè) ::  :: 聯(lián)系 ::  :: 管理 ::
            167 隨筆 :: 1 文章 :: 40 評(píng)論 :: 0 Trackbacks

          http://man.chinaunix.net/database/postgresql_8.0_CN/plpgsql-declarations.html
          創(chuàng)建plpgsql語(yǔ)言
          create language plpgsql;

          例子一

          CREATE OR REPLACE FUNCTION instr(character varying, integer)
                         RETURNS integer AS
          $BODY$
          declare
          str alias for $1;
          ind alias for $2;
          begin
          return ind+100;
          end;
          $BODY$
                         LANGUAGE 'plpgsql' VOLATILE;
          > select instr('aaa',100) ;
          > 200

          例子二
          如果一個(gè) PL/pgSQL 函數(shù)的返回類型聲明為一個(gè)多態(tài)類型 (anyelement 或者 anyarray),那么就會(huì)創(chuàng)建一個(gè)特殊的參數(shù), $0。它的數(shù)據(jù)類型是函數(shù)的實(shí)際返回類型,和從實(shí)際輸入類型推導(dǎo)推導(dǎo)類型一樣 (參閱 Section 31.2.5)。 這樣就允許函數(shù)訪問(wèn)它的實(shí)際返回類型,像 Section 35.4.2 里顯示的那樣。 $0 初始化為空,并且可以被函數(shù)修改,所以,如果需要,它可以用于保存返回值, 雖然這并非必須的。$0 還可以給予一個(gè)別名。比如,這個(gè)函數(shù)可以在任何有 + 操作符的數(shù)據(jù)類型上運(yùn)轉(zhuǎn):
          create or replace function addT (v1 anyelement, v2 anyelement, v3 anyelement)
          returns anyelement as $$
          declare
          res alias for $0;
          begin
          res := v1+v2+v3;
          return res;
          end;
          $$language plpgsql;
          > select addT(100,200,300)
          > 600

          例子三
          variable%TYPE

          %TYPE 提供一個(gè)變量或者表字段的數(shù)據(jù)類型。 你可以用這個(gè)聲明將要保存數(shù)據(jù)庫(kù)數(shù)值的變量。比如,假如你在 users 表里面有一個(gè)字段叫 user_id。要聲明一個(gè)和 users.user_id 類型相同的變量,你可以寫(xiě):

          user_id users.user_id%TYPE;

           

          通過(guò)使用 %TYPE,你必須知道你引用的結(jié)構(gòu)的數(shù)據(jù)類型, 并且,最重要的是,如果被引用項(xiàng)的數(shù)據(jù)類型在將來(lái)變化了(比如:你把 user_id 的類型從 integer 改成 real),你也不需要修改你的函數(shù)定義。

          %TYPE 對(duì)多態(tài)的函數(shù)特別有用,因?yàn)閮?nèi)部變量的數(shù)據(jù)類型可能在不同調(diào)用中是不一樣的。 我們可以通過(guò)給函數(shù)的參數(shù)或者結(jié)果占位符附加 %TYPE 的方法來(lái)創(chuàng)建合適的變量。

          例子四

          行類型
          name table_name%ROWTYPE;
          name composite_type_name;

           

          一個(gè)復(fù)合類型變量叫做變量(或者row-type變量)。 這樣的一個(gè)變量可以保存一次SELECT或者 FOR命令結(jié)果的完整一行,只要命令的字段集匹配該變量聲明的類型。 行數(shù)值的獨(dú)立的字段是使用常用的點(diǎn)表示法訪問(wèn)的,比如 rowvar.field

          一個(gè)行變量可以聲明為和一個(gè)現(xiàn)有的表或者視圖的行類型相同,方法是使用 table_name%ROWTYPE 表示法; 或者你也可以聲明它的類型是一個(gè)復(fù)合類型的名字。(因?yàn)槊總€(gè)表都有一個(gè)相關(guān)聯(lián)的同名數(shù)據(jù)類型, 在 PostgreSQL 里實(shí)在是無(wú)所謂你寫(xiě)不寫(xiě) %ROWTYPE。但是有 %ROWTYPE 的形式移植性更好。)

          函數(shù)的參數(shù)可以是復(fù)合類型(表的完整行)。這個(gè)時(shí)候, 對(duì)應(yīng)的標(biāo)識(shí)符 $n 將是一個(gè)行變量,并且可以從中選取字段,比如 $1.user_id

          在一個(gè)行類型的變量中,只可以訪問(wèn)用戶定義的表中行的屬性, 不包括 OID 或者其他系統(tǒng)屬性(因?yàn)樵撔锌赡軄?lái)自一個(gè)視圖)。 該行類型的數(shù)據(jù)域繼承表中象 char(n) 這種類型字段的尺寸和精度。

          這里是一個(gè)使用復(fù)合類型的例子:
          CREATE TABLE tbl_store1
          (
                     store_no integer NOT NULL DEFAULT nextval('tbl_store1_sq'::regclass),
                     parent_id integer,
                     "type" integer,
                     "values" real,
                     CONSTRAINT tbl_store1_pkey PRIMARY KEY (store_no)
          )
          插入植 1 1 1 1;

          CREATE OR REPLACE FUNCTION merge(t_row tbl_store1)
                     RETURNS text AS
          $BODY$
          declare
          t2_row tbl_store1%rowtype;
          begin
          select * into t2_row from tbl_store1 ;
          return t_row.values || t2_row.values;
          end;
          $BODY$
                     LANGUAGE 'plpgsql' VOLATILE;
          > select merge(t.*) from tbl_store1 t ;
          > 11

          例子五
          /**
          create or replace function logfun1(log text) returns timestamp as $$
          begin
          insert into tbl_store1 values(3,1,1,1,'now');
          return 'now';
          end;
          $$ language plpgsql;
          select logfun1('test');
          **/
          create or replace function logfun2(log text) returns timestamp as $$
          declare
          ctime timestamp;
          begin
          ctime :='now';
          insert into tbl_store1 values(6,2,1,1,ctime);
          return ctime;
          end;
          $$ language plpgsql;
          select logfun2('aaa');

          logfunc1() 的實(shí)例里, PostgreSQL 的主分析器在為 INSERT 準(zhǔn)備執(zhí)行計(jì)劃的時(shí)候知道字串 'now' 應(yīng)該解釋成 timestamp 類型,因?yàn)?logtable 的目標(biāo)字段就是該類型。所以,它會(huì)在這個(gè)時(shí)候從這個(gè)字串中計(jì)算一個(gè)常量, 然后在該服務(wù)器的整個(gè)生存期中的所有 logfunc1 調(diào)用中使用這個(gè)常量。不消說(shuō),這可不是程序員想要的。

          logfunc2里, PostgreSQL 的主分析器并不知道 now 應(yīng)該轉(zhuǎn)換成什么類型, 因此它返回一個(gè)包含字符串 now 的類型為 text 的數(shù)據(jù)值。 在隨后給局部變量curtime賦值時(shí), PL/pgSQL解釋器通過(guò)調(diào)用 text_outtimestamp_in 把這個(gè)字符串轉(zhuǎn)換成 timestamp 類型的變量。 因此,計(jì)算出的時(shí)戳就會(huì)按照程序員希望的那樣在每次執(zhí)行的時(shí)候都更新。

          記錄變量的易變性天性在這種結(jié)合上提出了一個(gè)問(wèn)題。 在一個(gè)記錄變量在語(yǔ)句或者表達(dá)式中使用時(shí), 該字段的數(shù)據(jù)類型在同一個(gè)表達(dá)式的不同調(diào)用期間不能修改, 因?yàn)樵摫磉_(dá)式準(zhǔn)備使用的是運(yùn)行第一次到達(dá)該表達(dá)式時(shí)出現(xiàn)的數(shù)據(jù)類型。 在寫(xiě)處理超過(guò)一個(gè)表的事件的觸發(fā)器過(guò)程的時(shí)候一定要把這個(gè)記住。(必要時(shí)可以用EXECUTE繞開(kāi)這個(gè)問(wèn)題。)

          例子六
          create or replace function tSInto () returns varchar as
          $$
          declare rec record;
          begin
          select into rec * from tbl_store1 where values =1;
          if not found then
          return 'test';
          else
          return 'tttt';
          end if;
          end;
          $$
          language plpgsql;
          select tSInto();

          create or replace function tSInto () returns varchar as
          $$
          declare rec record;
          begin
          select into rec * from tbl_store1 where values =1;
          if rec.values isNULL then
          return 'okkkkkkk';
          else return 'test';
          end if ;
          end;
          $$
          language plpgsql;
          select tSInto();
          例子七
          create or replace function cur1 () returns text as
          $$
          declare
          curs1 CURSOR for select * from tbl_store1;
          res text :='';
          a varchar;
          b varchar;
          c varchar;
          d varchar;
          e varchar;
          begin
          OPEN curs1;
          loop
          fetch curs1 into a,b,c,d,e;
          if not found then
          return 'error';
          exit;
          end if;
          res = 'test'||res;
          end loop;
          close curs1;
          return res;
          end;
          $$
          language plpgsql;

          CREATE OR REPLACE FUNCTION cur1()
              RETURNS text AS
          $BODY$
          declare
          curs1 CURSOR for select * from tbl_store1;
          res text :='';
          a varchar;
          b varchar;
          c varchar;
          d varchar;
          e varchar;
          begin
          OPEN curs1;
          loop
          fetch curs1 into a,b,c,d,e;
          if (found) then
          if (a is null) then
              a = '';
          end if ;
          if (b is null) then
              b = '';
          end if ;
          if (c is null) then
              c = '';
          end if ;
          if (d is null) then
              d = '';
          end if ;
          if (e is null) then
              e = '';
          end if ;
              res = res || a || b || c || d || e;
          else
          exit;
          end if;
          end loop;
          close curs1;
          return res;
          end;
          $BODY$
              LANGUAGE 'plpgsql' VOLATILE;
          select cur1();



          </script>

          posted on 2007-08-13 18:59 helloworld2008 閱讀(422) 評(píng)論(0)  編輯  收藏 所屬分類: SQL
          主站蜘蛛池模板: 萨嘎县| 时尚| 清远市| 邻水| 都安| 黄冈市| 贺兰县| 嘉黎县| 上蔡县| 平阳县| 正宁县| 井研县| 泰兴市| 洛浦县| 湖北省| 家居| 兰溪市| 尼玛县| 河北省| 太仓市| 大关县| 拜城县| 缙云县| 石狮市| 江安县| 万源市| 垫江县| 永胜县| 石棉县| 马尔康县| 宁强县| 新竹县| 金堂县| 洪湖市| 彰武县| 武威市| 惠来县| 宝清县| 宜兰市| 邹平县| 潞城市|