ORACLE和MS SQL SQL語法區別

數據類型比較

類型名稱
Oracle
  SQLServer
  比較

字符數據類型  CHAR  CHAR  都是固定長度字符資料但oracle裏面最大度爲2kb,SQLServer裏面最大長度爲8kb 
變長字符數據類型  VARCHAR2  VARCHAR  Oracle裏面最大長度爲4kb,SQLServer裏面最大長度爲8kb 
根據字符集而定的固定長度字符串  NCHAR  NCHAR  前者最大長度2kb後者最大長度4kb 
根據字符集而定的可變長度字符串  NVARCHAR2  NVARCHAR  二者最大長度都爲4kb 
日期和時間數據類型  DATE  有Datetime和Smalldatetime兩種  在oracle裏面格式爲DMY在SQLSerser裏面可以調節,默認的爲MDY 
數字類型  NUMBER(P,S)  NUMERIC[P(,S)]  Oracle裏面p代表小數點左面的位數,s代表小數點右面的位數。而SQLServer裏面p代表小數點左右兩面的位數之和,s代表小數點右面的位數。 
數字類型  DECIMAL(P,S)  DECIMAL[P(,S)]  Oracle裏面p代表小數點左面的位數,s代表小數點右面的位數。而SQLServer裏面p代表小數點左右兩面的位數之和,s代表小數點右面的位數。  
整數類型  INTEGER  INT  同爲整數類型,存儲大小都爲4個字節 
浮點數類型  FLOAT  FLOAT   
實數類型  REAL  REAL 

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 Microsoft SQL  
SELECT * FROM STUDENT_ADMIN.STUDENT
WHERE LNAME LIKE 'A%'
OR LNAME LIKE 'B%'
OR LNAME LIKE 'C%' 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 Microsoft SQL  
SELECT FNAME||' '||LNAME AS NAME
FROM STUDENT_ADMIN.STUDENT
-----------------------------------------------
SELECT FNAME +' '+ LNAME AS    NAME
FROM STUDENT_ADMIN.STUDENT 

 

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

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

 

關鍵字

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

語句 Oracle PL/SQL ---------------------Microsoft SQL Server Transact-SQL 

聲明變量 DECLARE DECLARE 
語句塊 BEGIN...END; BEGIN...END 
條件處理 IF…THEN,
ELSIF…THEN,
ELSE
ENDIF; 
--------------------------------------------------------
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 Microsoft SQL  
DECLARE
VSSN CHAR(9);
VFNAME VARCHAR2(12);
VLNAME VARCHAR2(20);
VBIRTH_DATE DATE;
VLOAN_AMOUNT NUMBER(12,2); 
-----------------------------------------
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 Microsoft SQL  
DECLARE VSSN CHAR(9);
VFNAME VARCHAR2(12);
VLNAME VARCHAR2(20);
BEGIN
VSSN := ?'
SELECT FNAME, LNAME INTO VFNAME, VLNAME FROM STUDENTS WHERE SSN=VSSN;
END; 
------------------------------------------------------------------------------
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)
SELECT @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 Microsoft SQL  
DECLARE
COUNTER NUMBER;
BEGIN
COUNTER := 0
WHILE (COUNTER <5) LOOP
COUNTER := COUNTER + 1;
END LOOP;
END; 
------------------------------------------------------
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



文章轉載自:http://www.itpub.net/thread-794011-1-1.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章