程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> 更多數據庫知識 >> ORACLE 系統函數大全SQLSERVER系統函數的異同

ORACLE 系統函數大全SQLSERVER系統函數的異同

編輯:更多數據庫知識

字符函數

下面是Oracle支持的字符函數和它們的Microsoft SQL Server等價函數。

函數 Oracle Microsoft SQL Server
把字符轉換為ASCII :ASCII ASCII
字串連接: CONCAT --------------(expression + expression)
把ASCII轉換為字符 CHR, CHAR
返回字符串中的開始字符(左起) INSTR ,---------------CHARINDEX
把字符轉換為小寫 LOWER ---------------------LOWER
把字符轉換為大寫 UPPER-------------------- UPPER
填充字符串的左邊 LPAD --------------------N/A
清除開始的空白 LTRIM--------------------LTRIM
清除尾部的空白 RTRIM --------------------RTRIM
字符串中的起始模式(pattern) INSTR --------------------PATINDEX
多次重復字符串 RPAD --------------------REPLICATE
字符串的語音表示 SOUNDEX --------------------SOUNDEX
重復空格的字串 RPAD --------------------SPACE
從數字數據轉換為字符數據 TO_CHAR --------------------STR
子串 SUBSTR --------------------SUBSTRING
替換字符 REPLACE --------------------STUFF
將字串中的每個詞首字母大寫 INITCAP --------------------N/A
翻譯字符串 TRANSLATE --------------------N/A
字符串長度 LENGTH-------------------- DATELENGTH or LEN
列表中最大的字符串 GREATEST-------------------- N/A
列表中最小的字符串 LEAST --------------------N/A
如果為NULL則轉換字串 NVL-------------------- ISNULL

日期函數

下面是Oracle支持的日期函數和它們的Microsoft SQL Server等價函數。

函數 Oracle --------------------Microsoft SQL Server
日期相加 (date column +/- value) or ADD_MONTHS  --------------------DATEADD

兩個日期的差 (date column +/- value) or MONTHS_BETWEEN  --------------------DATEDIFF
當前日期和時間 SYSDATE --------------------GETDATE()
一個月的最後一天 LAST_DAY  --------------------N/A
時區轉換 NEW_TIME  --------------------N/A
日期後的第一個周日 NEXT_DAY  --------------------N/A
代表日期的字符串 TO_CHAR --------------------DATENAME
代表日期的整數 TO_NUMBER (TO_CHAR))  --------------------DATEPART
日期捨入 ROUND  --------------------CONVERT
日期截斷 TRUNC  --------------------CONVERT
字符串轉換為日期 TO_DATE  --------------------CONVERT
如果為NULL則轉換日期 NVL -------------------- ISNULL

轉換函數

下面是Oracle支持的轉換函數和它們的Microsoft SQL Server等價函數。

函數 Oracle  --------------------Microsoft SQL Server
數字轉換為字符 TO_CHAR  --------------------CONVERT
字符轉換為數字 TO_NUMBER  --------------------CONVERT
日期轉換為字符 TO_CHAR  --------------------CONVERT
字符轉換為日期 TO_DATE CONVERT
16進制轉換為2進制 HEX_TO_RAW  --------------------CONVERT
2進制轉換為16進制 RAW_TO_HEX  --------------------CONVERT

其它行級別的函數

下面是Oracle支持的其它行級別的函數以及它們的Microsoft SQL Server等價函數。

函數 Oracle  --------------------Microsoft SQL Server
返回第一個非空表達式 DECODE -------------------------------------COALESCE
當前序列值 CURRVAL  --------------------N/A
下一個序列值 NEXTVAL  --------------------N/A

用戶登錄賬號ID數字 UID --------------------SUSER_ID
用戶登錄名 USER  --------------------SUSER_NAME
用戶數據庫ID數字 UID  --------------------USER_ID
用戶數據庫名 USER  --------------------USER_NAME
當前用戶 CURRENT_USER -------------------- CURRENT_USER
用戶環境(audit trail) USERENV  --------------------N/A
在CONNECT BY子句中的級別 LEVEL  --------------------N/A

合計函數

下面是Oracle支持的合計函數和它們的Microsoft SQL Server等價函數。

函數 Oracle  --------------------Microsoft SQL Server
Average AVG -------------------- AVG
Count COUNT  --------------------COUNT
Maximum MAX -------------------- MAX
Minimum MIN  --------------------MIN
Standard deviation STDDEV  --------------------STDEV or STDEVP
Summation SUM -------------------- SUM
Variance VARIANCE  --------------------VAR or VARP

