[转]SQLServer和Oracle,存储过程区别,常用函数对比
本文转自:http://www.cnblogs.com/neru/archive/2011/08/18/2144049.html
以前一直用sqlserver,只有很少的一点oracle的经验,现在要用oracle做一个很复杂的存储过程,感觉好别扭~ 唉
为啥就不能用sqlserver呢。。。
本文档主要从oracle与sql server语法上进行差异性比较,诸如两者在管理,性能,优化等方面的差异不作比较。
●概念上区别
1.Oracle 是一种对象关系数据库管理系统(ORDBMS),而Sql server 只是关系型数据库管
理系统(RDBMS).
2.Oracle使用Internet文件系统,该系统基于Java的应用程序,可以使数据库基于成为
Internet的开发平台;Sql server 是基于windows
3.Orace 主要的三类文件是:数据文件,控制文件,恢复日志文件
Sql server: 主要数据文件(必须有且只能有一个),次要数据文件以及日志文件
4.两者支持的命令类别差不多,数据定义语言,数据操纵语言,事务处理控制语言,
数据控制语言.在Oracle中,在事务控制语言中除了commit,rollback等还多了一个
Savepoint,设置保存点。
5.oracle sql的扩展叫PL/SQL,主要的结构化查询工具有sql*plus,isql*plus, pl/sql等
Ms sql的扩展叫Transact-SQL,主要的结构化查询工具就是自带的查询分析器
6.主要数据类型
Orace:主要支持char ,varchar2,long,number,datetime,raw,long raw,clob,blob,bfie
前面三个是Character数据类型,varchar2支持可变长度的字符串,long支持可
变长度的字符数据,raw,long raw用于存储二进制数据,long raw 可变长度
最后三个是大对象(lob)数据类型,存储非结构化的信息,例如声音剪辑,视频文件
CLOG表示Character Lob,可以存储大量的字符数据,它对于存储非结构化的XML
文档非常有用。BLOG表示Binary LOG,此数据类型可以存储大型二进制对象,如
图形、视频剪辑,声音文件等
支不支持,money,货币
Sql server 主要支持的文本类型char ,varchar,nchar,nvarchar,text,ntext,image,货币类型
Money,二进制 binary,varbinary等等
●开发语法
A.SQL 语法
两者的SQL语法基本上是相同的,只是一些细节方面的问题
一: 表的管理:修改表的结构,如增加,删除列,創建表
修改表
1.修改表的列的數據類型,大小的定義不同,如下面修改數據類型。
Ms sql是ALTER TABLE table_name ALTER COLUMN col DECIMAL (5, 2)
Oracle是 Alter TABLE table_name modify(col decimal(5,2))
2.增加和刪除表的列,兩者是相同的
Alter tabe table_name add(col definition)
Alter tabe table_name drop column col_name
3 .Oracle如果不要用某列,然後又不想刪除,就可以将某个列标记为未用
Alter tabe table_name set unused(tel_no)
.创建临时表
Oracle 的語法是:
Create global temporary table aa(col number) on commit preserve rows;
临时表只在用户会话时存在的表,或其数据在用户事务处理期间可
持续存在的表,创建临时表时可以指定该表是否应当在用户会话
期间持续存在(使用on commit preserve rows)
On commit delete rows 表示事务处理完成后删除它的行
Ms sql的語法是:
Select * into #temptable from existedtable
二 查询方面:
1.查表的前N行记录
oracle 是用rownum 如select * from table_name where rownum<n
Ms sql 是用top 如select top n * from table_name
2.查詢表的結構
Orace 可以通過desc来查看表的结构 语法是:desc table_name
或者使用数据字典表user_tab_coumns也可以查看到
Select column_name,data_type from user_tab_coumns
Where table_name=''
Ms sql可以通過一些系統的存儲過程來看表的結構
語法是:exec sp_help table_name
3.将一个表的数据添加到另外一个表中
a.新表存在前提下:兩者語法是一樣的,如
insert into newtable(col1)select col1 from old_table
b.新表不存在前提下,可以用
oracle 可以用Create tabe new _table_name as select * from old_table
ms sql 可以用 Select * into new_table from old_table
三 操作符
1.連接操作符
Oracle是 ‘||’; Ms sql是‘+’
2. Oracle的比较操作符中不等于除了'<>'之外,还有一个 '!='
3. 算术操作符,都是+-*/;逻辑操作符都是and,not,or(相同點)
4. oracle集合操作符除了union,union all之外还加入intersect,minus
Intersect是仅返回两个查询都有行,minus返回第一个查询有第
二个查询没有的行
四 函數
1.轉換函數
Oracle 中有to_char(),to_date(),to_number()
Ms sql 中有cast,convert
2.系统日期:
Oracle: sysdate
Ms sql: getdate()
如
Select sysdate from dual 一定要from子句
Select getdate() 不一定要from子句
3.Decode函数相当if else,或者ms 中的case语句
语法是decode(value,if1,then1,if2,then2....)
如decode(col1,'1','true','0','fase')
4.常规函数
Nvl 语法是NVL(EXP1,EXP2) 表示如果ex1为空则返回ex2
Nvl2 语法是nvl(exp1,exp2,exp3)表示如果ex1为空,则返回ex3,否则返回ex2
Nullif 语法是nullif(ex1,ex2) 如果这两个表达式相等则返回空
coalesce语法是coalesce(ex1,ex2,....exn)返回第一个非空表达式
5.分組函數
Oracle 中的分組函數Rollup,cube
Rollup返回的结果集包含分组行和小计行,cube产生交叉报表
如:
Select a,b,sum(c) from tabname group by rollup(a,b)
Select a,b,sum(c) from tabname group by cube(a,b)
Ms sql中的分組函數 compute 和 compute by
Compute子句为行聚集函数生成汇总值,该汇总值做为一个附加的行显示
在结果集中。没有GROUP BY 子句的情况下,也可以使用关键字COMPUTE.
此关键字使用MAX,MIN,SUM,COUNT,AVG等函数生成汇总值,而compute by
则在控制中断时给出该汇总值,compute by 必须包括在order by 子句中。
還有很多函數,諸如日期函數,字符串函數等等,就不一一作比較了。
Oracle中還有很多比較好的分析函數,也不列舉了。
五.Oracle中的数据库对象
同义词
作用:简化SQL语句;隐藏对象的名称和所有者,提供对象的公共访问等。
语法:CREATE PUBLIC SYNONYM seqname FOR OBJECT
序列
用来生成唯一、边续的整数,它通常用来自动生成主键或唯一值的键。
創建序列: create sequence seqname [increment by 1] start with 1 maxvalue 10
minvalue 1 cycle cache
访问序列:
Select seqname.nextval from dual 将返回序列的初始值
Select seqname.currval from dual 返回序列的当前值
簇(cluster):
簇是共享相同数据块的一组表,因为这些表具有相同的列,并且经常一起使用。
当两个或多个表的存储在物理上十分接近时,可以通过簇来提高使用这些表的
SQL联接语句的性能。簇是存储表的方法
应该先创建簇,然后再创建簇中的表,
六.Oracle中的对象类型
1. 抽象数据类型
此类型是包含一个或多个子类型的数据类型,并且这些数据类型并不局限
于标准的oracle数据类型
如:create or replace type t_mm as object(col number(3),
col2 varchar2(20))/
此时可以在创建表时使用该类型,如下
Create table test (aa varchar2(5),bb t_mm, cc number(10))
插入记录:
Insert into test values('cccc', t_mm(1,'col'))
类型声明:
用户定义的数据类型也可以声明为 final,not final,instantiable,
not instantiabe
Not final表示允许类型派生子类型。默认是final
create or replace type t_mm as object(col number(3),
col2 varchar2(20)) Not final
not instantiabe表示类型没有构造函数。
2. 可变数组
可变数组有助于在单个行中存储和重复记录的属性。
数据与表中的其它数据是存储在一起的,有限数目的行,不能被索引
创建可变数组的 语法是:
create type array1 as varray(5) of varchar2(5)
向可变数组中插入记录
Insert into test1 values ('2ee', array1('1','2','3','4','5') )
Select * from test1 结果集如下
2ee
'1','2','3','4','5'
Select col2 from test1 结果集如下
'1','2','3','4','5'
Select * from table(select t.col2 from test1 where col1='2ee'); 结果集如下
1
2
3
4
5
3. 嵌套表
它是包含在表中的表,对每行数据项数目没有限制,一个表在
另一表中是作为一列,主表中的每一行的嵌套表可以包含若干行。
创建嵌套表
先创建一个类型
Create type ord_ty as object(itemcode varchar2(5),qty _ord number(5),
Qty_held number(5));
创建另一个抽象数据类型,即嵌套表数据类型
Create type ord_nt as table of ord_ty
创建嵌套表
Create table order_mas (orderno varchar2(5),odate date,
vencode varchar2(5), dets ord_nt) nested table dets store as ord_nt_tab;
向嵌套表中插入数据:
Insert into order_mas values(‘001’,to_date('18-07-08','DD-MM-YY'),
'V009',ord_nt( ord_ty('i001',10,5),ord_ty('i002',34,2));
更新嵌套表的值:
Update table(select e.dets from order_mas e where e.orderno='001') p
Set value(p) =ord_ty('i090',8,9) where p.itemcode='i001';
删除嵌套表的值:
Delete from table(select e.dets from order_mas e where e.orderno='001') p
where p.itemcode='i001';
4. 对象表
在对象表中每一行都是一个行对象,对象表与关系表不同:
对象表中的每一行都有一个OID值,即对象标识符值。该值是在创建行时
分配的。可以使用create table 命令来创建对象表。
在创建对象类型时,Oracle 中是不允许为属性定义约束条件,但是
可以在创建对象表时为对象类型的属性指定约束条件。
Create table vend_master of vend_ty(vencode constraint vc_pk primary key);
创建对象表与关系表语法不同
表的使用方法不同 插入数据可以使用抽象数据类型的构造函数,如果对象
表所基于抽象数据类型又基于另一抽象数据类型,则必须多个构造函数的嵌
套调用。
Insert into vend_master values (vend_ty());
5. 对象视图
借助对象视图可以将面向对象的结构(如抽象数据类型)应用于现有已经
投入使用的表,而不需重建整个应用程序
B.PL/SQL與T_SQL语法
一批處理
SQL的能力畢竟有限,諸如事務處理方面,批處理於是oracle與ms 都把它進行了擴展,oracle 的擴展叫PL/SQL由声明部分,可执行部分,异常处理部分组成顺序如下:
Declare declarations
Begin
Executable statements
Exception
Handles
End
Ms 的擴展叫 Transact_SQL,簡稱T_SQL.
批处理:就是一次执行处理一组命令的过程。GO关键字樗着批处理的结束。
如use master
go
复杂一点也是由三部分組成:声明部分,可执行部分,异常处理部分。
不同的是,異常處理部分一般用跳轉語句來實現。
例如:
Declare declarations
Begin
Excutable statements
IF @ERROR <>0 GOTO ERROR
End
ERROR:
BEGIN
RAISERROR(20058, 16, -1)
return (1)
END
二逻辑控制语句
1. 控制结构:
Oracle
If condition then ........
End if
Case selector
when exp1 then statements
Else statements
End case
SQL SERVER
IF condition
Sql statements
ELSE
Sql statements
Case selector
When ex1 then statements
Else statements
End
2. 迭代结构
oracle
Loop statements end loop;
While condition
Loop statement end loop;
Sql server
While condition
Begin
Sql statement
End
面象对象编程涉及的概念有对象,类,属性和方法,面向对象的三大特性是:
封装,继承和多态。
将数据和函数包装到一个单元中的过程称为封装。不能从外部访问数据,只能包装在
类中的那些函数才能访问数据
继承可以是SQL类型的继承和方法的继承。
多态是一个对象可以呈现多种形式的能力,这使得不同的对象可以具有相同的名称
的方法,这些方法实现的任务相似,但实现方式却不同。
三.變量與常量
Pl/sql变量与常量可以具有属性,支持的属性类型有
%type,%rowtype
声明引用数据库列或变量的数据类型的变量时,可以使用%type属性。如:
Declare
Variable_name table_name.col_name %type
使用这个优点是,不需要知道列vencode的准确数据类型
%rowtype属性提供表示表中行的记录类型。
四.過程與函數(Procedure & Function)
a. 建立存儲過程的語法不同:
Ms sql 的語法是:
Create procedure procedure_name
(
@Id int =null,
@name varchar(10) out[put]
)
as
[變量定義區]
begin sql_statement end
--------------------------------------------------------------------
CREATE FUNCTION function_name (@DATE datetime)
RETURNS int
AS begin sql statement end
面向對象的特性之一是封裝,程序包就是对相关PL/SQL类型,子程序,游标,异常,变量,和常量的封装,它包含两部分程序包规格说明和程序包主体
在包规格说明书中,可以声明类型,变量,常量,异常,游标,子程序
程序包主体实现在程序包规格中定义的游标、子程序
包頭語法部分:
Create or replace package package_name is|as
Public type and item declarations
Subprogram specifications
End package_name
實例如下:
Create or replace package pack_me is
Procedure order_proc(orno varchar2);
Function order_fun(ornos varchar2) return varchar2;
End pack_me
包體語法部分:
Create or replace package body package_name is|as
Private type and item decarations
Subprogram bodies
End package_name;
包體具體實例就不寫了,包頭隻是起一個聲明作用,具體實現部分都在包體裡面。
下面是创建存储过程的语法:
Create [or replace] procedure procedure_name[arg1 in|out|in out]type {is|as}
[變量定義區]
Begin
Execute Sql statement
Exception handlers
End
注意:參數列表那裡,oracle是先定義參數是輸入還是輸出參數,然後再定義
參數類型; 而sql server正好相反
创建函数的语法:
Create function function_name argument
Return datatype is|as
Local decaration
Begin
Excutable statement
Exception
Handles
End;
b.變量賦值
1. Oracle里的用法:存储过程中边查询边给变量赋值。
select 某一列名 into 变量名 from table where ..;
相当于sql server中的select 变量名=列. From table where ….
注意:select * /某一列名 into 表名
2. Oracle 直接赋值的符号是:' := '
五 觸發器(Trigger)
Oracle
Create or replace trigger trigger_name [before/after]
[insert/update/delete] on table_name
变量声明
begin
Sql statement
end
Ms sql
Create trigger trigger_name on table
{for |after|instead of} [insert|update|delete] as sql_statements
六 遊標(Curcor)
Oracle中提供两种游标类型,它们是静态游标和ref游标
静态游标又分为隐式游标与显式游标
Ref游标,游标变量是一种引用 类型
隐式游标属性包括%notfound,%found,%rowcount,%isopen
如:
Begin
Delete from ta where ord='ddd'
If sql%notfound then
Dbms_output.put_line(''未找到值)
Else
Dbms_output.put_line(找到并删除之)
End if
End
显示游标:可以用下面语句控制游标
Open cursorname
Fetch cursor_name into var_name
Close cursor_name
创建游标语法:
Oracle:
declare variable
Cursor test is select * from order
Sql server
Declare test cursor for select * from order
七 .错误处理(Exception & test & debug)
有两种类型的异常:一种预定义,另外一种是用户自定义
預定義的類型有很多,如No_data_found,Cursor_already_open
對於Oracle的調試,可以借助第三方工具,如toad,Pl.sql Developer,
对于sql server采用 变量或者print 形式进行调试
Oracle异常定义部分的示例:
Exception
When <exception_name> then statements
When others then
Statements
End;
其中<exception_name>是系统预定义的名字。
Raiser_application_error用于创建用户定义的错误信息的过程,用户定义的错误消息
可以指定的异常描述的更详细
Sql server在错误处理上多采用自定义。或者是用goto跳转的方式
如:
Begin
Sql statements
if @error<>0 goto error
end
Error:
Return;
或是直接用raiserror
if @error<>0
begin
raiserror('发生错误.',-1,-1)
return (1)
end
好了,两者的主要的差异就写到这,但愿我表述清楚了,由于东西比较多,所以还有很多具体东西没有写
http://www.cnblogs.com/wangxiaohuo/archive/2008/04/20/1162631.html
函数
SQLServer和Oracle的常用函数对比 1.绝对值 S:select abs(-1) value O:select abs(-1) value from dual
2.取整(大) S:select ceiling(-1.001) value O:select ceil(-1.001) value from dual
3.取整(小) S:select floor(-1.001) value O:select floor(-1.001) value from dual
4.取整(截取) S:select cast(-1.002 as int) value O:select trunc(-1.002) value from dual
5.四舍五入 S:select round(1.23456,4) value 1.23460 O:select round(1.23456,4) value from dual 1.2346
6.e为底的幂 S:select Exp(1) value 2.7182818284590451 O:select Exp(1) value from dual 2.71828182
7.取e为底的对数 S:select log(2.7182818284590451) value 1 O:select ln(2.7182818284590451) value from dual; 1
8.取10为底对数 S:select log10(10) value 1 O:select log(10,10) value from dual; 1
9.取平方 S:select SQUARE(4) value 16 O:select power(4,2) value from dual 16
10.取平方根 S:select SQRT(4) value 2 O:select SQRT(4) value from dual 2
11.求任意数为底的幂 S:select power(3,4) value 81 O:select power(3,4) value from dual 81
12.取随机数 S:select rand() value O:select sys.dbms_random.value(0,1) value from dual;
13.取符号 S:select sign(-8) value -1 O:select sign(-8) value from dual -1 ----------数学函数
14.圆周率 S:SELECT PI() value 3.1415926535897931 O:不知道
15.sin,cos,tan 参数都以弧度为单位 例如:select sin(PI()/2) value 得到1(SQLServer)
16.Asin,Acos,Atan,Atan2 返回弧度
17.弧度角度互换(SQLServer,Oracle不知道) DEGREES:弧度-〉角度 RADIANS:角度-〉弧度
---------数值间比较
18. 求集合最大值 S:select max(value) value from (select 1 value union select -2 value union select 4 value union select 3 value)a
O:select greatest(1,-2,4,3) value from dual
19. 求集合最小值 S:select min(value) value from (select 1 value union select -2 value union select 4 value union select 3 value)a
O:select least(1,-2,4,3) value from dual
20.如何处理null值(F2中的null以10代替) S:select F1,IsNull(F2,10) value from Tbl O:select F1,nvl(F2,10) value from Tbl
--------数值间比较
21.求字符序号 S:select ascii('a') value O:select ascii('a') value from dual
22.从序号求字符 S:select char(97) value O:select chr(97) value from dual
23.连接 S:select '11'+'22'+'33' value O:select CONCAT('11','22')||33 value from dual
23.子串位置 --返回3 S:select CHARINDEX('s','sdsq',2) value O:select INSTR('sdsq','s',2) value from dual
23.模糊子串的位置 --返回2,参数去掉中间%则返回7 S:select patindex('%d%q%','sdsfasdqe') value O:oracle没发现,但是instr可以通过第四霾问刂瞥鱿执问?BR> select INSTR('sdsfasdqe','sd',1,2) value from dual 返回6
24.求子串 S:select substring('abcd',2,2) value O:select substr('abcd',2,2) value from dual
25.子串代替 返回aijklmnef S:SELECT STUFF('abcdef', 2, 3, 'ijklmn') value O:SELECT Replace('abcdef', 'bcd', 'ijklmn') value from dual
26.子串全部替换 S:没发现 O:select Translate('fasdbfasegas','fa','我' ) value from dual
27.长度 S:len,datalength O:length
28.大小写转换 lower,upper
29.单词首字母大写 S:没发现 O:select INITCAP('abcd dsaf df') value from dual
30.左补空格(LPAD的第一个参数为空格则同space函数) S:select space(10)+'abcd' value O:select LPAD('abcd',14) value from dual
31.右补空格(RPAD的第一个参数为空格则同space函数) S:select 'abcd'+space(10) value O:select RPAD('abcd',14) value from dual
32.删除空格 S:ltrim,rtrim O:ltrim,rtrim,trim
33. 重复字符串 S:select REPLICATE('abcd',2) value O:没发现
34.发音相似性比较(这两个单词返回值一样,发音相同) S:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') O:SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe') from dual SQLServer中用SELECT DIFFERENCE('Smithers', 'Smythers') 比较soundex的差 返回0-4,4为同音,1最高
--------------日期函数
35.系统时间 S:select getdate() value O:select sysdate value from dual
36.前后几日 直接与整数相加减
37.求日期 S:select convert(char(10),getdate(),20) value O:select trunc(sysdate) value from dual select to_char(sysdate,'yyyy-mm-dd') value from dual
38.求时间 S:select convert(char(8),getdate(),108) value O:select to_char(sysdate,'hh24:mm:ss') value from dual
39.取日期时间的其他部分 S:DATEPART 和 DATENAME 函数 (第一个参数决定) O:to_char函数 第二个参数决定
参数---------------------------------下表需要补充 year yy, yyyy quarter qq, q (季度) month mm, m (m O无效) dayofyear dy, y (O表星期) day dd, d (d O无效) week wk, ww (wk O无效) weekday dw (O不清楚) Hour hh,hh12,hh24 (hh12,hh24 S无效) minute mi, n (n O无效) second ss, s (s O无效) millisecond ms (O无效) ----------------------------------------------
40.当月最后一天 S:不知道 O:select LAST_DAY(sysdate) value from dual
41.本星期的某一天(比如星期日) S:不知道 O:SELECT Next_day(sysdate,7) vaule FROM DUAL;
42.字符串转时间 S:可以直接转或者select cast('2004-09-08'as datetime) value O:SELECT To_date('2004-01-05 22:09:38','yyyy-mm-dd hh24-mi-ss') vaule FROM DUAL;
43.求两日期某一部分的差(比如秒) S:select datediff(ss,getdate(),getdate()+12.3) value O:直接用两个日期相减(比如d1-d2=12.3) SELECT (d1-d2)*24*60*60 vaule FROM DUAL;
44.根据差值求新的日期(比如分钟) S:select dateadd(mi,8,getdate()) value O:SELECT sysdate+8/60/24 vaule FROM DUAL;
45.求不同时区时间 S:不知道 O:SELECT New_time(sysdate,'ydt','gmt' ) vaule FROM DUAL;
-----时区参数,北京在东8区应该是Ydt------- AST ADT 大西洋标准时间 BST BDT 白令海标准时间 CST CDT 中部标准时间 EST EDT 东部标准时间 GMT 格林尼治标准时间 HST HDT 阿拉斯加—夏威夷标准时间 MST MDT 山区标准时间 NST 纽芬兰标准时间 PST PDT 太平洋标准时间 YST YDT YUKON标准时间 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 日期相加 (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 数字转换为字符 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 返回第一个非空表达式 DECODE COALESCE 当前序列值 CURRVAL N/A 下一个序列值 NEXTVAL N/A 如果exp1 = exp2, 返回null DECODE NULLIF 用户登录账号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 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还有一个有用的函数EXTRACT,提取并且返回日期时间或时间间隔表达式中特定的时间域: EXTRACT(YEAR FROM 日期)
存储过程
一. 多表连接查询,更新存储过程 Sql存储过程 ALTER PROCEDURE [dbo].[ GetEvent] @SCSWId nvarchar(20)= null , @ToDate DATETIME, @FromDate DATETIME AS SELECT NOTES.NOTE_ID, NOTES.NOTE, SCSW_CALENDAR.DATE_TIME FROM SCSW_CALENDAR LEFT OUTER JOIN NOTES ON SCSW_CALENDAR.NOTE_ID=notes.note_id WHERE SCSW_CALENDAR.SCSW_ID = SCSWId ORDER BY Patient.PatientId
Oracel存储过程
1.查询数据的存储过程 PROCEDURE GetEvent(SCSWId IN VARCHAR2, FromDate IN DATE, ToDate IN DATE, refOut OUT refcursor) IS BEGIN OPEN refOut FOR select NOTES.NOTE_ID, NOTES.NOTE, SCSW_CALENDAR.DATE_TIME from SCSW_CALENDAR left join NOTES on SCSW_CALENDAR.NOTE_ID=notes.note_id where SCSW_CALENDAR.SCSW_ID = SCSWId AND SCSW_CALENDAR.DATE_TIME >= FromDate AND SCSW_CALENDAR.DATE_TIME < ToDate order by SCSW_CALENDAR.DATE_TIME; END GetEvent;
2.更新数据的存储过程: procedure UpdateArticlesubmodel ( ArticleSubID number, ArticleTitle nvarchar2, ArticleKeyWord nvarchar2, ArticleContent CLOB, CreatePerson nvarchar2, ChangeDate date, SetTop number, ArticleSubStyleID number, Checked number ) as begin update "ArticleSubModel" set "ArticleTitle"=ArticleTitle, "ArticleKeyWord"=ArticleKeyWord, "ArticleContent"=ArticleContent, "CreatePerson"=CreatePerson, "CreateDate"=ChangeDate, "SetTop"=SetTop, "ArticleSubStyleID"=ArticleSubStyleID, "Checked"=Checked where "ArticleSubID"=ArticleSubID; commit; Exception when others then rollback; end UpdateArticlesubmodel; 3.删除数据的存储过程 procedure DeleteArticlesubmodel ( ArticleSubID number ) as begin delete from "ArticleSubAccessories" where "ArticleSubID"=ArticleSubID; delete from "ArticleSubModel" where "ArticleSubID"=ArticleSubID; commit; Exception when others then rollback; end DeleteArticlesubmodel;
1. top N 问题 在sql server中,top N 问题很容易解决,如下例:从表stbdbdj中选取排序后的第一行数据进行赋值。
在sql中解决方法很简单,在select 后面加上:top n 即可,其中 n 代表行数。
select top 1 @entrust_date = entrust_date, @entrust_no = entrust_no from run2k..stbdbdj where entrust_date = @date and entrust_no > @entrust_no_q and report_status = '1' order by entrust_date,entrust_no;
在oracle中,没有top n这个命令,我们采取把两层查询方式解决:首先,把需要查找的字段值直接进行排序,然后在外面进行第二次查询,并使用rownum决定行数。
select entrust_date,entrust_no into @entrust_date, @entrust_no from ( select entrust_date,entrust_no from stbdbdj where entrust_date = @date and entrust_no > @entrust_no_q and report_status = '1' order by entrust_date,entrust_no ) where rownumber <=1 ;
2. 如何解决结果集返回时,* 和变量同时存在的问题 下面例子表示,在用游标返回结果集时,同时返回一个变量的值,在 sql server 中代码如下所示: select a.*,b.organ_id from run2k..stbbp a,run2k..stkaccoarg b where a.date = @entrust_date and a.serial_no = @serial_no and a.branch_no = b.branch_no and a.exchange_type = b.exchange_type;
但在oracle中却没有这种用法,’*’后面必需跟from。解决方法如下: 1)我们可以把 '*' 变成所需要选择的字段,就是说采用表中需要显示的全部字段表示*。 例如:
open p_cursor for select branch_no,...,organ_id where ...
2)如果这个字段或者说变量是从另外一张表中取出来的,同样可以采用下面的办法。
open p_cursor for select a.*,b.organ_id; from stkaccoentrust a, stkaccoarg b where a.branch_no = b.branch_no and a.exchange_type = b.exchange_type and a.init_date = v_entrust_date and a.serial_no = v_serial_no;
3. 外联接问题 sql <---> oracle a = *b <---> a(+)= b a *= b <---> a = b(+)
4. 多条记录求和问题 select sum(A+B+C) into D from ... where ... group by ...
单条记录求和 select A+B into C from ... where ...
5. case 问题转换 sql: case client_status when '0' then '正常' when '1' then '冻结' when '2' then '挂失' when '3' then '销户' else '未知' end
oracle: decode(client_status,'0','正常,'1','冻结','2','挂失','3','销户','未知');
6. char 和 varchar 类型区别: char 尾部补空格,varchar 尾部不补空格。
7. convert转换问题 sql ---> oracle convert(char(5),branch_no) ---> to_char(branch_no,'99999') convert(char(19),count(*)) ---> lpad(to_char(count(*)),19) convert(varchar(20),serial_no) ---> to_char(serial_no,'999...9' ) 总共20个9 lpad(to_char(serial_no),20)
8. charindex(substring,string) ---> instr(string,substring) 子串 父串 ---> 父串 子串
Oracle中差别
SQL SERVER中: 本质上没区别。只是函数有如:只能返回一个变量的限制。而存储过程可以返回多个。而函数是可以嵌入在sql中使用的,可以在select中调用,而存储过程不行。执行的本质都一样。
函数限制比较多,比如不能用临时表,只能用表变量.还有一些函数都不可用等等.而存储过程的限制相对就比较少 1. 一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强。 2. 对于存储过程来说可以返回参数,而函数只能返回值或者表对象。 3. 存储过程一般是作为一个独立的部分来执行(EXEC执行),而函数可以作为查询语句的一个部分来调用(SELECT调用),由于函数可以返回一个表对象,因此它可以在查询语句中位于FROM关键字的后面。
4. 当存储过程和函数被执行的时候,SQL Manager会到procedure cache中去取相应的查询语句,如果在procedure cache里没有相应的查询语句,SQL Manager就会对存储过程和函数进行编译。
Procedure cache中保存的是执行计划 (execution plan) ,当编译好之后就执行procedure cache中的execution plan,之后SQL SERVER会根据每个execution plan的实际情况来考虑是否要在cache中保存这个plan,评判的标准一个是这个execution plan可能被使用的频率;其次是生成这个plan的代价,也就是编译的耗时。保存在cache中的plan在下次执行时就不用再编译了。 sql server中总结的用法大部分适用于Oracle,在具体的使用过程中,还要看系统实现的复杂程度和实际情况.有经验的DBA对于这两者的运用应该已经了然于胸了,高手路过还请多多指教!
转自:http://www.cnblogs.com/jayhong/archive/2009/08/30/1556642.html
http://blog.163.com/mikelisuper/blog/static/72241886201112745343430/
posted on 2013-06-24 15:32 freeliver54 阅读(7574) 评论(1) 编辑 收藏 举报