国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

從SQL SERVER 向ORACLE 8遷移的技術實現方案

2024-08-31 00:52:09
字體:
來源:轉載
供稿:網友
不知道從哪里得到這個文檔,有用就放上來了 -gwb 數據庫端SQL語法的遷移
以下為常用的SQL語法遷移,包括數據類型、ID列向SEQUENCE遷移、表(主鍵、外鍵、CHECK、UNIQUE、DEFAULT、INDEX)、游標、存儲過程、函數、觸發器、常用SQL語法與函數幾個方面,考慮SQL SERVER的實際情況,沒有涉及Oracle特有的PACKAGE、EXCEPTION等。在以下的描述中,將SQL SERVER的TRANSACT-SQL簡稱為T-SQL。在ORACLE中,其語法集稱為PL/SQL。

 
<一> 數據類型的遷移
    <1>、ORACLE端語法說明

在ORACLE中,分析其數據類型,大致可分為數字、字符、日期時間和非凡四大類。其中,數字類型有NUMBER;字符類型有CHAR與VARCHAR2;日期時間類型只有DATE一種;除此之外,LONG、RAW、LONG RAW、BLOB、CLOB和BFILE等數據類型都可視為非凡數據類型。

 

    <2>、SQL SERVER端語法說明

在SQL SERVER中,參照上面對ORACLE的劃分,數據類型也大致可分為數字、字符、日期時間和非凡四大類。數字類型又可分為精確數值、近似數值、整數、二進制數、貨幣等幾類,其中,精確數值有DECIMAL[(P[, S])]與NUMERIC[(P[, S])];近似數值有FLOAT[(N)];整數有INT、SMALLINT、TINYINT;二進制數有BINARY[(N)]、VARBINARY[(N)];貨幣有MONEY、SMALLMONEY。字符類型有CHAR[(N)]與VARCHAR[(N)]。日期時間類型有DATETIME、SMALLDATETIME。除此之外,BIT、TIMESTAMP、TEXT和IMAGE、BINARY VARING等數據類型都可視為非凡數據類型。

 

<3>、從SQL SERVER向ORACLE的遷移方案

比較ORACLE與SQL SERVER在數據類型上的不同,當從SQL SERVER向ORACLE遷移時,可以做如下調整:

 

SQL SERVER

ORACLE

數字類型

DECIMAL[(P[, S])]

NUMBER[(P[, S])]

NUMERIC[(P[, S])]

NUMBER[(P[, S])]

FLOAT[(N)]

NUMBER[(N)]

INT

NUMBER

SMALLINT

NUMBER

TINYINT

NUMBER

MONEY

NUMBER[19,4]

SMALLMONEY

NUMBER[19,4]

字符類型

CHAR[(N)]

CHAR[(N)]

VARCHAR[(N)]

VARCHAR2[(N)]

日期時間類型

DATETIME

DATE

SMALLDATETIME

DATE

其它

TEXT

CLOB

IMAGE

BLOB

BIT

NUMBER(1)

方法:

公司原系統中的Money 用于金額時轉換用number(14,2);用于單價時用 number(10,4)代替;
<二> ID列向SEQUENCE遷移
    <1>、SQL SERVER端語法說明

在SQL SERVER中,可以將數據庫中的某一字段定義為IDENTITY列以做主鍵識別,如:

    jlbh        numeric(12,0)        identity(1,1)        /*記錄編號字段*/

    CONSTRAINT  PK_tbl_example  PRIMARY KEY  nonclustered (jlbh)  /*主鍵約束*/

在這里,jlbh是一個ID列,在向具有該列的表插入記錄時,系統將從1開始以1的步長自動對jlbh的值進行維護。

 

    <2>、ORACLE端語法說明

但在ORACLE中,沒有這樣的ID列定義,而是采用另一種方法,即創建SEQUENCE。

如:

/*--1、創建各使用地區編碼表--*/

drop table LT_AREA;

create table LT_AREA

  (

  area_id    number(5,0)      NOT NULL,   /*地區編碼*/

  area_name    varchar2(20)     NOT NULL,   /*地區名稱*/

  constraint PK_LT_AREA PRIMARY KEY(area_id)

 );

 

/*--2、創建SEQUENCE,將列area_id 類ID化--*/

drop sequence SEQ_LT_AREA;

create sequence SEQ_LT_AREA increment by 1    /*該SEQUENCE以1的步長遞增*/


 start with 1 maxvalue 99999;                /*從1開始,最大增長到99999*/

 

/*--3、實際操作時引用SEQUENCE的下一個值--*/

insert into LT_AREA(area_id, area_name) values(SEQ_LT_AREA.NEXTVAL, '深圳');

insert into LT_AREA(area_id, area_name) values(SEQ_LT_AREA.NEXTVAL, '廣州');

insert into LT_AREA(area_id, area_name) values(SEQ_LT_AREA.NEXTVAL, '北京');

 

/*--4、新插入連續三條記錄后,下一條語句運行后,‘上?!貐^的area_id為4--*/

insert into LT_AREA(area_id, area_name) values(SEQ_LT_AREA.NEXTVAL, '上海');

 

   <3>、從SQL SERVER向ORACLE的遷移方案

 

根據以上分析,當從SQL SERVER向ORACLE遷移時,可以做如下調整:

1、去掉建表語句中有關ID列的identity聲明要害字;

2、創建SEQUENCE,將此SEQUENCE與需類ID化的列對應;

3、在INSERT語句中對相應列引用其SEQUENCE值:SEQUENCENAME.NEXTVAL

實際上,處理以上情況在ORACLE中采用的方法為對有自動增長字段的表增加一插入前觸發器(具體資料見后“觸發器”一節),如下:

CREATE OR REPLACE TRIGGER GenaerateAreaID

BEFORE INSERT ON LT_AREA

FOR EACH ROW

        Select SEQ_LT_AREA.NEXTVAL INTO :NEW.ID

        FROM DUAL;

BEGIN

END GenaerateAreaID;

GenaerateAreaID實際上修改了偽記錄:new的area_id值。 :new最有用的一個特性----當該語句真正被執行時,:new中的存儲內容就會被使用。所以系統每次都能自動生成新的號碼。
<三> 表(主鍵、外鍵、CHECK、UNIQUE、DEFAULT、INDEX)
    <1>、SQL SERVER端語法說明

有如下SQL SERVER語句:

/* ------------------------ 創建employee 表------------------------ */

