现在的位置: 首页 > 综合 > 正文

主流数据库的SQL语法差异分析

2013年01月14日 ⁄ 综合 ⁄ 共 5911字 ⁄ 字号 评论关闭

       主流数据库系统支持的SQL语句的差异主要有以下几点:数据类型的差异;运算符的差异;函数的差异;常用SQL的差异;取元数据信息的差异。

1.1.1数据类型的差异

            
整数类型:在MYSQL中整数相关的类型有tinyintsmallintmediumintintinteger
bigint;在MSSQLServer中整数相关的类型有bitintsmallinttinyintbigint;在Oracle中整数相关的类型有number;在DB2中整数相关的类型有smallintintegerbigint

            
数值类型:在MYSQL中数值相关的类型有floatdoublerealdecimalnumeric
MSSQLServer中数值相关的类型有decimalnumericmoneysmallmoneyfloatreal;在Oracle中数值相关的类型有number;在DB2中数值相关的类型有decimalnumericrealdouble

            
字符类型:在MYSQL中字符相关的类型有charvarchartinytexttextmediumtext
longtextenumset;在MSSQLServer中字符相关的类型有charvarchartextncharnvarcharntext;在Oracle中字符相关的类型有charvarchar2nvarchar2clobnclobDB2中字符相关的类型有CHARACTERVARCHARLONG 
VARCHAR
CLOBGRAPHICVARGRAPHICLONGVARGRAPHIC

            
日期时间类型:在MYSQL中日期时间相关的类型有datetimedatetimetimestamp
year;在MSSQLServer中日期时间相关的类型有datetimesmalldatetimetimestamp;在Oracle中日期时间相关的类型有date
timestamp;在DB2中日期时间相

关的类型有DATETIMETIMESTAMP

            
二进制类型:MYSQLOracleDB2都支持Blob类型,而在MSSQLServer中支持image
类型。

1.1.2运算符的差异

            
在不同的数据库系统中字符串拼接的方式是不同的,下面的主流数据库系统对字符串拼
接的支持:

             MYSQL:在MYSQL中进行字符串的拼接要使用CONCAT函数,CONCAT函数支持一个或者多个参数,比如CONCAT('Hello',1,'World')MYSQL中还提供了另外一个进行字符串拼接的函数CONCAT_WSCONCAT_WS可以在待拼接的字符串之间加入指定的分

隔符,比如CONCAT_WS ('Hello',1,'World')

              MSSQLServerMSSQLServer中可以直接使用加号“+”来拼接字符串,比如'Hello'+'World'

             OracleOracle中使用“||”进行字符串拼接,比如'Hello'||'World';除了“||”,Oracle还支持使用CONCAT()函数进行字符串拼接,不过与MYSQLCONCAT()函数不同,OracleCONCAT()函数只支持两个参数,不支持两个以上字符串的拼接。

             DB2DB2中使用“||”进行字符串拼接,比如'Hello'||'World'

1.1.3函数的差异

            
不同数据库系统对函数的差异是非常大的,不仅同样功能的函数在不同数据库系统中的
名称不同,而且一些高级的函数也并不是在所有数据库系统中都有提供支持。比如将一个字符串转换为小写的函数在MYSQL,MSSQLServerOracle中为LOWER,而在DB2中则为LCASEMYSQL中支持IF函数,而在其他数据库系统中则只有通过变通方式才能实现。

1.1.4常用SQL的差异

            
主流数据库系统对SELECTUPDATEDELETECREATEDROP等基本语法的支
持是相同,不过在一些高级特性支持方面仍然有差异。

1.1.4.1限制结果集行数

            
在实现分页检索、排行榜等功能的时候,需要限制检索的结果集行数,不同的数据库系
统对此的支持是不同的。

             MYSQL中提供了LIMIT关键字用来限制返回的结果集,比如:

SELECT * FROM T_Employee

ORDERBY FSalary DESC LIMIT 2,5

             MSSQLServerMSSQLServer中提供了TOP关键字用来返回结果集中的前N条记录,比如:

select top 5 *from T_Employee

order by FSalaryDesc

MSSQLServer2005中还可以使用窗口函数ROW_NUMBER()实现限制结果集行数,比如:

SELECTROW_NUMBER() OVER(ORDER BY FSalary), FNumber,

FName,FSalary,FAge 

FROM T_Employee

             OracleOracle中支持窗口函数ROW_NUMBER(),其用法和MSSQLServer2005中相同;除了窗口函数ROW_NUMBER()Oracle中还提供了更方便的rownum机制,Oracle为每个结果集都增加了一个默认的表示行号的列,这个列的名称为rownum。使用rownum可以很轻松的取得结果集中前N条的数据行,比如:

SELECT * FROMT_Employee

WHERErownum<=6

ORDER BY FSalaryDesc

                DB2DB2中支持窗口函数ROW_NUMBER(),其用法和MSSQLServer2005以及Oracle中相同。除此之外,DB2还提供了FETCH关键字用来提取结果集的前N行,比如:

SELECT * FROMT_Employee

ORDER BY FSalaryDesc

FETCH FIRST 6ROWS ONLY

1.1.4.2
删除索引

            
索引的定义在各个数据库系统中基本相同,但是删除索引的语法则各有不同,比如删除
T_Person表中定义的名称为idx1的索引在不同数据库系统下的SQL语句如下:

MYSQL:

DROP INDEX idx1ON T_Person

MSSQLServer:

DROP INDEXT_Person.idx1

Oracle,DB2:

DROP INDEX idx1

1.1.5取元数据信息的差异