條件測試

Oracle的DECODE語句和Microsoft SQL Server的CASE表達式都執行條件測試。
當test_value中的值和後面的任何表達式匹配的時候,相關的值就返回。如果沒有找到任何匹配的值,就返回default_value。
如果沒有指定default_value,在沒有匹配的時候,DECODE和CASE都返回一個NULL。下表顯示了該語句的語法,
同時給出了轉換DECODE命令的示例。

Oracle Microsoft SQL 
DECODE (test_value,
expression1, value1
<,expression2, value2] […>
[,default_value]
)
CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(DECODE(grade
,'A', 4
,'A+', 4.3
,'A-', 3.7
,'B', 3
,'B+', 3.3
,'B-', 2.7
,'C', 2
,'C+', 2.3
,'C-', 1.7
,'D', 1
,'D+', 1.3
,'D-', 0.7
,0)),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN
CASE input_expression
WHEN when_expression THEN    result_expression

[ELSE else_result_expression]
END
CREATE VIEW STUDENT_ADMIN.STUDENT_GPA
(SSN, GPA)
AS SELECT SSN, ROUND(AVG(CASE grade
WHEN 'A' THEN 4
WHEN 'A+' THEN 4.3
WHEN 'A-' THEN 3.7
WHEN 'B' THEN 3
WHEN 'B+' THEN 3.3
WHEN 'B-' THEN 2.7
WHEN 'C' THEN 2
WHEN 'C+' THEN 2.3
WHEN 'C-' THEN 1.7
WHEN 'D' THEN 1
WHEN 'D+' THEN 1.3
WHEN 'D-' THEN 0.7
ELSE 0
END),2)
FROM STUDENT_ADMIN.GRADE
GROUP BY SSN

CASE表達式可以支持用SELECT語句執行布爾測試,這是DECODE命令所不允許的。欲了解關於CASE表達式的詳細信息,
請參閱SQL Server聯機手冊。

把值轉換為不同的數據類型

Microsoft SQL Server的CONVERT和CAST函數都是多目標轉換函數。它們提供了相似的功能,
把一種數據類型的表達式轉換為另一種數據類型的表達式,並且支持多種專門數據的格式。

CAST(expression AS data_type)
CONVERT (data type[(length)], expression [, style])
CAST是一個SQL-92標准的函數。這些函數執行同Oracle的TO_CHAR、TO_NUMBER、TO_DATE、HEXTORAW以及RAWTOTEXT函數相同的功能。

這裡所指的數據類型是任何表達式將被轉換成為的系統數據類型。不能使用用戶定義的數據類型。長度參數是可選的,
該參數用於char、varchar、binary以及varbinary數據類型。允許的最大長度是8000。

