熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

ORACLE和SQL語法區別歸納(2)

2013-11-13 16:04:17  來源: Oracle 

  字串連接

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

  Oracle Microsoft SQL

  SELECT FNAME|| ||LNAME AS NAME

  FROM STUDENT_ADMINSTUDENT

  

  SELECT FNAME + + LNAME AS    NAME

  FROM STUDENT_ADMINSTUDENT

  流控制(ControlofFlow)語言

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

  關鍵字

  這是兩個RDBMS支持的關鍵字

  語句 Oracle PL/SQL Microsoft SQL  Server TransactSQL

  聲明變量 DECLARE DECLARE

  語句塊 BEGINEND; BEGINEND

  條件處理 IF…THEN

  ELSIF…THEN

  ELSE

  ENDIF;

  

  IF…[BEGIN…END]

  ELSE

  [BEGIN…END]

  ELSE IF

  CASE expression

  無條件結束 RETURN RETURN

  無條件結束當前程序塊後面的語句 EXIT BREAK

  重新開始一個WHILE循環 N/A CONTINUE

  等待指定間隔 N/A (dbms_locksleep) WAITFOR

  循環控制 WHILE LOOP…END LOOP;

  

  LABEL…GOTO LABEL;

  FOR…END LOOP;

  LOOP…END LOOP;

  WHILE

  BEGIN… END

  LABEL…GOTO LABEL

  程序注釋 /* … */ /* … */

  打印輸出 RDBMS_OUTPUTPUT_LINE PRINT

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

  執行程序 EXECUTEEXECUTE

  語句終止符 Semicolon (;) N/A

  聲明變量

  TransactSQL 和PL/SQL 的變量是用DECLARE關鍵字創建的TransactSQL 變量用@標記

  並且就像PL/SQL 一樣在第一次創建時用空值初始化

  Oracle Microsoft SQL

  DECLARE

  VSSN CHAR();

  VFNAME VARCHAR();

  VLNAME VARCHAR();

  VBIRTH_DATE DATE;

  VLOAN_AMOUNT NUMBER();

  

  DECLARE

  @VSSN CHAR()

  @VFNAME VARCHAR()

  @VLNAME VARCHAR()

  @VBIRTH_DATE DATETIME

  @VLOAN_AMOUNT NUMERIC()

  TransactSQL 不支持%TYPE和%ROWTYPE變量數據類型定義一個TransactSQL 變量不能在DECLARE命令中初始化

  在Microsoft SQL Server數據類型定義中也不能使用Oracle 的NOT NULL和CONSTANT關鍵字

  像Oracle 的LONG和LONG RAW數據類型一樣文本和圖形數據類型不能被用做變量定義

  此外TransactSQL 不支持PL/SQL 風格的記錄和表的定義

  給變量賦值

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

  Oracle Microsoft SQL

  Assignment operator (:=) SET @local_variable = value

  SELECTINTO 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();

  VFNAME VARCHAR();

  VLNAME VARCHAR();

  BEGIN

  VSSN := ?

  SELECT FNAME LNAME INTO VFNAME VLNAME FROM STUDENTS WHERE SSN=VSSN;

  END;

  

  DECLARE @VSSN CHAR()

  @VFNAME VARCHAR()

  @VLNAME VARCHAR()

  SET @VSSN = ?

  SELECT @VFNAME=FNAME @VLNAME=LNAME FROM STUDENTS WHERE SSN = @VSSN

  語句塊

  Oracle PL/SQL 和Microsoft SQL Server TransactSQL 都支持用BEGIN…END術語來標記語句塊

  TransactSQL 不需要在DECLARE語句後使用一個語句塊

  

  如果在Microsoft SQL Server

  中的IF語句和WHILE循環中有多於一個語句被執行則需要使用BEGIN…END語句塊

  Oracle Microsoft SQL

  DECLARE

  DECLARE VARIABLES

  BEGIN THIS IS REQUIRED SYNTAX

  PROGRAM_STATEMENTS

  IF THEN

  STATEMENT;

  STATEMENT;

  STATEMENTN;

  END IF;

  WHILE LOOP

  STATEMENT;

  STATEMENT;

  STATEMENTN;

  END LOOP;

  END; THIS IS REQUIRED SYNTAX DECLARE

  DECLARE VARIABLES

  BEGIN THIS IS OPTIONAL SYNTAX

  PROGRAM_STATEMENTS

  IF

  BEGIN

  STATEMENT

  STATEMENT

  STATEMENTN

  END

  WHILE

  BEGIN

  STATEMENT

  STATEMENT

  STATEMENTN

  END

  END THIS IS REQUIRED SYNTAX

  條件處理

  Microsoft SQL Server TransactSQL 的條件語句包括IF和ELSE但不包括Oracle PL/SQL 中的ELSEIF語句

  可以用嵌套多重IF語句來到達同樣的效果對於廣泛的條件測試用CASE表達式也許更容易和可讀一些

  Oracle Microsoft SQL

  DECLARE

  VDEGREE_PROGRAM CHAR();

  VDEGREE_PROGRAM_NAME VARCHAR();

  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()

  @VDEGREE_PROGRAM_NAME VARCHAR()

  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 LOOPTransactSQL 則提供了WHILE循環和GOTO語句

  WHILE Boolean_expression

  {sql_statement | statement_block}

  [BREAK] [CONTINUE]

  WHILE循環需要測試一個布爾表達式來決定一個或者多個語句的重復執行

  只要給定的表達式結果為真這個(些)語句就一直重復執行下去如果有多個語句需要執行則這些語句必須放在一個BEGIN…END塊中

  Oracle Microsoft SQL

  DECLARE

  COUNTER NUMBER;

  BEGIN

  COUNTER :=

  WHILE (COUNTER <) LOOP

  COUNTER := COUNTER + ;

  END LOOP;

  END;

  

  DECLARE

  @COUNTER NUMERIC

  SELECT@COUNTER =

  WHILE (@COUNTER <)

  BEGIN

  SELECT @COUNTER =

  @COUNTER +

  END

  語句的執行可以在循環的內部用BREAK和CONTINUE關鍵字控制BREAK關鍵字使WHILE循環無條件的結束

  而CONTINUE關鍵字使WHILE循環跳過後面的語句重新開始BREAK關鍵字同Oracle PL/SQL 中的EXIT關鍵字是等價的

  而在Oracle 中沒有和CONTINUE等價的關鍵字

  GOTO語句

  Oracle 和Microsoft SQL Server都有GOTO語句但是語法不同GOTO語句使TransactSQL 跳到指定的標號處運行

  在GOTO語句後指定標號之間的任何語句都不會被執行

  Oracle Microsoft SQL

  GOTO label;

  <> GOTO label

  PRINT語句

  TransactSQL 的PRINT語句執行同PL/SQL 的RDBMS_OUTPUTput_line過程同樣的操作該語句用來打印用戶給定的消息

  用PRINT語句打印的消息上限是個字符定義為char或者varchar數據類型的變量可以嵌入打印語句

  如果使用其它數據類型的變量則必須使用CONVERT或者CAST函數本地變量全局變量可以被打印可以用單引號或者雙引號來封閉文本

  從存儲過程返回

  Microsoft SQL Server和Oracle 都有RETURN語句RETURN使你的程序從查詢或者過程中無條件的跳出RETURN 是立即的

  完全的並且可以用於從過程批處理或者語句塊的任意部分跳出在REUTRN後面的語句將不會被執行

  Oracle Microsoft SQL

  RETURN expression: RETURN [integer_expression]

  引發程序錯誤(Raising program errors)

  TransactSQL 的RAISERROR返回一個用戶定義的錯誤消息並且設置一個系統標志來記錄發生了一個錯誤

  這個功能同PL/SQL 的raise_application_error異常處理器的功能是相似的

  RAISERROR語句允許客戶重新取得sysmessages表的一個入口或者用用戶指定的嚴重性和狀態信息動態的建立一條消息

  在被定義後消息被送回客戶端作為系統錯誤消息

  RAISERROR ({msg_id | msg_str} severity state

  [ argument [ argument>)

  [WITH options]

  在轉換你的PL/SQL 程序時也許用不著使用RAISERROR語句在下面的示例代碼中

  PL/SQL 程序使用raise_application_error異常處理器但是TransactSQL 程序則什麼也沒用

  包括raise_application_error異常處理器是為了防止PL/SQL 返回不明確的未經處理的異常錯誤消息

  作為代替當一個不可預見的問題發生的時候異常處理器總是返回Oracle 錯誤消息

  當一個TransactSQL 失敗時它總是返回一個詳細的錯誤消息給客戶程序因此除非需要某些特定的錯誤處理

  一般是不需要RAISERROR語句的

  Oracle Microsoft SQL

  CREATE OR REPLACE FUNCTION

  DEPT_ADMINDELETE_DEPT

  (VDEPT IN VARCHAR) RETURN NUMBER AS

  BEGIN

  DELETE FROM DEPT_ADMINDEPT

  WHERE DEPT = VDEPT;

  RETURN(SQL %ROWCOUNT);

  EXCEPTION

  WHEN OTHER THEN

  RAISE_APPLICATION_ERROR

  (SQLERRM);

  END DELETE_DEPT;

  

  / CREATE PROCEDURE

  DEPT_ADMINDELETE_DEPT

  @VDEPT VARCHAR() AS

  DELETE FROM DEPT_DBDBODEPT

  WHERE DEPT = @VDEPT

  RETURN @@ROWCOUNT

  GO

  實現游標

  Oracle 在使用SELECT語句時總是需要游標不管從數據庫中請求多少行在 Microsoft SQL Server

  SELECT語句並不把在返回客戶的行上附加游標作為缺省的結果集合這是一種返回數據給客戶應用程序的有效的方法

  SQL Server為游標函數提供了兩種接口當在TransactSQL 批處理或者存儲過程中使用游標的時候SQL 語句可用來聲明

  打開和從游標中抽取就像定位更新和刪除一樣當使用來自DBLibraryODBC或者OLEDB程序的游標時SQL Server

  顯式的調用內建的服務器函數來更有效的處理游標

  當從Oracle 輸入一個PL/SQL 過程時首先判斷是否需要在TransactSQL 中采用游標來實現同樣的功能如果游標僅僅返回一

  組行給客戶程序就使用非游標的SELECT語句來返回缺省的結果集合如果游標用來從行中一次取得一個數據給本地過程變量

  你就必須在TransactSQL 中使用游標

  語法

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

  操作 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

  聲明一個游標

  盡管TransactSQL DECLARE CURSOR語句不支持游標參數的使用但它確實支持本地變量當游標打開的時候

  它就使用這些本地變量的值Microsoft SQL Server在其DECLARE CURSOR中提供了許多附加的功能

  INSENSITIVE選項用來定義一個創建數據的臨時拷貝以被游標使用的游標游標的所有請求都由這個臨時表來應答因此

  對原表的修改不會反映到那些由fetch返回的用於該游標的數據上這種類型的游標訪問的數據是不能被修改的

  應用程序可以請求一個游標類型然後執行一個不被所請求的服務器游標類型支持的TransactSQL 語句SQL Server返回一個錯誤

  指出該游標類型被改變了或者給出一組參數隱式的轉換游標欲取得一個觸發SQL Server 隱式的把游標從一種類型轉換為

  另一種類型的參數的完整列表請參閱SQL Server聯機手冊

  SCROLL選項允許除了前向的抽取以外向後的絕對的和相對的數據抽取一個滾動游標使用一種鍵集合的游標模型在該模型中

  任何用戶提交的對表的刪除和更新都將影響後來的數據抽取只有在游標沒有用INSENSITIVE選項聲明時上面的特性才起作用

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

  UPDATE [OF column_list]語句用來在游標中定義一個可更新的列如果提供了[OF column_list]那麼僅僅是那些列出的列可以被修改

  如果沒有指定任何列則所有的列都是可以更新的除非游標被定義為READ ONLY

  重要的是注意到一個SQL Server游標的名字范圍就是連接自己這和本地變量的名字范圍是不同的

  不能聲明一個與同一個用戶連接上的已有的游標相同名字的游標除非第一個游標被釋放

  打開一個游標

  TransactSQL 不支持向一個打開的游標傳遞參數這一點和PL/SQL 是不一樣的當一個TransactSQL 游標被打開以後

  結果集的成員和順序就固定下來了其它用戶提交的對原表的游標的更新和刪除將反映到對所有未加INSENSITIVE選項定義

  的游標的數據抽取上對一個INSENSITIVE游標將生成一個臨時表

  抽取數據

  Oracle 游標只能向前移動棗沒有向後或者相對滾動的能力SQL Server游標可以向前或者向後滾動具體怎麼滾動

  要由下表給出的數據抽取選項來決定只有在游標是用SCROLL選項聲明的前提下這些選項才能使用

  卷動選項 描述

  NEXT 如果這是對游標的第一次提取則返回結果集合的第一行否則在結果結合內移動游標到下一行

  NEXT是在結果集合中移動的基本方法 NEXT是缺省的游標提取(fetch)

  PRIOR 返回結果集合的前一行

  FIRST 把游標移動到結果集合的第一行同時返回第一行

  LAST 把游標移動到結果集合的最後一行同時返回最後一行

  ABSOLUTE n 返回結果集合的第n行如果n為負數則返回倒數第n行

  RELATIVE n 返回當前提取行後的第n行如果n是負數則返回從游標相對位置起的倒數第n行

  TransactSQL 的FETCH語句不需要INTO子句如果沒有指定返回變量行就自動作為一個單行結果集合返回給客戶但是

  如果你的過程必須把行給客戶一個不帶游標的SELECT語句更有效一些

  在每一個FETCH後面@@FETCH_STATUS函數被更新這和在PL/SQL 中使用CURSOR_NAME%FOUND和CURSOR_NAME%NOTFOUND變量是相似的

  @@FETCH_STATUS函數在每一次成功的數據抽取以後被設定為如果數據抽取試圖讀取一個超過游標末尾的數據則返回一個為的值

  如果請求的行在游標打開以後從表上被刪除了@@FETCH_STATUS函數就返回一個為的值只有游標是用SCROLL選項定義的情況下

  才會返回在每一次數據抽取之後都必須檢查該變量以確保數據的有效性

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

  CURRENT OF子句

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

  關閉一個游標

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

  TransactSQL 需要用DEALLOCATE CURSOR語句來清除游標數據結構DEALLOCATE CURSOR語句同CLOSE CURSOR是不一樣的

  後者保留數據結構以備重新打開DEALLOCATE CURSOR釋放所有與游標相關的數據結構並且清除游標的定義

  游標示例

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

  Oracle Microsoft SQL


From:http://tw.wingwit.com/Article/program/Oracle/201311/17760.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.