在开发一些功能的时候有时需要查询数据的一些信息,比如数据库的名称、当前用户名、数据库中有哪些表、指定表的字段定义等,这些信息被称为元数据。对元数据的支持在不同的数据库系统下的差异性是非常大的。

1.1.5.1
取数据库信息

             MYSQL中可以通过函数来取得数据库的信息,包括当前数据库名、版本、当前登录用户等信息:DATABASE()函数返回当前数据库名;VERSION()函数以一个字符串形式返回MySQL服务器的版本;USER()函数(这个函数还有SYSTEM_USERSESSION_USER两个别名)返回当前MySQL用户名。

             MSSQLServer中也可以通过函数来取得数据库的信息:APP_NAME()函数返回当前会话的应用程序名称;CURRENT_USER函数(注意这个函数不能带括号调用)返回当前登陆用户名;HOST_NAME()函数返回工作站名。

不过,在MSSQLServer中如果要查询当前数据库名,则必须到系统表sysprocesses中查询,SQL语句如下:

select 

dbname = 

case when dbid =0 then null 

when dbid<> 0 then db_name(dbid) 

end 

frommaster..sysprocesses

wherespid=@@SPID 

系统表“master..sysprocesses”中存储了当前数据库系统中的进程信息,而@@SPID则表示当前进程号。

             Oracle中使用USER函数用来取得当前登录用户名,注意使用这个函数的时候不能使用括号形式的空参数列表,也就是USER()这种使用方式是不对的。正确使用方式如下:

SELECT
USER FROM DUAL

             Oracle中使用USERENV()函数用来取得当前登录用户相关的环境信息,USERENV()函数有一个参数,参数的可选值如下:ISDBALANGUAGETERMINALSESSIONIDENTRYIDLANGINSTANCE

             DB2中可以通过CURRENT_USER来取得当前登陆用户名,而CURRENT_SERVER用来取得当前服务名,比如:

SELECT CURRENT_USER,CURRENT_SERVER 

FROM
sysibm.sysdummy1

DB2中取得当前数据库的版本的SQL语句如下:

SELECT *
FROM sysibm.sysversions

1.1.5.2
取得所有表

             MYSQL中取得当前数据库中所有表定义的SQL语句如下:

SHOW TABLES

               MSSQLServer中的系统表sysobjects中记录了当前系统中定义的对象,其中xtype字段等于U的记录为表定义,因此取得当前数据库中所有表定义的SQL语句如下:

SELECT name FROMsysobjects where xtype='U'

             Oracle中的系统表all_objects中记录了当前系统中定义的对象,其中Object_Type字段等于TABLE的记录为表定义,因此取得当前数据库中所有表定义的SQL语句如下:

selectObject_Name from all_objects where Object_Type='TABLE'

             DB2中的系统表all_syscat.tables中记录了当前系统中定义的表和视图,其中TYPE字段等于T的记录为表定义,因此取得当前数据库中所有表定义的SQL语句如下:

SELECT TABNAMEFROM syscat.tables where TYPE='T'

1.1.5.3
取得指定Schema下的表

             MYSQL中取得指定Schema下所有表定义的SQL语句如下(假设Schema名为demoschema):

SHOW TABLES
FROMdemoschema

             MSSQLServer中的系统表sysobjects中记录了当前系统中定义的对象,其中xtype字段等于U的记录为表定义,因此取得当前数据库中所有表定义的SQL语句如下(假设Schema名为demoschema):

SELECT name FROMdemoschema.sysobjects where xtype='U'

             Oracle中的系统表all_objects中记录了当前系统中定义的对象,其中Object_Type字段等于TABLE的记录为表定义,OWNER字段为Schema,因此取得当前数据库中所有表定义的SQL语句如下(假设Schema名为demoschema):

selectObject_Name from all_objects 

whereObject_Type='TABLE' and OWNER='demoschema'

             DB2中的系统表all_syscat.tables中记录了当前系统中定义的表和视图,其中TYPE字段等于T的记录为表定义,TABSCHEMA字段为Schema,因此取得当前数据库中所有表定义的SQL语句如下(假设Schema名为demoschema):

SELECT TABNAMEFROM syscat.tables 

where  TYPE='T' and TABSCHEMA='demoschema'

1.1.5.4
取得指定表的字段定义

             MYSQL中取得指定表的字段定义(假设表名为mytable):

DESCRIBE mytable

               MYSQLServer中取得指定表的字段定义(假设表名为mytable):

SELECTsyscols.name as COLUMN_NAME,

st.name asDATA_TYPE,

syscomm.text asDATA_DEFAULT,

syscols.isnullableas NULLABLE

FROM syscolumnssyscols

left joinsystypes st on syscols.xusertype=st.xusertype

left joinsyscomments syscomm on syscols.cdefault=syscomm.id

where syscols.id=OBJECT_ID(N'mytable')

order bysyscols.id,syscols.colorder

               Oracle中的all_tab_columns表是系统中所有表的字段定义,其中TABLE_NAME字段为表名,因此取得指定表的字段定义(假设表名为mytable):

selectCOLUMN_NAME,DATA_TYPE,DATA_DEFAULT,NULLABLE

fromall_tab_columns where TABLE_NAME ='MYTABLE'

                DB2中的syscat.columns表是系统中所有表的字段定义,其中TABNAME字段为表名,因此取得指定表的字段定义(假设表名为mytable):

select COLNAMEas COLUMN_NAME, TYPENAME as DATA_TYPE,DEFAULT as

DATA_DEFAULT,NULLSas NULLABLE

fromsyscat.columns where TABNAME='MYTABLE'

抱歉!评论已关闭.