轉換 Oracle Microsoft SQL Server
字符到數字 TO_NUMBER(ཆ')  --------------------CONVERT(numeric, ཆ')
數字到字符 TO_CHAR(10)  --------------------CONVERT(char, 10)
字符到日期 TO_DATE(ཀ-JUL-97')
TO_DATE(ཀ-JUL-1997','dd-mon-yyyy')

TO_DATE('July 4, 1997', 'Month dd, yyyy') --------------------CONVERT(datetime, ཀ-JUL-97')

CONVERT(datetime, ཀ-JUL-1997')
CONVERT(datetime, 'July 4, 1997')
日期到字符 TO_CHAR(sysdate)
TO_CHAR(sysdate, 'dd mon yyyy')
TO_CHAR(sysdate, 'mm/dd/yyyy') --------------------CONVERT(char, GETDATE())
CONVERT(char, GETDATE(), 106)
CONVERT(char, GETDATE(), 101)
16進制到2進制 HEXTORAW(ƇF')-------------------- CONVERT(binary, ƇF')
2進制到16進制 RAWTOHEX(binary_column) --------------------CONVERT(char, binary_column)

請注意字符串是怎樣轉換為日期的。在Oracle中,缺省的日期格式模型是"DD-MON-YY"如果你使用任何其它格式,
你必須提供一個合適的日期格式模型。CONVERT函數自動轉換標准日期格式,不需要任何格式模型。

從日期轉換到字符串時,CONVERT函數的缺省輸出是"dd mon yyyy hh:mm:ss:mmm(24h)"。
用一個數字風格代碼來格式化輸出,使它能輸出為其它類型的日期格式模型。欲了解CONVERT函數的詳細信息,請參閱SQL Server聯機手冊。

下表顯示了Microsoft SQL Server日期的缺省輸出。

Without Century With Century Standard Output
- 0 or 100 (*) Default mon dd yyyy hh:miAM (or PM)
1 101 USA mm/dd/yy
2 102 ANSI yy.mm.dd
3 103 British/French dd/mm/yy
4 104 German dd.mm.yy
5 105 Italian dd-mm-yy
6 106 - dd mon yy
7 107 - mon dd, yy
8 108 - hh:mm:ss
- 9 or 109 (*) Default milliseconds mon dd yyyy hh:mi:ss:mmm (AM or PM)
10 110 USA mm-dd-yy
11 111 Japan yy/mm/dd
12 112 ISO yymmdd
- 13 or 113 (*) Europe default dd mon yyyy hh:mm:ss:mmm(24h)
14 114 - hh:mi:ss:mmm(24h)

用戶自定義函數

Oracle PL/SQL函數可以在Oracle SQL語句中使用。在Microsoft SQL Server中一般可以通過其它方式來實現同樣的功能。

在SQL Server中可以用表中給出的查詢來代替。

Oracle Microsoft SQL Server
SELECT SSN, FNAME, LNAME, )    TUITION_PAID,
   TUITION_PAID/GET_SUM_
   MAJOR(MAJOR)
   AS PERCENT_MAJOR
FROM STUDENT_ADMIN.STUDENT SELECT SSN, FNAME, LNAME, TUITION_PAID, TUITION_PAID/SUM_MAJOR AS PERCENT_MAJOR
FROM STUDENT_ADMIN.STUDENT,
  (SELECT MAJOR,      SUM(TUITION_PAID) SUM_MAJOR
  FROM STUDENT_ADMIN.STUDENT
  GROUP BY MAJOR) SUM_STUDENT
WHERE STUDENT.MAJOR =      SUM_STUDENT.MAJOR
CREATE OR REPLACE FUNCTION GET_SUM_MAJOR
(INMAJOR VARCHAR2) RETURN NUMBER
AS SUM_PAID NUMBER;
BEGIN
SELECT SUM(TUITION_PAID) INTO    SUM_PAID
FROM STUDENT_ADMIN.STUDENT
WHERE MAJOR = INMAJOR;
RETURN(SUM_PAID);
END GET_SUM_MAJOR; No CREATE FUNCTION syntax is required; use CREATE PROCEDURE syntax.

比較操作符

Oracle和Microsoft SQL Server的比較操作符幾乎是一樣的。

算符 Oracle Microsoft SQL Server
等於 (=) (=)
大於 (>) (>)
小於 (<) (<)
大於或等於 (>=) (>=)
小於或等於 (<=) (<=)
不等於 (!=, <>, ^=) (!=, <>, ^=)
不大於,不小於 N/A !> , !<
在集合中任意成員中 IN IN
不在集合中的任何成員中 NOT IN NOT IN
集合中的任意值 ANY, SOME ANY, SOME
提交集合中的所有值 != ALL, <> ALL, < ALL,
> ALL, <= ALL, >= ALL, != SOME, <> SOME,
< SOME, > SOME,
<= SOME, >= SOME != ALL, <> ALL, < ALL,
> ALL, <= ALL, >= ALL, != SOME, <> SOME,
< SOME, > SOME,
<= SOME, >= SOME
像模式(Like pattern) LIKE LIKE
不像模式(Not like pattern) NOT LIKE NOT LIKE
X和y之間的值 BETWEEN x AND y BETWEEN x AND y
不在x和y之間的值 NOT BETWEEN NOT BETWEEN
值存在 EXISTS EXISTS
值不存在 NOT EXISTS NOT EXISTS
值{為|不為}空 IS NULL, IS NOT NULL Same. Also = NULL,
!= NULL for backward compatibility (not recommended).

模式匹配

SQL Server的LIKE關鍵字提供了有用的通配符搜索功能,這個功能在Oracle中不支持
除了所有的RDBMS都支持的(%)和(_)通配符以外,SQL Server還支持([ ])和([^])通配符。

([ ])字符用來查詢在一個范圍內的所有單個字符。例如,如果你需要查詢包含一個從a到f的字符的數據,
你可以這樣寫:“LIKE '[a-f]'”或者“LIKE '[abcdef]'”。這些附加的通配符的有效性在下表中給出。

Oracle:
SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE 'A%'
OR LNAME LIKE 'B%'
OR LNAME LIKE 'C%' ;

Microsoft SQL:

SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE '[ABC]%';

[^]通配符用來標記那些不在特定范圍內的字符。例如,如果除了a到f以外的所有字符都是可以接受的,你可以這樣書寫:
LIKE '[^a - f]'或者LIKE '[^abcdef]'。

欲了解關於LIKE關鍵字的詳細信息,請參閱SQL Server聯機手冊。

在比較中使用NULL

盡管Microsoft SQL Server傳統上支持SQL-92標准的和一些非標准的NULL行為,但是它還是支持Oracle中的NULL的用法。

為了支持分布式查詢,SET ANSI_NULLS必須設定為ON。

在進行連接的時候,SQL Server的SQL Server ODBC驅動程序和OLE DB提供者自動把SET ANSI_NULLS設定為ON。
這個設置可以在ODBC數據源、ODBC連接屬性、或者是在連接到SQL Server之前在應用程序中設置的OLE DB連接屬性中進行配置。
在從DB-Library應用程序中連接時,SET ANSI_NULLS缺省為OFF。

當SET ANSI_DEFAULTS為ON時,SET ANSI_NULLS被允許。

欲了解關於NULL用法的詳細信息,請參閱SQL Server聯機手冊。

字串連接

Oracle使用兩個管道符號(||)來作為字串連接操作符,SQL Server則使用加號(+)。這個差別要求你在應用程序中做小小的修改。

Oracle:  
SELECT FNAME||' '||LNAME AS NAME
FROM STUDENT_ADMIN.STUDENT;

/
-----------------------------------------------

Microsoft SQL:
 SELECT FNAME +' '+ LNAME AS    NAME
FROM STUDENT_ADMIN.STUDENT

流控制(Control-of-Flow)語言

流控制語言控制SQL語句執行流,語句塊以及存儲過程。PL/SQL和Transact-SQL提供了多數相同的結構,但是還是有一些語法差別。

關鍵字

這是兩個RDBMS支持的關鍵字。

語句 Oracle PL/SQL :

聲明變量 DECLARE DECLARE
語句塊 BEGIN...END; BEGIN...END
條件處理 IF…THEN,
ELSIF…THEN,
ELSE
ENDIF;
--------------------------------------------------------

Microsoft SQL Server Transact-SQL:
IF…[BEGIN…END]
ELSE <condition>
[BEGIN…END]
ELSE IF <condition>
CASE expression
無條件結束 RETURN------------ RETURN
無條件結束當前程序塊後面的語句 EXIT BREAK
重新開始一個WHILE循環 N/A CONTINUE
等待指定間隔 N/A (dbms_lock.sleep) WAITFOR
循環控制 WHILE LOOP…END LOOP;
------------
LABEL…GOTO LABEL;
FOR…END LOOP;
LOOP…END LOOP;
WHILE <condition>
BEGIN… END
LABEL…GOTO LABEL

程序注釋 /* … */, -- /* … */, --
打印輸出 RDBMS_OUTPUT.PUT_LINE PRINT

引發程序錯誤(Raise program error) RAISE_APPLICATION_ERROR --------------------RAISERROR

執行程序 EXECUTE----------------------EXECUTE
語句終止符 Semicolon (;) ------------------N/A

聲明變量

Transact-SQL和PL/SQL的變量是用DECLARE關鍵字創建的。Transact-SQL變量用@標記,
並且就像PL/SQL一樣,在第一次創建時,用空值初始化。

Oracle :  
DECLARE
VSSN CHAR(9);
VFNAME VARCHAR2(12);
VLNAME VARCHAR2(20);
VBIRTH_DATE DATE;

VLOAN_AMOUNT NUMBER(12,2);
-----------------------------------------

Microsoft SQL:
DECLARE
@VSSN CHAR(9),
@VFNAME VARCHAR2(12),
@VLNAME VARCHAR2(20),
@VBIRTH_DATE DATETIME,
@VLOAN_AMOUNT NUMERIC(12,2)

Transact-SQL不支持%TYPE和%ROWTYPE變量數據類型定義。一個Transact-SQL變量不能在DECLARE命令中初始化。
在Microsoft SQL Server數據類型定義中也不能使用Oracle的NOT NULL和CONSTANT關鍵字。

像Oracle的LONG和LONG RAW數據類型一樣。文本和圖形數據類型不能被用做變量定義。
此外,Transact-SQL不支持PL/SQL風格的記錄和表的定義。

給變量賦值

Oracle和Microsoft SQL Server提供了下列方法來為本地變量賦值。

Oracle Microsoft SQL 
Assignment operator (:=) ---------------------SET @local_variable = value
SELECT...INTO syntax for selecting column values from a single row
-------------------------
SELECT @local_variable = expression [FROM…] for assigning a literal value,
 an expression involving other local variables, or a column value from a single row

FETCH…INTO syntax------------------------------- FETCH…INTO syntax

這裡有一些語法示例

Oracle:
DECLARE VSSN CHAR(9);
VFNAME VARCHAR2(12);
VLNAME VARCHAR2(20);
BEGIN
VSSN := ?';
SELECT FNAME, LNAME INTO VFNAME, VLNAME FROM STUDENTS WHERE SSN=VSSN;
END;

/
------------------------------------------------------------------------------

Microsoft SQL:
DECLARE @VSSN CHAR(9),
@VFNAME VARCHAR(12),
@VLNAME VARCHAR(20)
SET @VSSN = ?'
SELECT @VFNAME=FNAME, @VLNAME=LNAME FROM STUDENTS WHERE SSN = @VSSN

語句塊

Oracle PL/SQL和Microsoft SQL Server Transact-SQL都支持用BEGIN…END術語來標記語句塊。
Transact-SQL不需要在DECLARE語句後使用一個語句塊。
---------------------------------------------------------------------------------
-如果在Microsoft SQL Server
中的IF語句和WHILE循環中有多於一個語句被執行,則需要使用BEGIN…END語句塊。

Oracle: Microsoft SQL:
DECLARE
DECLARE VARIABLES ...
BEGIN -- THIS IS REQUIRED SYNTAX
PROGRAM_STATEMENTS ...
IF ...THEN
STATEMENT1;
STATEMENT2;
STATEMENTN;
END IF;
WHILE ... LOOP
STATEMENT1;
STATEMENT2;
STATEMENTN;
END LOOP;
END; -- THIS IS REQUIRED SYNTAX DECLARE
DECLARE VARIABLES ...
BEGIN -- THIS IS OPTIONAL SYNTAX
PROGRAM_STATEMENTS ...
IF ...
BEGIN
STATEMENT1
STATEMENT2
STATEMENTN
END
WHILE ...
BEGIN
STATEMENT1
STATEMENT2
STATEMENTN
END
END -- THIS IS REQUIRED SYNTAX

條件處理

Microsoft SQL Server Transact-SQL的條件語句包括IF和ELSE,但不包括Oracle PL/SQL中的ELSEIF語句。
可以用嵌套多重IF語句來到達同樣的效果。對於廣泛的條件測試,用CASE表達式也許更容易和可讀一些。

Oracle Microsoft SQL 
DECLARE
VDEGREE_PROGRAM CHAR(1);
VDEGREE_PROGRAM_NAME VARCHAR2(20);
BEGIN
VDEGREE_PROGRAM := 'U';
IF VDEGREE_PROGRAM = 'U' THEN VDEGREE_PROGRAM_NAME := 'Undergraduate';

ELSIF VDEGREE_PROGRAM = 'M' THEN VDEGREE_PROGRAM_NAME := 'Masters';
ELSIF VDEGREE_PROGRAM = 'P'  THEN VDEGREE_PROGRAM_NAME := 'PhD';
ELSE VDEGREE_PROGRAM_NAME := 'Unknown';
END IF;
END;

/

-----------------------------------------------------
DECLARE
@VDEGREE_PROGRAM CHAR(1),
@VDEGREE_PROGRAM_NAME VARCHAR(20)
set @VDEGREE_PROGRAM = 'U'
SELECT @VDEGREE_PROGRAM_NAME =

        CASE @VDEGREE_PROGRAM
   WHEN 'U' THEN 'Undergraduate'
   WHEN 'M' THEN 'Masters'
   WHEN 'P' THEN 'PhD'.
   ELSE 'Unknown'
        END

重復執行語句(循環)

Oracle PL/SQL提供了無條件的LOOP和FOR LOOP。Transact-SQL則提供了WHILE循環和GOTO語句。

WHILE Boolean_expression
{sql_statement | statement_block}

[BREAK] [CONTINUE]

WHILE循環需要測試一個布爾表達式來決定一個或者多個語句的重復執行。
只要給定的表達式結果為真,這個(些)語句就一直重復執行下去。如果有多個語句需要執行,則這些語句必須放在一個BEGIN…END塊中。

Oracle:  
DECLARE
COUNTER NUMBER;
BEGIN
COUNTER := 0;
WHILE (COUNTER <5) LOOP
COUNTER := COUNTER + 1;
END LOOP
END;

/
------------------------------------------------------

Microsoft SQL:
DECLARE
@COUNTER NUMERIC
SELECT @COUNTER = 1
WHILE (@COUNTER <5)
BEGIN
   SELECT @COUNTER =
   @COUNTER +1
END

語句的執行可以在循環的內部用BREAK和CONTINUE關鍵字控制。BREAK關鍵字使WHILE循環無條件的結束,
而CONTINUE關鍵字使WHILE循環跳過後面的語句重新開始。BREAK關鍵字同Oracle PL/SQL中的EXIT關鍵字是等價的。
而在Oracle中沒有和CONTINUE等價的關鍵字

GOTO語句

Oracle和Microsoft SQL Server都有GOTO語句,但是語法不同。GOTO語句使Transact-SQL跳到指定的標號處運行,
在GOTO語句後指定標號之間的任何語句都不會被執行。

Oracle Microsoft SQL 
GOTO label;
<<label name here>> GOTO label

PRINT語句

Transact-SQL的PRINT語句執行同PL/SQL的RDBMS_OUTPUT.put_line 過程同樣的操作。該語句用來打印用戶給定的消息。

用PRINT語句打印的消息上限是8,000個字符。定義為char或者varchar數據類型的變量可以嵌入打印語句。
如果使用其它數據類型的變量,則必須使用CONVERT或者CAST函數。本地變量、全局變量可以被打印。可以用單引號或者雙引號來封閉文本。

從存儲過程返回

Microsoft SQL Server和Oracle都有RETURN語句。RETURN使你的程序從查詢或者過程中無條件的跳出。RETURN是立即的、
完全的、並且可以用於從過程、批處理或者語句塊的任意部分跳出。在REUTRN後面的語句將不會被執行。

Oracle Microsoft SQL 
RETURN expression: RETURN [integer_expression]

引發程序錯誤(Raising program errors)

Transact-SQL的RAISERROR返回一個用戶定義的錯誤消息,並且設置一個系統標志來記錄發生了一個錯誤。
這個功能同PL/SQL的raise_application_error異常處理器的功能是相似的。

RAISERROR語句允許客戶重新取得sysmessages表的一個入口,或者用用戶指定的嚴重性和狀態信息動態的建立一條消息。
在被定義後,消息被送回客戶端作為系統錯誤消息。

RAISERROR ({msg_id | msg_str}, severity, state
[, argument1 [, argument2>)

[WITH options]

在轉換你的PL/SQL程序時,也許用不著使用RAISERROR語句。在下面的示例代碼中。
PL/SQL程序使用raise_application_error異常處理器,但是Transact-SQL程序則什麼也沒用。
包括raise_application_error異常處理器是為了防止PL/SQL返回不明確的未經處理的異常錯誤消息。
作為代替,當一個不可預見的問題發生的時候,異常處理器總是返回Oracle錯誤消息。

當一個Transact-SQL失敗時,它總是返回一個詳細的錯誤消息給客戶程序。因此,除非需要某些特定的錯誤處理,
一般是不需要RAISERROR語句的。

Oracle Microsoft SQL 
CREATE OR REPLACE FUNCTION
DEPT_ADMIN.DELETE_DEPT
(VDEPT IN VARCHAR2) RETURN NUMBER AS
BEGIN
DELETE FROM DEPT_ADMIN.DEPT
WHERE DEPT = VDEPT;
RETURN(SQL%ROWCOUNT);
EXCEPTION
WHEN OTHER THEN
RAISE_APPLICATION_ERROR
(-20001,SQLERRM);
END DELETE_DEPT;
------------------------------------------------------
/ CREATE PROCEDURE
DEPT_ADMIN.DELETE_DEPT
@VDEPT VARCHAR(4) AS
DELETE FROM DEPT_DB.DBO.DEPT
WHERE DEPT = @VDEPT
RETURN @@ROWCOUNT
GO

實現游標

Oracle在使用SELECT語句時總是需要游標,不管從數據庫中請求多少行。在Microsoft SQL Server,
SELECT語句並不把在返回客戶的行上附加游標作為缺省的結果集合。這是一種返回數據給客戶應用程序的有效的方法。

SQL Server為游標函數提供了兩種接口。當在Transact-SQL批處理或者存儲過程中使用游標的時候,SQL語句可用來聲明、
打開、和從游標中抽取,就像定位更新和刪除一樣。當使用來自DB-Library、ODBC、或者OLEDB程序的游標時,SQL Server
顯式的調用內建的服務器函數來更有效的處理游標。

當從Oracle輸入一個PL/SQL過程時,首先判斷是否需要在Transact-SQL中采用游標來實現同樣的功能。如果游標僅僅返回一
組行給客戶程序,就使用非游標的SELECT語句來返回缺省的結果集合。如果游標用來從行中一次取得一個數據給本地過程變量,
你就必須在Transact-SQL中使用游標。

語法

下表顯示了使用游標的語法。

操作 Oracle Microsoft SQL Server
聲明一個游標 CURSOR cursor_name [(cursor_parameter(s))]
IS select_statement;
----------------------------------------------------
DECLARE cursor_name CURSOR
[LOCAL | GLOBAL]
[FORWARD_ONLY | SCROLL]
[STATIC | KEYSET | DYNAMIC | FAST_FORWARD]
[READ_ONLY | SCROLL_LOCKS | OPTIMISTIC]
[TYPE_WARNING]
FOR select_statement
[FOR UPDATE [OF column_name [,…n>]
打開一個游標 OPEN cursor_name [(cursor_parameter(s))];
----------------
OPEN cursor_name
從游標中提取(Fetching) FETCH cursor_name INTO variable(s)
-------------------------------------------------------------------------------------------
FETCH FROM] cursor_name
[INTO @variable(s)]
更新提取行 UPDATE table_name
SET statement(s)…
WHERE CURRENT OF cursor_name; UPDATE table_name
SET statement(s)…
WHERE CURRENT OF cursor_name
刪除提取行 DELETE FROM table_name
WHERE CURRENT OF cursor_name; DELETE FROM table_name
WHERE CURRENT OF cursor_name
關閉游標 CLOSE cursor_name; CLOSE cursor_name
清除游標數據結構 N/A DEALLOCATE cursor_name

聲明一個游標

盡管Transact-SQL DECLARE CURSOR語句不支持游標參數的使用,但它確實支持本地變量。當游標打開的時候,
它就使用這些本地變量的值。Microsoft SQL Server在其DECLARE CURSOR中提供了許多附加的功能。

INSENSITIVE選項用來定義一個創建數據的臨時拷貝以被游標使用的游標。游標的所有請求都由這個臨時表來應答。因此
對原表的修改不會反映到那些由fetch返回的用於該游標的數據上。這種類型的游標訪問的數據是不能被修改的。

應用程序可以請求一個游標類型然後執行一個不被所請求的服務器游標類型支持的Transact-SQL語句。SQL Server返回一個錯誤,
指出該游標類型被改變了,或者給出一組參數,隱式的轉換游標。欲取得一個觸發SQL Server 7.0隱式的把游標從一種類型轉換為
另一種類型的參數的完整列表,請參閱SQL Server聯機手冊。

SCROLL選項允許除了前向的抽取以外,向後的、絕對的和相對的數據抽取。一個滾動游標使用一種鍵集合的游標模型,在該模型中,
任何用戶提交的對表的刪除和更新都將影響後來的數據抽取。只有在游標沒有用INSENSITIVE選項聲明時,上面的特性才起作用。

如果選擇了READ ONLY選項,對游標中的行的更新就被禁止。該選項將覆蓋游標的缺省選項棗允許更新。

UPDATE [OF column_list]語句用來在游標中定義一個可更新的列。如果提供了[OF column_list],那麼僅僅是那些列出的列可以被修改。
如果沒有指定任何列。則所有的列都是可以更新的,除非游標被定義為READ ONLY。

重要的是,注意到一個SQL Server游標的名字范圍就是連接自己。這和本地變量的名字范圍是不同的。
不能聲明一個與同一個用戶連接上的已有的游標相同名字的游標,除非第一個游標被釋放。

打開一個游標

Transact-SQL不支持向一個打開的游標傳遞參數,這一點和PL/SQL是不一樣的。當一個Transact-SQL游標被打開以後,
結果集的成員和順序就固定下來了。其它用戶提交的對原表的游標的更新和刪除將反映到對所有未加INSENSITIVE選項定義
的游標的數據抽取上。對一個INSENSITIVE游標,將生成一個臨時表。

抽取數據

Oracle游標只能向前移動棗沒有向後或者相對滾動的能力。SQL Server游標可以向前或者向後滾動,具體怎麼滾動,
要由下表給出的數據抽取選項來決定。只有在游標是用SCROLL選項聲明的前提下,這些選項才能使用。

卷動選項 描述
NEXT 如果這是對游標的第一次提取,則返回結果集合的第一行;否則,在結果結合內移動游標到下一行。
NEXT是在結果集合中移動的基本方法 。NEXT是缺省的游標提取(fetch)。
PRIOR 返回結果集合的前一行。
FIRST 把游標移動到結果集合的第一行,同時返回第一行。
LAST 把游標移動到結果集合的最後一行,同時返回最後一行。
ABSOLUTE n 返回結果集合的第n行。如果n為負數,則返回倒數第n行
RELATIVE n 返回當前提取行後的第n行,如果n是負數,則返回從游標相對位置起的倒數第n行。

Transact-SQL的FETCH語句不需要INTO子句。如果沒有指定返回變量,行就自動作為一個單行結果集合返回給客戶。但是,
如果你的過程必須把行給客戶,一個不帶游標的SELECT語句更有效一些。

在每一個FETCH後面,@@FETCH_STATUS函數被更新。這和在PL/SQL中使用CURSOR_NAME%FOUND和CURSOR_NAME%NOTFOUND變量是相似的
。@@FETCH_STATUS函數在每一次成功的數據抽取以後被設定為0。如果數據抽取試圖讀取一個超過游標末尾的數據,則返回一個為-1的值。
如果請求的行在游標打開以後從表上被刪除了,@@FETCH_STATUS函數就返回一個為-2的值。只有游標是用SCROLL選項定義的情況下,
才會返回-2值。在每一次數據抽取之後都必須檢查該變量,以確保數據的有效性。

SQL Server不支持Oracle的游標FOR循環語法。

CURRENT OF子句

更新和刪除的CURRENT OF子句語法和函數在PL/SQL和Transact-SQL中是一樣的。在給定游標中,在當前行上執行定位的UPDATE和DELETE。

關閉一個游標

Transact-SQL的CLOSE CURSOR語句關閉游標,但是保留數據結構以備重新打開。PL/SQL 的CLOSE CURSOR語句關閉並且釋放所有的數據結構。

Transact-SQL需要用DEALLOCATE CURSOR語句來清除游標數據結構。DEALLOCATE CURSOR語句同CLOSE CURSOR是不一樣的,
後者保留數據結構以備重新打開。DEALLOCATE CURSOR釋放所有與游標相關的數據結構並且清除游標的定義。

游標示例

下面的例子顯示了在PL/SQL和Transact-SQL等價的游標語句。

Oracle Microsoft SQL 
-----------------------------------------------------------------------------------------------------------
DECLARE
VSSN CHAR(9);
VFNAME VARCHAR(12);
VLNAME VARCHAR(20);
-----------------------------------------------------------------------------------------------------------
DECLARE
@VSSN CHAR(9),
@VFNAME VARCHAR(12),
@VLNAME VARCHAR(20)
CURSOR CUR1
IS
SELECT SSN, FNAME, LNAME
FROM STUDENT ORDER BY LNAME;

BEGIN
    OPEN CUR1;
    FETCH CUR1 INTO VSSN,     VFNAME, VLNAME;
    WHILE (CUR1%FOUND) LOOP
    FETCH CUR1 INTO VSSN,     VFNAME, VLNAME;
END LOOP;
CLOSE CUR1;
END;
-----------------------------------------------------------------------------------------------------------
DECLARE curl CURSOR FOR
   SELECT SSN, FNAME, LNAME
   FROM STUDENT ORDER BY SSN
OPEN CUR1
FETCH NEXT FROM CUR1
   INTO @VSSN, @VFNAME, @VLNAME
WHILE (@@FETCH_STATUS <> -1)
   BEGIN
  FETCH NEXT FROM CUR1 INTO       @VSSN, @VFNAME, @VLNAME
   END
CLOSE CUR1
DEALLOCATE CUR1

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved