<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    悟心

    成功不是將來才有的,而是從決定去做的那一刻起,持續累積而成。 上人生的旅途罷。前途很遠,也很暗。然而不要怕。不怕的人的面前才有路。

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      93 隨筆 :: 1 文章 :: 103 評論 :: 0 Trackbacks
    項目中需要使用到按規則生成序列號,開始的解決辦法是根據條件取得最大ID號進行分解+1再合并的解決方案,后來發現如果兩個客戶同時操作的時候出現問題:添加的時候ID已經存在,原因是:A用戶在訪問取得第MAX(N)記錄deID,但是還沒有進行增加操作,這時,B用戶也取得第MAX(N)記錄deID,這是A進行添加操作同時,B也同時進行添加操作,那么B用戶就會保存失敗,我們開始的時候采用的解決方案是:(枷鎖)在程序的方法上枷鎖,采用單線程操作,實施結果:失敗,客戶等待時間長,后來我們采用綁定數據庫的方案:編寫存儲過程,雖然綁定不怎么方便,但是執行效率要快很多。由于時間問題,沒有做序列自動創建功能,歡迎各位大蝦進行指點和評論,我們最后的方案如下:
    在oracle里面編寫了2個基本做基本處理的自定義函數:
    create or replace function fun_config_glide_num(p_class  varchar2,
                                                    p_column 
    varchar2)
    /**
      * 流水帳號配置_oracle
      * author:ai bo 2010.02.23
      *  p_table varchar2 表名
      *  p_website varchar2 自定義開頭字符
      
    */
     
    return varchar2 as
      v_curId 
    integer;
      
    --  v_seq       varchar2(50);
      -- v_seq_value number;
      v_sql     varchar2(200);
      v_ret     
    number(3);
      v_num     
    varchar2(20);
      p_table   
    varchar2(30);
      p_website 
    varchar2(20);
      p_length  
    varchar2(3);
      t_class   
    varchar2(20);
      t_column  
    varchar2(20);
    begin
      t_class  :
    = p_class;
      t_column :
    = p_column;
      v_sql    :
    = 'SELECT lszh_tname,lszh_mark,lszh_num FROM lszh_table WHERE lszh_cname = ' ||
                  chr(
    39|| t_class || chr(39|| '
     and lszh_column=
    ' || chr(39|| t_column || chr(39|| '';
      v_curId  :
    = DBMS_SQL.OPEN_CURSOR; --為處理打開光標
      DBMS_SQL.PARSE(v_curId, v_Sql, DBMS_SQL.native); --分析語句
      DBMS_SQL.DEFINE_COLUMN(v_curId, 1, p_table, 128); --定義動態游標所能得到的對應值
      DBMS_SQL.DEFINE_COLUMN(v_curId, 2, p_website, 128);
      DBMS_SQL.DEFINE_COLUMN(v_curId, 
    3, p_length, 128);
      v_ret :
    = DBMS_SQL.EXECUTE(v_curId); --執行語句

      loop
        
    if DBMS_SQL.FETCH_ROWS(v_curId) = 0 then
          
    exit;
        
    end if;
        DBMS_SQL.COLUMN_VALUE(v_curId, 
    1, p_table); --將所取得的游標數據賦值到相應的變量
        --DBMS_OUTPUT.PUT_LINE(p_table);
        DBMS_SQL.COLUMN_VALUE(v_curId, 2, p_website);
        
    --DBMS_OUTPUT.PUT_LINE(p_website);
        DBMS_SQL.COLUMN_VALUE(v_curId, 3, p_length);
        
    --DBMS_OUTPUT.PUT_LINE(p_length);
      end loop;
      DBMS_SQL.CLOSE_CURSOR(v_curid); 
    --關閉一個動態游標
      v_num := fun_get_glide_num(trim(p_table), trim(p_website), trim(p_length));
      
    return v_num;
    end;


    create or replace function fun_get_glide_num(p_table   varchar2,p_website varchar2,p_length number)
    /**
    * 流水帳號創建oracle版本
    * author : ai bo 2010.02.23
    *  p_table varchar2 表名
    *  p_website varchar2 自定義開頭字符
    */
    return varchar2 as
       v_seq       
    varchar2(50);
       v_seq_value 
    number;
        v_sql       
    varchar2(200);
       v_num       
    varchar2(20);
    begin
        v_seq :
    = 'seq_' || p_table;
        v_sql :
    = 'select ' || v_seq || '.nextval from dual';
        dbms_output.put_line(v_sql);
       
    execute immediate v_sql
           
    into v_seq_value;
       
    select lpad(v_seq_value, p_length, '0'into v_num from dual;
       v_num :
    = p_website || v_num;
        
    return v_num;
    end;

    下面為調用實例:
    select fun_config_glide_num('TabMachineType','FAC_CODE'as CN FROM dual;

    下面是表流水帳號表結構

    -- Create table
    create table LSZH_TABLE
    (
      LSZH_CNAME    
    CHAR(20not null,
      LSZH_TNAME    
    CHAR(20),
      LSZH_COLUMN   
    CHAR(20not null,
      LSZH_MARK     
    CHAR(20),
      LSZH_DATETYPE 
    CHAR(10),
      LSZH_NUM      
    CHAR(3default 4
    )

    -- Add comments to the columns 
    comment on column LSZH_TABLE.LSZH_CNAME
      
    is '流水帳號類名';
    comment 
    on column LSZH_TABLE.LSZH_TNAME
      
    is '流水帳對應的數據庫表名';
    comment 
    on column LSZH_TABLE.LSZH_COLUMN
      
    is '流水帳號類別標識列';
    comment 
    on column LSZH_TABLE.LSZH_MARK
      
    is '流水帳號類別標識對應的字符';
    comment 
    on column LSZH_TABLE.LSZH_DATETYPE
      
    is '時間作為流水號的排列次序';
    comment 
    on column LSZH_TABLE.LSZH_NUM
      
    is '流水碼長度';
    -- Create/Recreate primary, unique and foreign key constraints 
    alter table LSZH_TABLE
      
    add constraint PK_LSZH_TABLE primary key (LSZH_COLUMN, LSZH_CNAME)

    參考資料:
    DBMS_SQL系統包提供了很多函數及過程,現在簡要闡述其中使用頻率較高的幾種:   
        
      function   open_cursor:打開一個動態游標,并返回一個整型;   
        
      procedure   close_cursor(c   in   out   integer);關閉一個動態游標,參數為open_cursor所打開的游標;   
        
      procedure   parse(c   in   integer,   statement   in   varchar2,   language_flag   in   integer):對動態游標所提供的sql語句進行解析,參數C表示游標,statement為sql語句,language-flag為解析sql語句所用oracle版本,一般有V6,V7跟native(在不明白所連database版本時,使用native);   
        
      procedure   define_column(c   in   integer,   position   in   integer,   column   any   datatype,   [column_size   in   integer]):定義動態游標所能得到的對應值,其中c為動態游標,positon為對應動態sql中的位置(從1開始),column為該值所對應的變量,可以為任何類型,column_size只有在column為定義長度的類型中使用如VARCHAR2,CHAR等(該過程有很多種情況,此處只對一般使用到的類型進行表述);   
        
      function   execute(c   in   integer):執行游標,并返回處理一個整型,代表處理結果(對insert,delete,update才有意義,而對select語句而言可以忽略);   
        
      function   fetch_rows(c   in   integer):對游標進行循環取數據,并返回一個整數,為0時表示已經取到游標末端;   
        
      procedure   column_value(c   in   integer,   position   in   integer,   value):將所取得的游標數據賦值到相應的變量,c為游標,position為位置,value則為對應的變量;   
        
      procedure   bind_variable(c   in   integer,   name   in   varchar2,   value):定義動態sql語句(DML)中所對應字段的值,c為游標,name為字段名稱,value為字段的值;   
        
      以上是在程序中經常使用到的幾個函數及過程,其他函數及過程請參照oracle所提供定義語句dbmssql.sql   
        
        
      對于一般的select操作,如果使用動態的sql語句則需要進行以下幾個步驟:   
      open   cursor--->parse--->define   column--->excute--->fetch   rows--->close   cursor;   
      而對于dml操作(insert,update)則需要進行以下幾個步驟:   
      open   cursor--->parse--->bind   variable--->execute--->close   cursor;   
      對于delete操作只需要進行以下幾個步驟:   
      open   cursor--->parse--->execute--->close   cursor;   
    序列sequence:
    http://www.examda.com/Oracle/
    關于Oracle的序列(Sequence)使用序列是一數據庫對象,利用它可生成唯一的整數。一般使用序列自動地生成主鍵值。對我們程序員來講,精力時間有限,我們只學最有用的知識。大家請看:
      
    1) 建立序列命令
      
    CREATE SEQUENCE [user.]sequence_name
      
    [increment by n]
      
    [start with n]
      
    [maxvalue n | nomaxvalue]
      
    [minvalue n | nominvalue];
      
    [NOCYCLE]  --
      INCREMENT BY: 指定序列號之間的間隔,該值可為正的或負的整數,但不可為0.序列為升序。忽略該子句時,缺省值為1.
      START 
    WITH:指定生成的第一個序列號。在升序時,序列可從比最小值大的值開始,缺省值為序列的最小值。對于降序,序列可由比最大值小的值開始,缺省值為序列的最大值。
      MAXVALUE:指定序列可生成的最大值。
      NOMAXVALUE:為升序指定最大值為1027,為降序指定最大值為
    -1.
      MINVALUE:指定序列的最小值。
      NOMINVALUE:為升序指定最小值為1.為降序指定最小值為
    -1026.
      NOCYCLE:一直累加,不循環
      
    2) 更改序列命令
      ALTERSEQUENCE 
    [user.]sequence_name
      
    [INCREMENT BY n]
      
    [MAXVALUE n| NOMAXVALUE ]
      
    [MINVALUE n | NOMINVALUE]
      修改序列可以:修改未來序列值的增量。
      設置或撤消最小值或最大值。
      改變緩沖序列的數目。
      指定序列號是否是有序。
      注意:
      
    1,第一次NEXTVAL返回的是初始值
      
    2,可以alter除start至以外的所有sequence參數。如果想要改變start值,必須 drop sequence 再 re-create .
      
    3) 刪除序列命令
      
    DROP SEQUENCE [user.]sequence_name;
      用于從數據庫中刪除一序列。
      
    4)牛刀小試
      
    4.1)創建一個序列號的語句:
      
    -- Create sequence
      create sequence NCME_QUESTION_SEQ
      minvalue 
    1
      maxvalue 
    999999999999
      start 
    with 1
      increment 
    by 1
      nocache;
      
    //////////////////////////////
      
    4.2)SQL中取序列號的用法:
      
    SELECT NCME_QUESTION_SEQ.nextval FROM dual
      
    SELECT NCME_QUESTION_SEQ.CURRVAL FROM dual
      
    SELECT NCME_QUESTION_SEQ.nextval FROM dual SELECT NCME_QUESTION_SEQ.CURRVAL FROM dual
      注意:在使用序列的時候,有時需要有用戶名,就像這樣:
      
    insert into system.CONSERVATOR(CONSERVATORNAME,CONPASS,CONTRUENAME,CONSEX,CONID)values('JG','123456','000',0, system.CONID.nextval);
    參考資料鏈接:
    關于DBMS_SQL包,動態SQL語句的問題
    oracle 隱式游標,顯示游標,游標循環,動態SELECT語句和動態游標,異常處理,自定義異常
    oracle 創建,刪除存儲過程,參數傳遞,創建,刪除存儲函數,存儲過程和函數的查看,包,系統包
    幾種使用動態SQL做游標的總結
    關于動態SQL的使用
    oracle創建存儲過程
    oracle創建函數,存儲過程,視圖以及for循環語法
    oracle自定義函數
    posted on 2010-02-24 17:20 艾波 閱讀(4534) 評論(2)  編輯  收藏 所屬分類: SQL

    評論

    # re: Oracle 游標總結+整理 2010-02-24 17:52 石頭JAVA擺地攤兒
    貼主,能講一講原理嗎?

    代碼太多沒有看懂,

    這個是怎么實現的?什么原理?

      回復  更多評論
      

    # re: Oracle 游標總結+整理 2010-03-06 23:57 spdia
    為什么不用 oracle sequence實現主鍵  回復  更多評論
      

    主站蜘蛛池模板: 先锋影音资源片午夜在线观看视频免费播放 | 四虎影视精品永久免费网站| 精品亚洲成AV人在线观看| 永久免费不卡在线观看黄网站| 精品亚洲视频在线观看| GOGOGO高清免费看韩国| 亚洲伊人久久精品影院| 久操视频在线免费观看| 亚洲一卡2卡三卡4卡有限公司| 免费一级毛片在线播放视频| 久久青青草原亚洲AV无码麻豆 | 亚洲熟妇成人精品一区| 全免费a级毛片免费看不卡| 毛片亚洲AV无码精品国产午夜| 免费人成在线观看网站视频| 一级做a爰片久久毛片免费陪 | 亚洲A∨精品一区二区三区| 污污的视频在线免费观看| 国产又黄又爽又猛的免费视频播放| 男男黄GAY片免费网站WWW| 国产L精品国产亚洲区久久 | 一二三四免费观看在线电影 | 免费jjzz在线播放国产| 一级毛片试看60分钟免费播放| 亚洲人成网站在线观看播放| 91麻豆国产免费观看| 亚洲综合色婷婷在线观看| 又粗又硬又大又爽免费视频播放| 男女一边桶一边摸一边脱视频免费 | 亚洲综合伊人久久综合| 99久久免费国产精精品| 亚洲熟妇色自偷自拍另类| 大学生美女毛片免费视频| 国产精品无码免费专区午夜| 婷婷亚洲久悠悠色悠在线播放| a级毛片无码免费真人| 一区二区三区在线免费观看视频| 久久夜色精品国产噜噜噜亚洲AV| 性盈盈影院免费视频观看在线一区| 九九久久精品国产免费看小说| 久久99国产亚洲精品观看|