鷹翔宇空

          學習和生活

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks

          公告

          歡迎和大家成為朋友!
          歡迎和大家就任何技術進行交流!
          QQ:77542728
          MSN:hnlyhyq@hotmail.com
          Email:hnlyhyq@163.com

          常用鏈接

          留言簿(16)

          隨筆分類(107)

          隨筆檔案(109)

          文章分類(145)

          文章檔案(141)

          收藏夾(22)

          java

          javascript

          jdbc

          web

          其它

          開源項目

          我的好友

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          引自:http://bbs.chinaunix.net/viewthread.php?tid=643946

          在oracle中創建存儲過程和sybase及sql server下的語法有些不一致之處。

          下面就此用不同的數據庫下存儲過程的例子來演示之。

          ---------------------------
          oracle下:
          CREATE OR REPLACE FUNCTION MY_FUNC
          (
          P1 IN MY_TABLE.YY%TYPE,
          P2 IN MY_TABLE.NN%TYPE,
          P3 VARCHAR(100)
          )
          RETURN VARCHAR2 AS
          /*定義有參數的游標和無參數的游標*/
          CURSOR MY_CURSOR1 IS
              SELECT YY,NN,DECODE(FYYSDM,0,'合計',1,'加工費','其他費用要素')
              FROM MY_TABLE
              WHERE YY=P1
              GROUP BY YY,NN
              ORDER BY YY,NN;
          /*定義游標變量,存儲游標數據集中的記錄*/
          V_CURSOR1 MY_CURSOR1%ROWTYPE;

          CURSOR MY_CURSOR2(V_ZYDM MY_TABLE.ZYDM%TYPE,V_FYYSDM NUMBER) AS
              SELECT YY,NN,ZYDM,NVL(ZYCB,0) /*NVL函數轉換空值為指定值*/
              FROM MY_TABLE
              WHERE YY=P1 AND NN=P2 AND ZYDM=V_ZYDM AND FYYSDM=V_FYYSDM
              GROUP BY YY,NN;
          /*定義游標變量,存儲游標數據集中的記錄*/
          V_CURSOR2 MY_CURSOR2%ROWTYPE;

          V_CPDM  MY_TABLE.CPDM%TYPE;
          V_COUNT NUMBER;
          V_BZ    VARCHAR2(2);
          V_CPCB  NUMBER(22,2);

          BEGIN
              V_BZ:=1;
              SELECT CPDM INTO V_CPDM FROM MY_TABLE;
              SELECT CPCB INTO V_CPCB FROM MY_TABLE WHERE ROWNUM=1;
             
              IF MY_CURSOR1%ISOPEN THEN /*判斷游標是否已經打開*/
                  CLOSE MY_CURSOR1;
              END IF;
              OPEN MY_CURSOR1;
              FETCH MY_CURSOR1 INTO V_CURSOR1;
              IF MY_CURSOR1%NOTFOUND THEN /*游標返回結果為空*/
                  CLOSE MY_CURSOR1;
                     RETURN(V_BZ);
              END IF;
              WHILE MY_CURSOR1%FOUND LOOP /*游標返回結果不為空*/
                  V_CPDM:=V_CURSOR1.CPDM;
                  V_CPCB:=V_CURSOR1.CPCB;
                  V_COUNT:=100;
                  IF V_COUNT=100 THEN
                      V_COUNT:=99;
                  END IF;
                      FETCH MY_CURSOR1 INTO V_CURSOR1;
              END LOOP;
              CLOSE MY_CURSOR1;

              /*顯式打開帶參游標*/
              SELECT CPDM INTO V_CPDM FROM MY_TABLE;
              OPEN MY_CURSOR2;
              FETCH MY_CURSOR2 INTO V_CURSOR2;
              WHILE MY_CURSOR2%FOUND LOOP /*游標返回結果不為空*/
                  V_CPDM:=V_CURSOR2.CPDM;
                  V_CPCB:=V_CURSOR2.CPCB;
                  V_COUNT:=100;
                  IF V_COUNT=100 THEN
                      V_COUNT:=99;
                  ELSE
                      V_COUNT:=88;
                  END IF;
                      FETCH MY_CURSOR2 INTO V_CURSOR2;
              END LOOP;
              CLOSE MYCURSOR2;

              /*隱式打開游標*/
              FOR V_CURSOR2 IN MY_CURSOR2(V_CPDM,V_CURSOR1.FYYSDM) LOOP
                  IF V_CURSOR2.CPCB IS NULL THEN
                     PRINT '非法!';
                     ROLLBACK;
                  END IF;

                  UPDATE MY_TABLE
                  SET CPCB=V_CPCB
                  WHERE YY=P1 AND NN=P2 AND CPDM=V_CURSOR2.CPDM;
                  IF SQL%NOTFOUND THEN /*判斷前句是否有執行結果*/
                     /*程序段*/
                  END IF;
              END LOOP;
             
              V_BZ:=MY_DELETE_CB(P_YY,P_NN);
              IF V_BZ<>0 THEN
                  PRINT '失敗!';
              END IF;
              FOR I INT 1..V_COUNT LOOP
                  /**/
              END LOOP;

              COMMIT;/*提交事務*/
              RETURN(0);/*要有返回值*/
          END MY_FUNC;

          CREATE OR REPLACE PROCEDURE SP_MY
          (
          P_YY IN MY_TABLE.YY%TYPE;
          P_NN NUMBER;
          )
          IS

          CURSOR MY_CURSOR IS
              SELECT CPCB
              FROM MY_TABLE
              WHERE YY=P_YY AND NN=P_NN;

          V_ZYCB NUMBER(22,2);

          BEGIN
              /**/
              /*無返回值*/
          END;

          附oracle下函數:
          NVL(AAA,BBB)  空值判斷函數,AAA是待判斷變量,BBB為為空時要替換值
          DECODE(ID,P1,S1,P2,S2,S3) 條件判斷函數,假如ID是P1則返回S1,假如ID是P2則返回S2,否則返回S3。
          RPAD(AAA,COUNT,'0') 字符補空函數,在AAA變量后補零,共字符串長COUNT。
          SUBSTR(AAA,M,N) 取子串函數,取AAA從第M個字符開始,取N個字符。
          LENGTH(STR)  取字符長度。
          LENGTHB(STR) 取字符字節長度。
          TO_CHAR()
          TO_NUMBER()類型轉換函數
          --------------------------------------------------
          SYBASE下:
          CREATE PROCEDURE PRO_MY
          (
          @P_YY CHAR(4),
          @P_NN CHAR(2)='01',
          @P_OUT VARCHAR(255)=NULL OUTPUT
          )
          AS
          BEGIN
              DECLARE @V_CPDM NUMERIC(9,0),
                      @V_CPCB NUMERIC(22,2),
                      @V_ID   INT,
                      @V_JE   FLOAT

              DECLARE CUR_TEST CURSOR FOR
                  SELECT CPCB,JE
                  FROM TEST
                  WHERE YY=@P_YY AND NN=@P_NN AND CPDM=@V_CPDM
              FOR READ ONLY

              SELECT @V_CPCB=CPCB
              FROM TEST
              WHERE YY=@P_YY AND NN=@P_NN AND CPDM=@V_CPDM
              IF @@ROWCOUNT=0
                  PRINT '未找到'
              ELSE
                      PRINT '找到'

              OPEN CUR_TEST
              FETCH CUR_TEST INTO @V_CPCB,@V_JE
              IF @@SQLSTATUS=2 --返回結果集為空
              IF @@SQLSTATUS=1 --游標執行出錯
              BEGIN
                  RAISERROR 20000 --返回自定義錯誤號
                  --RAISERROR 20000,'錯誤信息' --返回自定義錯誤號
                  ROLLBACK
                  RETURN 10
              END
              WHILE @@SQLSTATUS=0 --結果集返回正常結果
              BEGIN
                  /*Exception*/
                  FETCH CUR_TEST INTO @V_CPCB,@V_JE
              END
             
              SELECT @V_ID=@V_ID+1

              IF (@V_STR NOT LIKE "[0-9]")
                  SELECT @@V_ID=1

              EXECUTE @V_ID=DELETE_CB @P_YY,@P_NN  

              UPDATE TEST SET CPCB=100 WHERE YY=@P_YY AND NN=@P_NN
              IF @@ERROR!=0
                       PRINT '更新失敗'  

              RETURN 0

          END

          附錄:
          CONVERT(INT,@V_JE) --類型轉換函數
          LTRIM(@V_STR) --去掉左空格
          RTRIM(@V_STR) --去掉右空格
          ROUND(@V_JE,2) --數值小數位數設定
          SUBSTRING(@V_STR,M,N) --取子字符串
          STR(@V_JE,M,N) --設置數值的顯示位數和小數位數
          CHAR_LENGTH(@V_STR) --字符串長度
          PATINDEX("%[0-9]%",@V_STR) --取前邊字符在后面字符串中的起始位置
          patindex("%[kKmMgGpP]%", @v_str)
          --case語句
          CASE @V_ID WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE 'OTHER' END
          ISNULL(@V_JE,0) --非空值判斷
          -------------------------
          另外:
          關于事務處理:
          ORACLE下不用顯式打開事務,直接提交即可,而且可以分步提交,多次提交,不用成對出現。
          SYBASE必須顯式打開和提交事務,且必須成對出現,平時我們單條更新語句的執行被sybase默認為隱式事務來提交。

          posted on 2006-02-23 17:22 TrampEagle 閱讀(2142) 評論(0)  編輯  收藏 所屬分類: datebase
          主站蜘蛛池模板: 舒兰市| 乌什县| 陇西县| 江油市| 孝义市| 海原县| 河北省| 海口市| 成武县| 西畴县| 广安市| 崇信县| 右玉县| 柳林县| 洮南市| 齐河县| 怀化市| 昌乐县| 年辖:市辖区| 安远县| 邯郸县| 达日县| 叶城县| 正阳县| 南乐县| 乌兰浩特市| 江口县| 大安市| 九龙坡区| 宁安市| 谢通门县| 百色市| 府谷县| 深圳市| 九龙城区| 济源市| 汝阳县| 太康县| 镇康县| 楚雄市| 洛南县|