您的位置:首页 > 数据库 > Oracle

ORACLE和SQL语法区别归纳(2)

2011-10-05 10:00 375 查看
 字串连接
  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

  [BEGIN…END]

  ELSE IF

  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

  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;

  <> 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: