ASE与Oracle差异.docx
《ASE与Oracle差异.docx》由会员分享,可在线阅读,更多相关《ASE与Oracle差异.docx(67页珍藏版)》请在冰豆网上搜索。
ASE与Oracle差异
1.ASE数据类型
2.数据类型差异表
Oracle
Sybase
Comments
VARCHAR2(n)
VARCHAR(n)
NVARCHAR2(n)
NVARCHAR(n)
CHAR
CHAR
CHAR
(1)
BIT
True/false和yes/no类型的数据可以被存储
占用1个字节的空间,可以存放0或者1
CHAR(n)
CHAR(n)
NCHAR(n)
NCHAR(n)
NUMBER(3)
TINYINT
Sybasetinyint范围是0-255
NUMBER(4)
SMALLINT
Sybasesmallint范围是–32768to+32767
NUMBER(9)
INT
integer的范围是从2^31-1(2,147,483,647)到-2^31
(-2,147,483,648)
Oracle
Sybase
Comments
NUMBER(19,4)
MONEY
Money和samllmoney数据类型存储金融数据。
存储为保留为小数点后4位精度,小数点前面的数字,对于smallmoney大约为+/-$214K,对于money大约为+/-922T。
NUMBER(19,4)
SMALLMONEY
同上.
NUMBER
REAL,FLOAT,DOUBLE
FLOAT
FLOAT,REAL
FLOAT(p)
DOUBLEPRECISION
FLOAT(p)
FLOAT(p)
NUMBER(p,s)
NUMERIC(p,s)
Oracle数据库number(p,s)数据类型对应的是ASE数据库的numeric和decimal数据类型。
NUMBER(p,s)
DECIMAL(p,s)
可参照上面的Oraclenumber的数据类型。
BINARY_FLOAT
-
BINARY_DOUBLE
-
DATE
DATETIME
Datatime的数值可以精确到1/300秒,前提是所在的平台必须也要能支持到这一粒度,存储的时间是从1753/1/1到9999/12/31
TIMESTAMP
DATETIME
DATEDATE
DATE
可以存储的时间范围是0001/1/1到9999/12/31。
占用4个字节的存储空间
SMALLDATETIME
可以存储的时间范围是1900/1/1到2079/6/6,可以精确到分钟。
占用4个字节存储
TIME
Time存储的范围是00:
00:
00:
000and23:
59:
59:
999
TIMESTAMP
DATETIME
Datetime的值可以精确到1/300秒
CLOB
Text
Text是一个变长的字段,它可以存储存储2,147,483,647(2^31-1)字节的可打印字符。
BLOB
Image
Image是一个可变长的字段,它可以存储2,147,483,647(2^31-1)字节的裸数据。
LONG
TEXT
tText是一个变长的字段,它可以存储存储2,147,483,647(2^31-1)字节的可打印字符。
RAW(n)
VARBINARY(n)
RAW(n)
IMAGE
BFILE
-
不支持
3.SQL语言差异
下面是关于两种SQL语言差异的列表和实例:
Oracle
Sybase
转换
#
代码
翻译
操作
常规
1
/
GO
搜索“/”并替换为“GO”
这个"/"包含在SQL命令的结尾。
它等价于Sybase的GO命令。
2
SQL中的分号(;)
用空格全局替换之。
搜索并替换
3
变量的定义
比如:
x:
=表达式
SELECT@x=表达式
手工修改
4
参数名的转换
在Sybase中需变量前增加“@”符号。
如果Oracle的变量长度是30个字符,可能会带来Sybase的30个字符长度限制的问题。
替换或手工修改
5
select…into变量
这是Oracle中将选择出来的数据赋给宿主语言的变量。
使用Sybase的语法:
select@variable1=col1,@veriable2=col2…
手工修改
6
常数
检查其使用的范围(局部/全局)然后将其定义为变量
手工修改
7
%TYPE
寻找Oracle数据类型域的定义,然后用代码还原
手工重新编码
8
%ROWTYPE
将每个域分别按单独的变量编码.
手工重新编码
9
ISRECORDOF
将每个域分别按单独的变量编码.
手工编码转换
10
ISTABLEOF
使用临时表,然后使用FETCH或SELECT处理每一行。
重新设计代码以使用游标查询临时表来处理数据行
手工编码转换
11
ORACLE的调用dbms
重新编码以使用Sybase的函数,比如RAISEERROR或PRINT和其他Sybase系统存储过程
手工重新编码
12
动态SQL
使用SybaseT-SQL重新编码。
手工重新编码
13
使用缺省值
例如:
blood_type_char:
='O'
使用“=”。
例如:
@blood_group_char='O'
搜索并替换
14
EXITWHENnDbedDone=1ANDnAWMSDone=1;
将其转换成一个表达式,然后将其值作为If的条件,并使用T-SQL语句BREAK或RETURN确定程序的执行流程
手工重新编码
15
INITCAP
将其转换成存储过程或OpenClient/OpenServer的应用程序。
手工重新编码
16
SEQUENCE或CREATESEQUENCE
例如:
CREATESEQUENCEtest_seqMINVALUE1
STARTWITH1
INCREMENTEDby1
CACHE20;
INSERTINTOm_tabbleVALUES(test_seq.nextval,…)
设置一个关键值表,然后定义存储过程来模拟ORACLE中的NEXTVAL功能。
例如:
CREATETABLEmy_seq(seqint)
go
INSERTINTOmy_seqselect0
go
CREATEPROCEDUREget_seq(@seqint
OUTPUT)
AS
UPDATEmy_seqSETseq=seq+1
SELECT@seq=seqFROMmy_seq
go
DECLARE@seqint
EXECget_seq@seqOUTPUT
INSERTINTOm_tableVALUES(@seq,…)
Go
手工重新编码,将会带来schema的变化
17
synonym
用database.table.column_name手工重新编码,使之为每个字段所引用。
手工重新编码
18
TYPEAccountingRecISRECORD
手工对每个域编码,使其那为一个变量
手工重新编码
19
UNION
UNION
20
userenv('sessionid')
master..sysprocesses中的kernelpid唯一标识了每个会话的ID。
使用这样等价的语句:
selectkpidfrommaster..sysprocesseswherestatus='running'
手工重新编码
21
局部和全局变量的处理
可能会在存储过程中使用局部变量,它们的值可以被传递到调用者或被调用者中。
在那些需要将package转换那各自分离的存储过程时,使用的局部或全局变量可能会涉及修改成特殊的代码。
手工重新编码
22
用户自定义的函数
使用Sybase存储过程。
EXECUTE命令用于运行存储过程。
在ASE15.0.2可以支持用户自定义的函数。
手工重新编码
23
IS
在存储过程中定义,转换成AS
替换
24
存储过程中的NUMBER类型
使用NUMERIC(10)
25
PackagesandProcedures
PrivateandPublic
尽可能地将Package转换成各自单一的存储过程。
手工重新编码
26
触发器(之前触发器)
可以在Sybase中使用"规则(rule)"对确定的列设定可接受的数据条件。
手工重新编码
27
RETURNBOOLEAN
由于boolean不是一个整数表达式,它不允许作为SybaseRETURN语句的一个参数。
所以将其转换成一个整数表达式(0,1):
@falseinteger=1并且@true
interger=0;因此存储过程应该返回@false或@true.
手工重新编码
操作符
1
串联操作符
||
“+”
将“||”替换成“+”
Sybase支持字符串的串联操作。
操作符是”+“
2
取模运算
MOD
%
替换
3
比较操作
4
IFrAcct.AuthNumISNULL
THEN....BEGIN..END
E.gIFVARISNULL
Or
IFVARISNOTNULL
评估代码并将NULL转换成ISNULL或NOTNULL。
可能会在schema级涉及列定义的修改。
例如:
IF@VAR=NULL
Or
IF@VAR!
=NULL
手工重新编码并可能会有schema的修改
函数
系统函数
1
CEIL
返回大于或等于指定值的最小整数。
CEILING
替换
2
TRUNC
CONVERT(INT,…)
替换
字符串函数
3
SUBSTR()
SUBSTRING()
替换
4
LENGTH()
CHAR_LENGTH()
替换
5
CHR()
CHAR()
替换
6
TO_CHAR
CONVERT
手工重新编码
7
TO_NUMBER
CONVERT(NUMERIC(n,n),field)
手工重新编码
8
转换字符到数字
有用户自定义的字符转换到数字的程序。
可以用Sybase函数(convert(decimal(x,y),“string”)来替换。
对于可能有千年问题的应用,设置X=18,Y=9
替换并手工重新编码
日期函数
9
DATE函数和日期计算
转换成Sybase的日期处理程序。
Sybase支持大量的日期和时间处理函数,比如DATEADD,
DATEDIFF,DATEPART(),DATENAME(),timestamp等等。
替换并手工重新编码
10
LAST_DAY
转换到Sybase的存储过程或OpenClient/OpenServer程序
手工重新编码
11
SYSDATE,SYSTIMESTAMP
使用GETDATE()和正确的格式
替换
12
DATE和TIMESTAMP函数
在一些情况下用局部变量代替,或者可以重新架构使用Sybase的用户自定义数据类型TIMESTAMP.
手工重新编码
13
TRUNC(dstartdate)
使用Sybase的CONVERT并使之返回带有00:
00小时格式的日期
手工重新编码
转换函数
14
NVL
用ISNULL替换
替换
15
NVL2
E.gNVL2(salary,salary*2,0)
CASE表达式,例如:
CASE
WHENsalary=NULLTHEN0
ELSEsalary*2
END
手工重新编码
条件函数
16
DECODE,用于代替'if-else'的逻辑
转换到Sybase的case表达式。
例如:
SELECTSTUDENT_ID,
(CASEWHENCOURSE_ID=101THEN1
ELSE0END)ASCOURSE_101,
(CASEWHENCOURSE_ID=105THEN1
ELSE0END)ASCOURSE_105,
(CASEWHENCOURSE_ID=201THEN1
ELSE0END)ASCOURSE_201,
(CASEWHENCOURSE_ID=210THEN1
ELSE0END)ASCOURSE_210,
(CASEWHENCOURSE_ID=300THEN1
ELSE0END)ASCOURSE_300
GROUPBYSTUDENT_ID
ORDERBYSTUDENT_ID
手工重新编码
连接(join)
1
col1=col2(+)
或
col1(+)=col2
转换到SybaseT-SQL:
col1=*col2
或
col2*=col1)
手工重新编码
游标
1
CURSOR的使用
转换CURSOR的定义代码到Sybase的代码
手工重新编码
2
CURSOR的一些操作选项
%ISOPEN,%NOTFOUND,
%FOUND,%ROWCOUNT
使用@@rowcount和@@sqlstatus全局变量
手工重新编码
程序流的控制
1
IFexpressionTHEN
statement;
ENDIF;
IFexpression
statement
当statement有多条语句时,使用BEGIN和END作为该语句块的标识符。
手工重新编码
2
EXIT;
BREAK
替换
3
LOOPandENDLOOP
转换到T-SQL语句WHILE,CONTINUE,GOTO和IF-ELSE
手工重新编码
错误处理
1
SQLCODE
"@@error
替换
2
一般错误的处理
通过Sybase的系统函数监测错误的条件。
加入代码以处理异常和错误。
手工重新编码
3
WHENTOO_MANY_ROWS
THEN(ErrorHandling)
通过Sybase的@@rowcount监测TOO_MANY_ROWS,然后加入错误处理代码。
手工重新编码
4
WHENNO_DATA_FOUND
通过Sybase的@@rowcount监测,然后加入错误处理代码。
手工重新编码
5
诸如EXCEPTION的错误处理
用Sybase的错误和消息处理代替
手工重新编码
6
cursor_already_open,
dup_val_on_index,
invalid_cursor,
invlaid_number,login_denied,
no_data_found,
not_logged_on,
program_error,storage_error,
timeout_on_resource,
too_many_rows,
transaction_backed_out,
value_error,zero_divide.
通过Sybase的系统函数监测错误的条件。
加入代码以处理异常和错误。
手工重新编码
7
WHENDUP_VAL_ON_INDEX
THENEXCEPTION
根据INSERT或其他命令返回的错误代码判断。
对于这种类型的错误,增加错误处理代码。
手工重新编码
8
PRAGMAandotherOracle
compilerdirectives
通过Sybase的系统函数监测错误的条件。
加入代码以处理异常和错误。
手工重新编码
9
RAISE_APPLICATION_ERROR
(-20300,'TaskhasnoReason
Codesupplied');
在Sybase有几种方法可以处理。
最简便的方法是使用EAISEERROR或PRINT命令打印出错误消息文本。
其他的方法是创建系统消息并将其链接到逻辑条件中。
手工重新编码
SQL差异的举例:
字符串的处理:
oracle="SUBSTR(phone,1,3)ASAREA_CODE"
sybase="SUBSTRING(phone,1,3)ASAREA_CODE"
oracle="(first_name||''||mi_name||''||last_name)asname"
sybase="(first_name+''+mi_name+''+last_name)asname"
数字的处理:
oracle="SELECTstudent_id='100'"(acceptable,butnotagoodidea)
sybase="SELECTstudent_id=100"
oracle="LTRIM(RTRIM(TO_CHAR(course_ceu,'999D99')))"
sybase="RTRIM(CONVERT(CHAR,ROUND(course_ceu,2))))"
oracle="LTRIM(RTRIM(TO_CHAR(COURSE_CEU,'999')))"
sybase="RTRIM(CONVERT(CHAR,CONVERT(INT,COURSE_CEU))))"(notROUND)
控制结构:
oracle=LOOP
monthly_value:
=daily_value*31;
EXITWHENmonthly_value>4000;
ENDLOOP;
Sybase=WHILE@monthly_value<=4000
SELECT@monthly_value=@daily_value*31
Oracle=FORiIN1..5
…
ENDLOOP;
Sybase=DECLARE@lbint,@ubint,@i
SELECT@lb=1,@i=@lb,@ub=5
WHILE@i<=@ub
BEGIN
…
SELECT@i=@i+1
END
存储过程:
执行一个存储过程:
Oracle=Result:
=proc_name(param1=>NAME,param2=>value);
Sybase=EXEC@Result=proc_name@param1=@NAME,@param2=@valueoutput
日期的处理:
oracle="TO_CHAR(start_date,'FMHH12FM:
MIPM')"
sybase="SUBSTRING(RTRIM(CONVERT(CHAR,start_date,0)),13,8)"
oracle="TO_CHAR(sysdate,'mm/yy')"
sybase="SUBSTRING(RTRIM(CONVERT(CHAR,GETDATE(),3)),4,5)"
oracle="SELECTadd_months(xyz,3)FROMdual
sybase="SELECTDATEADD(month,3,xyz)FROMdual"
oracle="credit_expiration_date=last_day(TO_DATE('"+cc_date+"'))"
sybase="credit_expiration_date=CONVERT(DATETIME,"
sybase+="RTRIM(CONVERT(CHAR,"+s_month+"))+'/'+"
sybase+="RTRIM(CONVERT(CHAR,DATEDIFF(DAY,"
sybase+="RTRIM(CONVERT(CHAR,"+s_month+"))+"
sybase+="'/1/'+RTRIM(CONVERT(CHAR,"+nYear+")),"
sybase+="DATEADD(MONTH,1,"
sybase+="RTRIM(CONVERT(CHAR,"+s_month+"))+"
sybase+="'/1/'+RTRIM(CONVERT(CHAR,"+nYear+"))))))+"
sybase+="'/'+RTRIM(CONVERT(CHAR,"+nYear+")))"
其他:
oracle=DECLARECOUNTINT;
BEGIN
SELECTCOUNT()intoCOUNTFROMXYZ;
END;
sybase=declare@COUNYint
SELECT@COUNT=COUNT(*)FROMXYZ
oracle="SELECTNULLasstart_date"
sybase="SELECTCONVERT(DATETIME,NULL)asstart_date"
sybase="SELECT''asstart_date"(better)
oracle="SELECTNULLascourse_id"
sybase="SELECTCONVERT(INT,NULL)ascourse_id"
sybase="SELECT0ascourse_id"(better)
oracle="SELECTNULLasfirst_name"
sybase="SELECTCONVERT(CHAR,NULL)asfirst_name"
sybase="SELECT''asfirst_name"(better)
外连接的语法:
oracle="student.student_id=student_company.student_id(+)"
sybase="student.student_id*=student_company.student_id"
oracle="student_company.student_id(+)=student.student_id"
sybase="student_company.student_id=*student.student_id"
限制:
SybaseASE不允许在一个已经有外连接的表上再作一个其他的连接(example#1)。
另外,如果执行带有一个外连接的查询,它的结果集列