主流数据库的SQL语法差异分析
主流数据库系统⽀持的SQL语句的差异主要有以下⼏点:数据类型的差异;运算符的差异;函数的差异;常⽤SQL的差异;取元数据信息的差异。
1.1.1数据类型的差异
整数类型:在MYSQL中整数相关的类型有tinyint、smallint、mediumint、int、integer和bigint;在MSSQLServer中整数相关的类型
有bit、int、smallint、tinyint和bigint;在Oracle中整数相关的类型有number;在DB2中整数相关的类型有smallint、integer和bigint。
数值类型:在MYSQL中数值相关的类型有float、double、real、decimal和numeric;在MSSQLServer中数值相关的类型
有decimal、numeric、money、smallmoney、float和real;在Oracle中数值相关的类型有number;在DB2中数值相关的类型
有decimal、numeric、real和double。
字符类型:在MYSQL中字符相关的类型有char、varchar、tinytext、text、mediumtext、longtext、enum和set;在MSSQLServer中字符相关的类型有char、varchar、text、nchar、nvarchar和ntext;在Oracle中字符相关的类型
有char、varchar2、nvarchar2、clob和nclob;在DB2中字符相关的类型有CHARACTER、VARCHAR、LONG
VARCHAR、CLOB、GRAPHIC、VARGRAPHIC和LONGVARGRAPHIC。
⽇期时间类型:在MYSQL中⽇期时间相关的类型有date、time、datetime、timestamp和year;在MSSQLServer中⽇期时间相关的类型
有datetime、smalldatetime和timestamp;在Oracle中⽇期时间相关的类型有date 和timestamp;在DB2中⽇期时间相
关的类型有DATE、TIME和TIMESTAMP。
⼆进制类型:MYSQL、Oracle和DB2都⽀持Blob类型,⽽在MSSQLServer中⽀持image类型。
1.1.2运算符的差异
在不同的数据库系统中字符串拼接的⽅式是不同的,下⾯的主流数据库系统对字符串拼接的⽀持:
MYSQL:在MYSQL中进⾏字符串的拼接要使⽤CONCAT函数,CONCAT函数⽀持⼀个或者多个参数,⽐
如CONCAT('Hello',1,'World');MYSQL中还提供了另外⼀个进⾏字符串拼接的函数CONCAT_WS,CONCAT_WS可以在待拼接的字符串之间加⼊指定的分
隔符,⽐如CONCAT_WS ('Hello',1,'World')。
MSSQLServer:MSSQLServer中可以直接使⽤加号“+”来拼接字符串,⽐如'Hello'+'World'。
Oracle:Oracle中使⽤“||”进⾏字符串拼接,⽐如'Hello'||'World';除了“||”,Oracle还⽀持使⽤CONCAT()函数进⾏字符串拼接,不过
与MYSQL的CONCAT()函数不同,Oracle的CONCAT()函数只⽀持两个参数,不⽀持两个以上字符串的拼接。
DB2:DB2中使⽤“||”进⾏字符串拼接,⽐如'Hello'||'World'。
1.1.3函数的差异
不同数据库系统对函数的差异是⾮常⼤的,不仅同样功能的函数在不同数据库系统中的名称不同,⽽且⼀些⾼级的函数也并不是在所有数据库系统中都有提供⽀持。⽐如将⼀个字符串转换为⼩写的函数在MYSQL,MSSQLServer和Oracle中为LOWER,⽽在DB2中则
为LCASE;MYSQL中⽀持IF函数,⽽在其他数据库系统中则只有通过变通⽅式才能实现。
1.1.4常⽤SQL的差异
主流数据库系统对SELECT、UPDATE、DELETE、CREATE、DROP等基本语法的⽀持是相同,不过在⼀些⾼级特性⽀持⽅⾯仍然有差异。
1.1.4.1限制结果集⾏数
在实现分页检索、排⾏榜等功能的时候,需要限制检索的结果集⾏数,不同的数据库系统对此的⽀持是不同的。
MYSQL中提供了LIMIT关键字⽤来限制返回的结果集,⽐如:
SELECT * FROM T_Employee
ORDERBY FSalary DESC LIMIT 2,5
MSSQLServer:MSSQLServer中提供了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
Oracle:Oracle中⽀持窗⼝函数ROW_NUMBER(),其⽤法和MSSQLServer2005中相同;除了窗⼝函数ROW_NUMBER(),Oracle中还提供了更⽅便的rownum机制,Oracle为每个结果集都增加了⼀个默认的表⽰⾏号的列,这个列的名称为rownum。使⽤rownum可以很轻松的取得结果集中前N条的数据⾏,⽐如:
SELECT * FROMT_Employee
WHERErownum<=6
ORDER BY FSalaryDesc
DB2:DB2中⽀持窗⼝函数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_USER、SESSION_USER两个别名)返回当前MySQL⽤户名。
MSSQLServer中也可以通过函数来取得数据库的信息:APP_NAME()函数返回当前会话的应⽤程序名称;CURRENT_USER函数(注意这个函数不能带括号调⽤)返回当前登陆⽤户名;HOST_NAME()函数返回⼯作站名。
不过,在MSSQLServer中如果要查询当前数据库名,则必须到系统表sysprocesses中查询,SQL语句如下:
s elect
dbname =
case when dbid =0 then null
when dbid<> 0 then db_name(dbid)
end
frommaster..sysprocesses
wherespid=@@SPID
系统表“master..sysprocesses”中存储了当前数据库系统中的进程信息,⽽”则表⽰当前进程号。
Oracle中使⽤USER函数⽤来取得当前登录⽤户名,注意使⽤这个函数的时候不能使⽤括号形式的空参数列表,也就是USER()这种使⽤⽅式是不对的。正确使⽤⽅式如下:
SELECT USER FROM DUAL
Oracle中使⽤USERENV()函数⽤来取得当前登录⽤户相关的环境信息,USERENV()函数有⼀个参数,参数的可选值如
下:ISDBA、LANGUAGE、TERMINAL、SESSIONID、ENTRYID、LANG和INSTANCE。
DB2中可以通过CURRENT_USER来取得当前登陆⽤户名,⽽CURRENT_SERVER⽤来取得当前服务名,⽐如:
SELECTCURRENT_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下的表
基本的sql语句有哪些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,
< 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.lorder
Oracle中的all_tab_columns表是系统中所有表的字段定义,其中TABLE_NAME字段为表名,因此取得指定表的字段定义(假设表名
为mytable):
selectCOLUMN_NAME,DATA_TYPE,DATA_DEFAULT,NULLABLE
fromall_tab_columns where TABLE_NAME ='MYTABLE'
DB2中的lumns表是系统中所有表的字段定义,其中TABNAME字段为表名,因此取得指定表的字段定义(假设表名为mytable):select COLNAMEas COLUMN_NAME, TYPENAME as DATA_TYPE,DEFAULT as
DATA_DEFAULT,NULLSas NULLABLE
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论