IF EXISTS(SELECT 1 FROM SYSOBJECTS WHERE NAME = ‘employee’

          AND TYPE = ‘U’)

        DROP TABLE employee

GO

 

CREATE TABLE employee

(

    emp_id   empid    /*empid為用戶自定義數據類型*/

    /*創建自命名主鍵約束*/

        CONSTRAINT PK_employee PRIMARY KEY NONCLUSTERED

    /*創建自命名CHECK約束*/

        CONSTRAINT CK_emp_id CHECK (emp_id LIKE

                     '[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]' or

                     emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]'),

        /* CHECK約束說明:Each employee ID consists of three characters that

        represent the employee's initials, followed by a five

        digit number ranging from 10000 to 99999 and then the

        employee's gender (M or F). A (hyphen) - is acceptable

        for the middle initial. */

    fname     varchar(20)      NOT NULL,


    minit     char(1)         NULL,

    lname     varchar(30)      NOT NULL,

 

    ss_id     varchar(9)        UNIQUE,    /*創建唯一性約束*/

 

job_id    smallint            NOT NULL

        DEFAULT 1,            /*設定DEFAULT值*/

    job_lvl tinyint

       DEFAULT 10,            /*設定DEFAULT值*/

        /* Entry job_lvl for new hires. */

    pub_id   char(4)         NOT NULL

        DEFAULT ('9952')        /*設定DEFAULT值*/

        REFERENCES publishers(pub_id),  /*創建系統命名外鍵約束*/

        /* By default, the Parent Company Publisher is the company

        to whom each employee reports. */

    hire_date        datetime       NOT NULL

        DEFAULT (getdate()),        /*設定DEFAULT值*/

        /* By default, the current system date will be entered. */

    CONSTRAINT FK_employee_job FOREIGN KEY (job_id)

        REFERENCES jobs(job_id)        /*創建自命名外鍵約束*/

)

GO

   

    /* --------------------- 創建employee表上的index --------------------- */

IF EXISTS (SELECT 1 FROM sysindexes

               WHERE name = 'emp_pub_id_ind')

    DROP INDEX employee. emp_pub_id_ind

GO

 

    CREATE INDEX emp_pub_id_ind

        ON employee(pub_id)

GO

 

    <2>、ORACLE端語法說明

在ORACLE端的語法如下:

    /* ---------------------- 創建employee 表---------------------- */

    DROP TABLE employee;

 

CREATE TABLE employee

(

    emp_id    varchar2(9)  /*根據用戶自定義數據類型的定義調整為varchar2(9)*/

    /*創建自命名主鍵約束*/

        CONSTRAINT PK_employee PRIMARY KEY NONCLUSTERED

    /*創建自命名CHECK約束*/

        CONSTRAINT CK_emp_id CHECK (emp_id LIKE


                     '[A-Z][A-Z][A-Z][1-9][0-9][0-9][0-9][0-9][FM]' or

                     emp_id LIKE '[A-Z]-[A-Z][1-9][0-9][0-9][0-9][0-9][FM]'),

        /* CHECK約束說明:Each employee ID consists of three characters that

        represent the employee's initials, followed by a five

        digit number ranging from 10000 to 99999 and then the

        employee's gender (M or F). A (hyphen) - is acceptable

        for the middle initial. */

    fname     varchar2(20)     NOT NULL,

    minit     varchar2(1)      NULL,

    lname     varchar2(30)     NOT NULL,

 

    ss_id     varchar2(9)      UNIQUE,    /*創建唯一性約束*/

 

job_id    number(5,0)      NOT NULL

        /*這里考慮了SMALLINT的長度,也可調整為number*/

        DEFAULT 1,            /*設定DEFAULT值*/

    job_lvl     number(3,0)

        /*這里考慮了TINYINT的長度,也可調整為number*/

       DEFAULT 10,            /*設定DEFAULT值*/

        /* Entry job_lvl for new hires. */

    pub_id  varchar2(4)        NOT NULL

        DEFAULT ('9952')        /*設定DEFAULT值*/

        REFERENCES publishers(pub_id),  /*創建系統命名外鍵約束*/

        /* By default, the Parent Company Publisher is the company

        to whom each employee reports. */

    hire_date        date            NOT NULL

        DEFAULT SYSDATE,        /*設定DEFAULT值*/

        /*這里,SQL SERVER的getdate()調整為ORACLE的SYSDATE*/

        /* By default, the current system date will be entered. */

    CONSTRAINT FK_employee_job FOREIGN KEY (job_id)

        REFERENCES jobs(job_id)        /*創建自命名外鍵約束*/


);

   

    /* -------------------- 創建employee表上的index -------------------- */

DROP INDEX employee. emp_pub_id_ind;

    CREATE INDEX emp_pub_id_ind ON employee(pub_id);

 

<3>、從SQL SERVER向ORACLE的遷移方案

比較這兩段SQL代碼,可以看出,在創建表及其主鍵、外鍵、CHECK、UNIQUE、DEFAULT、INDEX時,SQL SERVER 與ORACLE的語法大致相同,但時遷移時要注重以下情況:

    (1) Oracle定義表字段的default屬性要緊跟字段類型之后,如下:

    Create table MZ_Ghxx

  ( ghlxh  number primay key ,

    rq     date   default sysdate not null,

  ….

  )

  而不能寫成

    Create table MZ_Ghxx

  ( ghlxh  number primay key ,

    rq     date   not null default sysdate,

  ….

  )

(2)T-SQL定義表結構時,假如涉及到用默認時間和默認修改人員,全部修改如下:

 ZHXGRQ     DATE   DEFAULT SYSDATE NULL,

 ZHXGR      CHAR(8) DEFAULT ‘FUTIAN’ NULL,

(3)如表有identity定段,要先將其記錄下來,建完表之后,馬上建相應的序列和表觸發器,并作為記錄。
<四> 游標
    <1>、SQL SERVER端語法說明

1、DECLARE CURSOR語句

       語法:

           DECLARE cursor_name [INSENSITIVE] [SCROLL] CURSOR

    FOR select_statement

  [FOR {READ ONLY UPDATE [OF column_list ]}]

       例:

       DECLARE  authors_cursor  CURSOR  FOR

        SELECT  au_lname, au_fname

          FROM  authors

         WHERE  au_lname LIKE ‘B%’

      ORDER BY  au_lname, au_fname

 

2、OPEN語句

   語法:

       OPEN  cursor_name

       例:

       OPEN authors_cursor

 

