日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Oracle 游標總結+整理

 WindySky 2011-03-22
項目中需要使用到按規(guī)則生成序列號,開始的解決辦法是根據(jù)條件取得最大ID號進行分解+1再合并的解決方案,后來發(fā)現(xiàn)如果兩個客戶同時操作的時候出現(xiàn)問題:添加的時候ID已經(jīng)存在,原因是:A用戶在訪問取得第MAX(N)記錄deID,但是還沒有進行增加操作,這時,B用戶也取得第MAX(N)記錄deID,這是A進行添加操作同時,B也同時進行添加操作,那么B用戶就會保存失敗,我們開始的時候采用的解決方案是:(枷鎖)在程序的方法上枷鎖,采用單線程操作,實施結果:失敗,客戶等待時間長,后來我們采用綁定數(shù)據(jù)庫的方案:編寫存儲過程,雖然綁定不怎么方便,但是執(zhí)行效率要快很多。由于時間問題,沒有做序列自動創(chuàng)建功能,歡迎各位大蝦進行指點和評論,我們最后的方案如下:
在oracle里面編寫了2個基本做基本處理的自定義函數(shù):
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); --定義動態(tài)游標所能得到的對應值
  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); --執(zhí)行語句

  loop
    
if DBMS_SQL.FETCH_ROWS(v_curId) = 0 then
      
exit;
    
end if;
    DBMS_SQL.COLUMN_VALUE(v_curId, 
1, p_table); --將所取得的游標數(shù)據(jù)賦值到相應的變量
    --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); 
--關閉一個動態(tài)游標
  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)
/**
* 流水賬號創(chuàng)建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;

下面為調(diào)用實例:
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 '流水帳對應的數(shù)據(jù)庫表名';
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系統(tǒng)包提供了很多函數(shù)及過程,現(xiàn)在簡要闡述其中使用頻率較高的幾種:   
    
  function   open_cursor:打開一個動態(tài)游標,并返回一個整型;   
    
  procedure   close_cursor(c   in   out   integer);關閉一個動態(tài)游標,參數(shù)為open_cursor所打開的游標;   
    
  procedure   parse(c   in   integer,   statement   in   varchar2,   language_flag   in   integer):對動態(tài)游標所提供的sql語句進行解析,參數(shù)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]):定義動態(tài)游標所能得到的對應值,其中c為動態(tài)游標,positon為對應動態(tài)sql中的位置(從1開始),column為該值所對應的變量,可以為任何類型,column_size只有在column為定義長度的類型中使用如VARCHAR2,CHAR等(該過程有很多種情況,此處只對一般使用到的類型進行表述);   
    
  function   execute(c   in   integer):執(zhí)行游標,并返回處理一個整型,代表處理結果(對insert,delete,update才有意義,而對select語句而言可以忽略);   
    
  function   fetch_rows(c   in   integer):對游標進行循環(huán)取數(shù)據(jù),并返回一個整數(shù),為0時表示已經(jīng)取到游標末端;   
    
  procedure   column_value(c   in   integer,   position   in   integer,   value):將所取得的游標數(shù)據(jù)賦值到相應的變量,c為游標,position為位置,value則為對應的變量;   
    
  procedure   bind_variable(c   in   integer,   name   in   varchar2,   value):定義動態(tài)sql語句(DML)中所對應字段的值,c為游標,name為字段名稱,value為字段的值;   
    
  以上是在程序中經(jīng)常使用到的幾個函數(shù)及過程,其他函數(shù)及過程請參照oracle所提供定義語句dbmssql.sql   
    
    
  對于一般的select操作,如果使用動態(tài)的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)使用序列是一數(shù)據(jù)庫對象,利用它可生成唯一的整數(shù)。一般使用序列自動地生成主鍵值。對我們程序員來講,精力時間有限,我們只學最有用的知識。大家請看:
  
1) 建立序列命令
  
CREATE SEQUENCE [user.]sequence_name
  
[increment by n]
  
[start with n]
  
[maxvalue n | nomaxvalue]
  
[minvalue n | nominvalue];
  
[NOCYCLE]  --
  INCREMENT BY: 指定序列號之間的間隔,該值可為正的或負的整數(shù),但不可為0.序列為升序。忽略該子句時,缺省值為1.
  START 
WITH:指定生成的第一個序列號。在升序時,序列可從比最小值大的值開始,缺省值為序列的最小值。對于降序,序列可由比最大值小的值開始,缺省值為序列的最大值。
  MAXVALUE:指定序列可生成的最大值。
  NOMAXVALUE:為升序指定最大值為1027,為降序指定最大值為
-1.
  MINVALUE:指定序列的最小值。
  NOMINVALUE:為升序指定最小值為1.為降序指定最小值為
-1026.
  NOCYCLE:一直累加,不循環(huán)
  
2) 更改序列命令
  ALTERSEQUENCE 
[user.]sequence_name
  
[INCREMENT BY n]
  
[MAXVALUE n| NOMAXVALUE ]
  
[MINVALUE n | NOMINVALUE];
  修改序列可以:修改未來序列值的增量。
  設置或撤消最小值或最大值。
  改變緩沖序列的數(shù)目。
  指定序列號是否是有序。
  注意:
  
1,第一次NEXTVAL返回的是初始值
  
2,可以alter除start至以外的所有sequence參數(shù)。如果想要改變start值,必須 drop sequence 再 re-create .
  
3) 刪除序列命令
  
DROP SEQUENCE [user.]sequence_name;
  用于從數(shù)據(jù)庫中刪除一序列。
  
4)牛刀小試
  
4.1)創(chuàng)建一個序列號的語句:
  
-- 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);

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多