3、FETCH語句

   語法:

       FETCH

             [ [ NEXT PRIOR FIRST LAST ABSOLUTE n RELATIVE n ]

           FROM  cursor_name

         [INTO @variable_name1, @variable_name2,… ]

       例:

       FETCH NEXT FROM authors_cursor

                  INTO @au_lname, @au_fname

 

4、CLOSE語句

   語法:

       CLOSE  cursor_name


       例:

       CLOSE authors_cursor

 

5、DEALLOCATE語句

   語法:

       DEALLOCATE  cursor_name

       例:

       DEALLOCATE authors_cursor

 

6、游標中的標準循環與循環終止條件判定

   (1)FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname

 

   (2)-- Check @@FETCH_STATUS to see if there are any more rows to fetch.

        WHILE @@FETCH_STATUS = 0

        BEGIN

           -- Concatenate and display the current values in the variables.

           PRINT "Author: " + @au_fname + " " +  @au_lname

 

           -- This is executed as long as the previous fetch sUCceeds.

               FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname

        END

 

   (3)CLOSE authors_cursor

7、隱式游標

MSSQLServer中對于數據操縱語句受影響的行數,有一個全局的變量:@@rowcount,其實它是一個隱式的游標,它記載了上條數據操縱語句所影響的行數,當@@rowcount小于1時,表時,上次沒有找到相關的記錄,如下:

Update students set lastname = ‘John’ where student_id = ‘301’

If @@rowcount < 1 then

Insert into students values (‘301’,’stdiv’,’john’,’996-03-02’)

表示假如數據表中有學號為“301”的記錄,則修改其名字為“John”,假如找不到相應的記錄,則向數據庫中插入一條“John”的記錄。

8、示例:

-- Declare the variables to store the values returned by FETCH.

DECLARE @au_lname varchar(40), @au_fname varchar(20)

 

DECLARE  authors_cursor  CURSOR  FOR

 SELECT  au_lname, au_fname

   FROM  authors

  WHERE  au_lname LIKE ‘B%’

   ORDER BY  au_lname, au_fname

 

OPEN authors_cursor

 

-- Perform the first fetch and store the values in variables.

-- Note: The variables are in the same order as the columns

-- in the SELECT statement.

 

FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname

 

-- Check @@FETCH_STATUS to see if there are any more rows to fetch.

WHILE @@FETCH_STATUS = 0

 

BEGIN

  -- Concatenate and display the current values in the variables.

      PRINT "Author: " + @au_fname + " " +  @au_lname

 

      -- This is executed as long as the previous fetch succeeds.


      FETCH NEXT FROM authors_cursor INTO @au_lname, @au_fname

END

 

CLOSE authors_cursor

 

DEALLOCATE authors_cursor

 

    <2>、ORACLE端語法說明

1、  DECLARE CURSOR語句

       語法:

    CURSOR  cursor_name  IS  select_statement;

       例:

           CURSOR  authors_cursor  IS

       SELECT  au_lname, au_fname

         FROM  authors

        WHERE  au_lname LIKE ‘B%’

     ORDER BY  au_lname, au_fname;

 

2、  OPEN語句

   語法:

       OPEN  cursor_name

       例:

       OPEN authors_cursor;

 

3、  FETCH語句

   語法:

       FETCH  cursor_name  INTO  variable_name1 [, variable_name2,… ] ;

       例:

       FETCH  authors_cursor  INTO  au_lname, au_fname;

 

4、  CLOSE語句

   語法:

       CLOSE  cursor_name

       例:

       CLOSE authors_cursor;

 

5、簡單游標提取循環結構與循環終止條件判定

   1> 用%FOUND做循環判定條件的WHILE循環

     (1)FETCH  authors_cursor  INTO  au_lname, au_fname ;

     (2)WHILE authors_cursor%FOUND LOOP

             -- Concatenate and display the current values in the variables.

                 DBMS_OUTPUT.ENABLE;

             DBMS_OUTPUT.PUT_LINE( ‘Author: ‘ au_fname ‘ ‘ au_lname) ;

             FETCH  authors_cursor  INTO  au_lname, au_fname ;

          END LOOP ;

     (3)CLOSE authors_cursor ;

 

   2> 用%NOTFOUND做循環判定條件的簡單LOOP...END LOOP循環

     (1)OPEN authors_cursor;

     (2)LOOP

             FETCH  authors_cursor  INTO  au_lname, au_fname ;

                 -- Exit loop when there are no more rows to fetch.


             EXIT  WHEN  authors_cursor%NOTFOUND ;

             -- Concatenate and display the current values in the variables.

             DBMS_OUTPUT.ENABLE;

             DBMS_OUTPUT.PUT_LINE( ‘Author: ‘ au_fname ‘ ‘ au_lname) ;

          END LOOP ;

     (3)CLOSE authors_cursor ;

3>用游標式FOR循環,如下:

DECLARE

                CURSOR c_HistoryStudents IS

                SELECT id,first_name,last_name

                FROM Students

                WHERE major = ‘History’

BEGIN

              FOR v_StudentData IN c_HistoryStudents LOOP

              INSERT INTO registered_students

(student_id,first_name,last_name,department,course)

VALUES(v_StudentData.ID,v_StudentData.first_name, v_StudentData.last_name,’HIS’,301);

              END LOOP;

COMMIT;

END;

首先,記錄v_StudentData沒有在塊的聲明部分進行聲明,些變量的類型是c_HistoryStudents%ROWTYPE,v_StudentData的作用域僅限于此FOR循環本身;其實,c_HistoryStudents以隱含的方式被打開和提取數據,并被循環關閉。

6、隱式游標SQL%FOUND 與SQL%NOTFOUND

        與MSSQL SERVER 一樣,ORACLE也有隱式游標,它用于處理INSERT、DELETE和單行的SELECT..INTO語句。因為SQL游標是通過PL/SQL引擎打開和關閉的,所以OPEN、FETCH和CLOSE命令是無關的。但是游標屬性可以被應用于SQL游標,如下:

BEGIN

        UPDATE rooms

          SET number_seats = 100

        WHERE room_id = 9990;

--假如找不相應的記錄,則插入新的記錄

        IF SQL%NOTFOUND THEN

            INSERT INTO rooms(room_id,number_seats)

            VALUES (9990,100)

END IF

    END;

7、示例:

-- Declare the variables to store the values returned by FETCH.

-- Declare the CURSOR authors_cursor.

DECLARE

   au_lname  varchar2(40) ;

   au_fname  varchar2(20) ;

       CURSOR  authors_cursor  IS

   SELECT  au_lname, au_fname

     FROM  authors

    WHERE  au_lname LIKE ‘B%’


 ORDER BY  au_lname, au_fname;

 

BEGIN

   OPEN authors_cursor;

   FETCH  authors_cursor  INTO  au_lname, au_fname ;

   WHILE authors_cursor%FOUND LOOP

      -- Concatenate and display the current values in the variables.

          DBMS_OUTPUT.ENABLE;

      DBMS_OUTPUT.PUT_LINE( ‘Author: ‘ au_fname ‘ ‘ au_lname) ;

      FETCH  authors_cursor  INTO  au_lname, au_fname ;

   END LOOP ;

 

   CLOSE authors_cursor ;

END ;

 

    <3>、從SQL SERVER向ORACLE的遷移方案

        比較上述SQL代碼,在遷移過程中要做如下調整:

        (1)T-SQL對CURSOR的聲明在主體代碼中,而PL/SQL中對CURSOR的聲明與變

             量聲明同步,都要在主體代碼(BEGIN要害字)之前聲明,所以在遷移時要

             將游標聲明提前,MSSQL SERVER的Cursor定義后的參數省去;

        (2)對CUOSOR操作的語法中PL/SQL沒有T-SQL里DEALLOCATE CURSOR這一部分,

             遷移時要將該部分語句刪除。

        (3)PL/SQL 與T-SQL對游標中的循環與循環終止條件判定的處理不太一樣,根

             據前面的討論并參考后面對兩種語法集進行控制語句對比分析部分的敘述,

             建議將T-SQL中的游標提取循環調整為PL/SQL中的WHILE游標提取循環結

             構,這樣可保持循環的基本結構大致不變,同時在進行循環終止條件判定時

             要注重將T-SQL中的對@@FETCH_STATUS全局變量的判定調整為對

             CURSOR_NAME%FOUND語句進行判定。

        (4)對于T-SQL,沒有定義語句結束標志,而PL/SQL用“;”結束語句。

(5)對于原MSSQL SERVER類型的游標,假如游標取出的值沒有參與運算的,全部采用FOR循環方式來替換;而對于取出的值還要進行其它運算的,可以采用直接在定義變量位置定義變量。

 (6)MSSQL中對于同一游標重復定義幾次的情況在ORACLE中可通過游標變量來解決.如下:

MSSQL SERVER 中:

Declare cur_ypdm cursor for

Select * from yp

Open cur_yp

Fetch cur_yp into @yp,@mc …

While @@fetch_status <> -1

Begin

  If @@fetch_status <> -2

  Begin

    ….

  End

  Fetch cur_yp into @yp,@mc …

End

Close cur_ypdm

Deallocate cur_ypdm

..

Declare cur_ypdm cursor for

Select * from yp where condition 1

Open cur_yp

Fetch cur_yp into @yp,@mc …

While @@fetch_status <> -1

Begin

  If @@fetch_status <> -2

  Begin

    ….


  End

  Fetch cur_yp into @yp,@mc …

End

Close cur_ypdm

Deallocate cur_ypdm

..

Declare cur_ypdm cursor for

Select * from yp  where condition 2

Open cur_yp

Fetch cur_yp into @yp,@mc …

While @@fetch_status <> -1

Begin

  If @@fetch_status <> -2

  Begin

    ….

  End

  Fetch cur_yp into @yp,@mc …

End

Close cur_ypdm

Deallocate cur_ypdm

..

在程序中,三次定義同一游標cur_yp

在遷移過程中,最好先定義一游標變量,在程序中用open打開,如下:

declare

  type cur_type is ref  cur_type;

  cur_yp cur_type;

  …

begin

  open cur_yp for select * from yp;

  loop

    fetch cur_yp into yp,mc …

    Exit When cur_yp%NotFound;

    ….

  end loop;

  close cur_yp;

  open cur_yp for select * from yp where condition1;

  loop

    fetch cur_yp into yp,mc …

    Exit When cur_yp%NotFound;

    ….

  end loop;

  close cur_yp;

  open cur_yp for select * from yp where condition2;

  loop

    fetch cur_yp into yp,mc …

    Exit When cur_yp%NotFound;

    ….

  end loop;

  close cur_yp;

end;

(7)請注重,游標循環中中一定要退出語名,要不然執行時會出現死循環。

<五> 存儲過程/函數

    <1>、SQL SERVER端語法說明

    1、語法:

           CREATE PROC[EDURE] [owner.]procedure_name [;number]

             [ (parameter1[, parameter2]…[, parameter255])]

             [ {FOR REPLICATION} {WITH RECOMPILE}

             [ {[WITH] [ , ] } ENCRYPTION ] ]

           AS

             sql_statement [...n]

           其中,Parameter = @parameter_name datatype [=default] [output]

 

       說明:T-SQL中存儲過程的結構大致如下

           CREATE PROCEDURE procedure_name

               /*輸入、輸出參數的聲明部分*/

           AS

               DECLARE


               /*局部變量的聲明部分*/

           BEGIN

               /*主體SQL語句部分*/

              /*游標聲明、使用語句在此部分*/

           END

 

    2、示例:

       IF EXISTS(SELECT 1 FROM sysobjects

                 WHERE name = 'titles_sum' AND type = 'P')

          DROP PROCEDURE titles_sum

       GO

 

       CREATE PROCEDURE titles_sum

              @TITLE varchar(40) = '%', @SUM money OUTPUT

       AS

       BEGIN

          SELECT  'Title Name' = title

            FROM  titles

           WHERE  title  LIKE  @TITLE

          SELECT  @SUM = SUM(price)

            FROM  titles

           WHERE  title  LIKE  @TITLE

       END

 

    <2>、ORACLE端PROCEDURE語法說明

    1、語法:

           CREATE [OR REPLACE] PROCEDURE procedure_name

             [ (parameter1 [ {IN OUT IN OUT } ] type ,

               …

               parametern [ {IN OUT IN OUT } ] type ) ]

           { IS AS }

           [BEGIN]

             sql_statement [...n] ;

           [END] ;

      

       說明:PL/SQL中存儲過程的結構大致如下

           CREATE OR REPLACE PROCEDURE procedure_name

              (  /*輸入、輸出參數的聲明部分*/  )


           AS

               /*局部變量、游標等的聲明部分*/

           BEGIN

               /*主體SQL語句部分*/

               /*游標使用語句在此部分*/

           EXCEPTION

               /*異常處理部分*/

           END ;

 

    2、示例:

       CREATE OR REPLACE PROCEDURE  drop_class

          ( arg_student_id  IN         varchar2,

            arg_class_id    IN      varchar2,

            status          OUT     number   )

       AS

          counter     number ;

       BEGIN

          status := 0 ;

          -- Verify that this class really is part of the student’s schedule.

          select  count (*)  into  counter

            from  student_schedule

           where  student_id  =  arg_student_id

             and  class_id    =  arg_class_id ;

         

          IF  counter  =  1  THEN

             delete  from  student_schedule

              where  student_id  =  arg_student_id

                and  class_id    =  arg_class_id ;

             status := -1 ;

          END IF ;

       END ;

<3>ORACLE端FUNCTION語法說明


(1)  語法

CREATE [OR REPLACE] FUNCTION function_name

[(argument [{IN OUT IN OUT }] ) type,



[(argument [{IN OUT IN OUT }] ) type

RETURN return_type {IS AS}

BEGIN



END;

要害字return 指定了函數返回值的數據類型。它可以是任何合法的PL/SQL數據類型。每個函數都必須有一個return 子句,因為在定義上函數必須返回一個值給調用環境。

(2)示例

CREATE OR REPLACE FUNCTION blanace_check(Person_Name IN varchar2)

RETURN NUMBER

IS

Balance NUMBER(10,2);

BEGIN

              Select sum(decode(acton,’BOUGHT’,Amount,0))

              INTO balance

              FROM ledger

              WHERE Person = Person_name;

              RETURN (balance);

END;

(3)過程與函數的區別

函數可以返回一個值給調用環境;而過程不能,過程只能通過返回參數(帶“OUT”或“IN OUT”)傳回去數據。

<4>從SQL SERVER向ORACLE的遷移方案

通過比較上述SQL語法的差異,在遷移時必須注重以下幾點:

1、對于有返回單值的MSSQL存儲過程,在數據庫移值最好轉換成ORALCE的函數;對于MSSQL有大量數據的處理而又不需返回值的存儲過程轉換成ORACLE的過程

       2、在T-SQL中,輸入、輸出參數定義部分在“CREATE…”和“AS”之間,前后

          沒有括號;而在PL/SQL中必須有“(”和“)”與其他語句隔開。

       3、在T-SQL中,聲明局部變量時,前面要有DECLARE要害字;

          而在PL/SQL中不用DECLARE要害字。

       4、在T-SQL中,參數名的第一個字符必須是“@”,并符合標識符的規定;

          而在PL/SQL中,參數名除符合標識符的規定外沒有非凡說明,T-SQL中,對于參數可其數據類型及其長度和精度;但是PL/SQL中除了引用%TYPE和%ROWTYPE之外,不能在定義參數數據類型時給出長度和精度,如下:

      CREATE OR REPLACE  PROCEDURE PROC_SELE_YS

       (YSDM  CHAR(6),GZ NUMBER(14,4))

      AS

      BEGIN

        …

      END;

     是錯誤的,應如下定義

      CREATE OR REPLACE  PROCEDURE PROC_SELE_YS

       (YSDM  CHAR,GZ NUMBER)

      AS

      BEGIN

        …

      END;

     或者

      CREATE OR REPLACE  PROCEDURE PROC_SELE_YS

       (YSDM  YSDMB.YSDM%TYPE,GZ YSDMB.GZ%TYPE)

      AS

      BEGIN

        …

      END;

 

       5、對于T-SQL,游標聲明在主體SQL語句中,即聲明與使用語句同步;


          而在PL/SQL中,游標聲明在主體SQL語句之前,與局部變量聲明同步。

       6、對于T-SQL,在主體SQL語句中用如下語句對局部變量賦值(初始值或

          數據庫表的字段值或表達式):

           “SELECT 局部變量名 =  所賦值(初始值或數據庫表的字段值或表達式)”;

          而在PL/SQL中,將初始值賦給局部變量時,用如下語句:

           “局部變量名 : =  所賦值(初始值或表達式);” ,

          將檢索出的字段值賦給局部變量時,用如下語句:

           “SELECT 數據庫表的字段值 INTO 局部變量名 …” 。

       7、在PL/SQL中,可以使用%TYPE來定義局部變量的數據類型。說明如下:

          例如,students表的first_name列擁有類型VARCHAR2(20),基于這點,

          我們可以按照下述方式聲明一個變量:

              V_FirstName    VARCHAR2(20) ;

          但是假如改變了first_name列的數據類型則必須修改該聲明語句,因此可以采

          用%TYPE進行變量數據類型聲明:

             V_FirstName     students.first_name%TYPE ;

          這樣,該變量在存儲過程編譯時將由系統自動確定其相應數據類型。

8、對于T-SQL,沒有定義語句結束標志,而PL/SQL用“END <過程名>;”結束語句。

9、存儲過程的調用要注重:在MSSQLSERVER中的格式為“EXEC Procedure_Name {arg1,arg2,…},但在ORACLE中直接引用過程名即可,如要執行存儲過程DefaltNo,其參數為“9”,則執行時為 Default(“9”)。

10、ORACLE 數據庫的存儲過程不支持用select 子句直接返回一個數據集,要做到通過程產生一記錄集有兩種方案:

方案一:采用包和游標變量

第一步,創建一個包,定義一個游標變量

create package p_name
is
type cursor_name is ref cursor;
end;

第二步,創建過程,但是基返回參數用包中的游標類型
create procedure procedure_name(s in out p_name.cursor_name) is
begin
open s for select * from table_name...;
end;

這樣,通過存儲過程就可以返回一個數據集了,但用到這種情況,過程的參數中只這返回結果的游標參數可以帶要害字”OUT”,其它不能帶”out”,否則,系統會出現導常。

方案二:通過中間表,建一中間表,其表格的列為所需數據列再加上一個序列字段。過程的處理為將數據插入到中間表中,同時通過

select userenv(‘sessionid’) from dual;取得當前連接會話的序號,將取得的序號值放置到序列字段中,同時存儲過程返回連接會話的序號,前臺PB程序直接訪問中間表,數據窗口在檢索時通過序號參數可將所需的數據檢索出來。
<六> 觸發器
    <1>、SQL SERVER端語法說明

    1、語法:

           CREATE TRIGGER [owner.]trigger_name

           ON [owner.]table_name

           FOR { INSERT, UPDATE, DELETE }

             [WITH ENCRYPTION]

           AS

             sql_statement [...n]


       或者使用IF UPDATE子句:

           CREATE TRIGGER [owner.]trigger_name

           ON [owner.]table_name

           FOR { INSERT, UPDATE }

             [WITH ENCRYPTION]

           AS

             IF UPDATE (column_name)

             [{AND OR} UPDATE (column_name)…]

             sql_statement [ ...n]

 

     2、示例:

        IF EXISTS (SELECT 1 FROM sysobjects

                   WHERE name = 'reminder' AND type = 'TR')

          DROP TRIGGER reminder

        GO

 

        CREATE TRIGGER employee_insupd

               ON employee

              FOR INSERT, UPDATE

        AS

        /* Get the range of level for this job type from the jobs table. */

        DECLARE @min_lvl tinyint,

                    @max_lvl tinyint,

                    @emp_lvl tinyint,

                    @job_id  smallint

         SELECT @min_lvl = min_lvl,

                    @max_lvl = max_lvl,

                    @emp_lvl = i.job_lvl,

                    @job_id  = i.job_id

           FROM employee e, jobs j, inserted i

          WHERE e.emp_id = i.emp_id AND i.job = j.job_id

        IF (@job_id = 1) and (@emp_lvl <> 10)

        BEGIN


               RAISERROR ('Job id 1 eXPects the default level of 10.', 16, 1)

              ROLLBACK TRANSACTION

        END

        ELSE

        IF NOT (@emp_lvl BETWEEN @min_lvl AND @max_lvl)

        BEGIN

             RAISERROR ('The level for job_id:%d should be between %d and %d.',

                         16, 1, @job_id, @min_lvl, @max_lvl)

             ROLLBACK TRANSACTION

        END

        GO

 

    <2>、ORACLE端語法說明

    1、語法:

           CREATE [OR REPLACE] TRIGGER trigger_name

           { BEFORE AFTER } triggering_event ON  table_name

           [ FOR EACH ROW ]

           [ WHEN trigger_condition ]

           trigger_body ;

    2、使用說明與示例:

       (1)、上語法中,trigger_event 是對應于DML的三條語句INSERT、UPDATE、

             DELETE;table_name是與觸發器相關的表名稱;FOR EACH ROW是可選

             子句,當使用時,對每條相應行將引起觸發器觸發;condition是可選的

             ORACLE BOOLEAN條件,當條件為真時觸發器觸發;trigger_body是觸發

             器觸發時執行的PL/SQL塊。

 

       (2)、ORACLE觸發器有以下兩類:

             1> 語句級(Statement-level)觸發器,在CREATE TRIGGER語句中不

                包含FOR EACH ROW子句。語句級觸發器對于觸發事件只能觸發一次,

                而且不能訪問受觸發器影響的每一行的列值。一般用語句級觸發器處理

                有關引起觸發器觸發的SQL語句的信息——例如,由誰來執行和什么時

                間執行。


             2> 行級(Row-level)觸發器,在CREATE TRIGGER語句中

                包含FOR EACH ROW子句。行級觸發器可對受觸發器影響的每一行觸

                發,并且能夠訪問原列值和通過SQL語句處理的新列值。行級觸發器的

                典型應用是當需要知道行的列值時,執行一條事務規則。

 

        (3)在觸發器體內,行級觸發器可以引用觸發器觸發時已存在的行的列值,這些

             值倚賴于引起觸發器觸發的SQL語句。

             1> 對于INSERT語句,要被插入的數值包含在new.column_name,這里的

                column_name是表中的一列。

             2> 對于UPDATE語句,列的原值包含在old.column_name中,數據列的新

                值在new.column_name中。

             3> 對于DELETE語句,將要刪除的行的列值放在old.column_name中。

觸發語句

:old

:new

INSERT

無定義——所有字段都是NULL

當該語句完成時將要插入的數值

UPDATE

在更新以前的該行的原始取值

當該語句完成時將要更新的新值

DELETE

在刪除行以前的該行的原始取值

未定義——所有字段都是NULL

             4> 在觸發器主體中,在new和old前面的“:”是必需的。而在觸發器的

                WHEN子句中,:new和:old記錄也可以在WHEN子句的condition內部

                引用,但是不需要使用冒號。例如,下面CheckCredits觸發器的主體僅

                當學生的當前成績超過20時才會被執行:

                CREATE OR REPLACE TRIGGER CheckCredits

                   BEFORE INSERT OR UPDATE OF current_credits ON students

                   FOR EACH ROW

                   WHEN (new.current_credits > 20)

                BEGIN

                   /*Trigger body goes here. */

                END ;

                但CheckCredits也可以按下面方式改寫:


                CREATE OR REPLACE TRIGGER CheckCredits

                   BEFORE INSERT OR UPDATE OF current_credits ON students

                   FOR EACH ROW

                BEGIN

                   IF  :new.current_credits > 20  THEN

                      /*Trigger body goes here. */

                   END IF ;

                END ;

                注重,WHEN子句僅能用于行級觸發器,假如使用了它,那么觸發器主體

                僅僅對那些滿足WHEN子句指定的條件的行進行處理。

 

        (4)觸發器的主體是一個PL/SQL塊,在PL/SQL塊中可以使用的所有語句在觸

             發器主體中都是合法的,但是要受到下面的限制:

             1> 觸發器不能使用事務控制語句,包括COMMIT、ROLLBACK或

                SAVEPOINT。ORACLE保持這種限制的原因是:假如觸發器碰到錯誤時,

                由觸發器導致的所有數據庫變換均能被回滾(roll back)取消;但假如

                觸發器確認(commit)了對數據庫進行的部分變換,ORACLE就不能完全

                回滾(roll back)整個事務。

             2> 在觸發器主體中調用到的存儲過程的實現語句里也不能使用事務控制語

                句。

             3> 觸發器主體不能聲明任何LONG或LONG RAW變量。而且,:new和:old

                不能指向定義觸發器的表中的LONG或LONG RAW列。

             4> 當聲明觸發器的表中有外鍵約束時,假如將定義觸發器的表和需要作為

                DELETE CASCADE參考完整性限制的結果進行更新的表稱為變化表,

                將外鍵相關聯的表稱為限制表,則在此觸發器主體中的SQL語句不答應


                讀取或修改觸發語句的任何變化表,也不答應讀取或修改限制表中的主

                鍵、唯一值列或外鍵列。

 

        (5)以下是建立一個事前插入觸發器的示例:

             CREATE OR REPLACE TRIGGER Credit_Charge_Log_Ins_Before

                BEFORE insert ON Credit_Charge_Log

                FOR EACH ROW

             DECLARE

                Total_for_past_3days     number ;

             BEGIN

                -- Check the credit charges for the past 3 days.

                -- If they total more than $1000.00, log this entry

                -- int the Credit_Charge_Attempt_Log for further handling.

                select sum ( amount ) into total_for_past_3days

                  from Credit_Charge_Log

                 where Card_Number = :new.Card_Number

                   and Transaction_Date >= sysdate – 3;

                IF total_for_past_3days > 1000.00 THEN

                   insert into credit_Charge_Attemp_Log

                     (Card_Number, Amount, Vendor_ID, Transaction_Date)

                   values

                     (:new.Card_Number, :new.Amount,

                      :new.Vendor_ID, :new.Transaction_Date);

                END IF ;


             END ;

 

<3>、從SQL SERVER向ORACLE的遷移方案

 

         1、通過比較上面SQL語法的不同并考慮現有SQL SERVER的實際編程風格,在從

            T-SQL向PL/SQL遷移時,要遵守下面規則:

            1> 在CREATE TRIGGER定義中采用AFTER要害字,即調整為事后觸發器。

            2> 在CREATE TRIGGER定義中采用FOR EACH ROW要害字,即調整為行級觸發

               器。

            3> 將觸發器主體中的“inserted”調整為“:new”,將“deleted”調整為“:old”。

            4> 在觸發器主體中禁用CURSOR操作:new與:old。

            5> 在觸發器主體中禁用COMMIT、ROLLBACK、SAVEPOINT等事務控制語句。

 

         2、用觸發器解決ID列向SEQUENCE遷移的問題:

            下面的GenerateStudentID觸發器使用了:new。這是一個before INSERT觸

            發器,其目的是使用student_sequence序列所產生的數值填寫

            students表的ID字段。

            例:

            CREATE OR REPLACE TRIGGER GenerateStudentID

               BEFORE INSERT ON students

               FOR EACH ROW

            BEGIN

               SELECT student_sequence.nextval

                 INTO :new.ID

                 FROM dual;

            END;

            在上面的觸發器主體中,GenerateStudentID實際上修改了:new.ID的值。這

            是:new最有用的一個特性——當該語句真正被執行時,:new中的存儲內容就

            將被使用。有了這個觸發器,我們就可以使用下面這樣的INSERT語句,而不

            會產生錯誤:

               INSERT INTO students (first_name, last_name)


               VALUES (‘LUO’, ‘TAO’) ;

            盡管我們沒有為主鍵列ID(這是必需的)指定取值,觸發器將會提供所需要

            的取值。事實上,假如我們為ID指定了一個取值,它也將會被忽略,因為觸

            發器修改了它。假如我們使用下面的語句:

               INSERT INTO students (ID, first_name, last_name)

               VALUES (-789, ‘LUO’, ‘TAO’) ;

            其處理結果還是相同的。無論在哪種情況下,student_sequence.nextval都

            將用作ID列值。

 

            由此討論,可以采用這種方法處理SQL SERVER中ID列向ORACLE的SEQUENCE

            轉換的問題。

 

            另外,由于上面的原因,我們不能在after行級觸發器中修改 :new,因為該

            語句已經被處理了。通常,:new僅僅在before行級觸發器中被修改,而:old

            永遠不會被修改,僅僅可以從它讀出數據。

 

            此外,:new和:old記錄僅僅在行級觸發器內部是有效的。假如試圖要從語句

            級觸發器進行引用,將會得到一個編譯錯誤。因為語句級觸發器只執行一次

            ——盡管語句要處理許多行——所以:new和:old是沒有意義的,因為怎么確

            定它們引用的會是哪一行呢?

            
<七> 常用SQL語法與函數
    <1>、SQL SERVER端常用語法說明

    1、使用局部變量:

       1> 變量定義:

              DECLARE @variable_name datatype [,…]

          例:

              declare

                 @name    varchar(30),

                 @type   int

       2> 給變量賦值:

         方法一:

              例:

                  declare @int_var    int


                  select @int_var = 12

         方法二:

              例:

                  declare

                     @single_auth    varchar(40),

                     @curdate        datetime

                  select @single_auth = au_lname,

                         @curdate     = getdate()

                    from authors

                   where au_id = ‘123-45-6789’

 

2、使用T-SQL標準控制結構:

       1> 定義語句塊

          語法:

              BEGIN

                 Statements

              END

 

       2> IF ... ELSE語句

          語法:

              IF boolean_expression

                 { statement statement_block }

              ELSE

                 { statement statement_block }

          示例:

              if (select avg(price) from titles where type = ‘business’) > $19.95

                  print ‘The average price is greater then $19.95’

              else

                  print ‘The average price is less then $19.95’


 

       3> IF EXISTS語句

          語法:

              IF [not] EXISTS (select_statement)

                 { statement statement_block }

              [ELSE

                 { statement statement_block }]

          示例:

              declare

                 @lname      varchar(40),

                 @msg        varchar(255)

              select @lname = ‘Smith’

              if exists(select * from titles where au_lname = @lname)

                 begin

                    select @msg = ‘There are authors named’ + @lname

                    print @msg

                 end

              else

                 begin

                    select @msg = ‘There are no authors named’ + @lname

                    print @msg

                 end

 

       4> 循環語句:

          WHILE

          語法:

              WHILE boolean_condition

                 [{ statement statement_block }]

              [BREAK]


              [condition]

          示例:

              declare

                 @avg_price              money,

                 @max_price              money,

                 @count_rows             int,

                 @times_thru_the_loop int

              select @avg_price            = avg(price),

                     @max_price            = max(price),

                     @count_rows           = count(*),

                     @times_thru_the_loop = 0

                from titles

              while @avg_price < $25 and (@count_rows < 10 or @max_price < $50)

              begin

                 select @avg_price          = avg(price) * 1.05,

                        @max_price          = max(price) * 1.05,

                        @time_thru_the_loop = @time_thru_the_loop + 1

              end

              if @time_thru_the_loop = 0

                 select @time_thru_the_loop = 1


              update titles

                 set price = price * power(1.05, @time_thru_the_loop)

 

       4> GOTO語句

          語法:

              GOTO label

              ...

              label:

          示例:

              begin transaction

                 insert tiny(c1) values(1)

                 if @@error != 0 goto error_handler

                 commit transaction

                 return

              error_handler:

                 rollback transaction

                 return

 

       5> RETURN語句

          語法:

              RETURN

          (1)用于無條件退出一個批處理、存儲過程或觸發器。

               示例:

                   if not exists(select 1 from inventory

                                  where item_num = @item_num)

                   begin

                      raiseerror 51345 ‘Not Found’

                      return

                   end


                   print ‘No error found’

                   return

          (2)用于存儲過程中返回狀態值。

               示例:

                   create procedure titles_for_a_pub

                          (@pub_name varchar(40) = null)

                   as

                   if @pub_name is null

                      return 15

                   if not exists(select 1 from publishers

                                  where pub_name = @pub_name)

                      return –101

                   select t.tile from publishers p, titles t

                    where p.pub_id = t.pub_id

                      and pub_name = @pub_name

                   return 0

 

    3、T-SQL中的游標提取循環語句:

   (1)FETCH [NEXT FROM] cursor_name INTO @variable_1, ...@variable_n

   (2)WHILE @@FETCH_STATUS = 0

        BEGIN

           Other_statements

           FETCH [NEXT FROM] cursor_name INTO @variable_1, ...@variable_n

        END

   (3)CLOSE cursor_name

 

    4、T-SQL中的事務處理語句:

       1> 開始一個事務:

          BEGIN TRAN[SACTION [transaction_name]]


 

       2> 提交一個事務:

          COMMIT TRAN[SACTION [transaction_name]]

 

       3> 回滾一個事務:

          ROLLBACK TRAN[SACTION [transaction_name]]

 

       4> 使用事務保存點:

          BEGIN TRAN[SACTION [transaction_name]]

             SAVE TRAN[SACTION] savepoint_name

             ROLLBACK TRAN[SACTION] savepoint_name

          COMMIT TRAN[SACTION [transaction_name]]

 

    5、T-SQL中可用于錯誤判定或其它處理的全局變量:

       1>  @@rowcount:        前一條命令處理的行數

       2>  @@error:           前一條SQL語句報告的錯誤號

       3>  @@trancount:        事務嵌套的級別

       4>  @@transtate:        事務的當前狀態

       5>  @@tranchained:  當前事務的模式(鏈接的(chained)或非鏈接的)

       6>  @@servername:    本地SQL SERVER的名稱

       7>  @@version   :        SQL SERVER和O/S的版本級別

       8>  @@spid:            當前進程的id

       9>  @@identity:        上次insert操作中使用的identity值

       10> @@nestlevel:        存儲過程/觸發器中的嵌套層

       11> @@fetch_status: 游標中上條fetch語句的狀態

 

    6、使用標準內置錯誤消息發送函數:

       函數說明:

           RAISERROR ({msg_id msg_str}, severity, state

           [, argument1 [,argument2][,...] )

           [WITH LOG]

 

       其中,msg_id表示錯誤號,用戶定義錯誤消息的錯誤號在50001到2147483647之

       間,特定的消息會引起錯誤50000。msg_str是錯誤消息正文,最多可有255個字

       符。Severity描述了與這個消息關聯的用戶定義的嚴重性級別,取值包括0和10

       至25之間的任何整數。State描述了錯誤的“調用狀態”,它是1到127之間的整

       數值。Argument定義用于代替在msg_str中定義的變量或對應與msg_id的消息的


       參數。WITH LOG表示要在服務器錯誤日志和事件日志中記錄錯誤。

       例1:

          RAISEERROR( ‘Invalid customer id in order.’, 16, 1)

          則返回:

              Msg 50000, Level 16, State 1

              Invalid customer id in order.

       例2:

          sp_addmessage 52000, 16, ‘Invalid customer id %s in order’

          RAISEERROR( 52000, 16, 1, ‘ID52436’)

          則返回:

              Msg 52000, Level 16, State 1

              Invalid customer id ID52436 in order.

   

    <2>、ORACLE端常用語法說明

    1、使用局部變量:

       1> 定義變量:

          VARIABLE_NAME   DATA TYPE   [ := INITIAL VALUE ] ;

          例:定義變量

              v_Num       number;

              v_string    varchar2(50);

          例:定義變量并賦初值

              v_Num       number := 1 ;

              v_string    varchar2(50) := ‘Hello world!’ ;

       2> 給變量賦值:

         方法一:

              例:

                  v_Num      := 1;

                  v_string := ‘Hello world!’;

         方法二:

              例:

                  SELECT first_name INTO v_String

                    FROM students


                   WHERE id = v_Num ;

 

    2、使用PL/SQL標準控制結構:

       1> 定義語句塊

          語法:

              BEGIN

                 Statements ;

              END ;

 

       2> IF ... THEN ... ELSE語句

          語法:

              IF boolean_expression THEN

                 { statement statement_block } ;

              [ELSIF boolean_expression THEN      /*注重此處的寫法—— ELSIF */

                 { statement statement_block } ;]

              ...

              [ELSE

                 { statement statement_block } ;]

              END IF ;

 

          示例:

              v_NumberSeats rooms.number_seats%TYPE;

              v_Comment VARCHAR2(35);

              BEGIN

              /* Retrieve the number of seats in the room identified by ID 99999.

                 Store the result in v_NumberSeats. */

                SELECT number_seats

                  INTO v_NumberSeats

                  FROM rooms

                 WHERE room_id = 99999;

                IF v_NumberSeats < 50 THEN


                   v_Comment := 'Fairly small';

                ELSIF v_NumberSeats < 100 THEN

                   v_Comment := 'A little bigger';

                ELSE

                   v_Comment := 'Lots of room';

                END IF;

              END;

 

       3> 循環語句:

         (1)簡單循環語句:

              語法:

                  LOOP

                     { statement statement_block } ;

                     [EXIT [WHEN condition] ;]

                  END LOOP ;

                  其中,語句EXIT [WHEN condition];等價于

                      IF condition THEN

                         EXIT ;

                      END IF ;

              示例1:

                  v_Counter BINARY_INTEGER := 1;

                  BEGIN

                    LOOP

                      -- Insert a row into temp_table with the current value of the

                      -- loop counter.


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 攀枝花市| 泰和县| 延川县| 德保县| 云安县| 长沙市| 宽甸| 大竹县| 收藏| 仪征市| 皋兰县| 盘锦市| 远安县| 石渠县| 平利县| 巴中市| 云霄县| 成都市| 舞钢市| 大庆市| 辉南县| 深州市| 台东市| 来宾市| 德州市| 盐池县| 广丰县| 鹤庆县| 双鸭山市| 嘉兴市| 邻水| 仁布县| 彩票| 平顶山市| 丽江市| 渭源县| 镇远县| 江达县| 建湖县| 黔西县| 徐州市|