本文通过整理网络上的关于数据库的文章以及参考DBMS的参考手册、旨在比较MySQL、SQL SERVER与ANSI SQL的语法,以编写跨平台的数据库应用程序。如果存在不合理之处,请及时修改并发布新的版本以适应新的需求,方便大家的工作。
一、数据类型
下列表列出了 ANSI SQL 数据类型和等效的数据库引擎 SQL数据类型还有它们的有效同义字。
ANSI SQL | MySQL 的数据类型 | Microsoft SQL |
BIT,BIT VARYING | BINARY | BINARY, VARBINARY |
不支持 | BIT | BIT |
不支持 | TINYINT | |
不支持 | COUNTER |
|
不支持 | 不支持 | MONEY |
DATE, TIME, TIMESTAMP | DATE、DATETIME、TIMESTAMP、TIME、YEAR | DATETIME |
不支持 | 不支持 | UNIQUEIDENTIFIER |
DECIMAL | DECIMAL | DECIMAL |
REAL | REAL | REAL |
DOUBLE PRECISION,FLOAT | DOUBLE PRECISION, | FLOAT |
SMALLINT | SMALLINT | SMALLINT |
INTEGER | INTEGER | INTEGER |
不支持 | BIGINT | 不支持 |
INTERVAL | 不支持 | 不支持 |
不支持 | 不支持 | IMAGE |
不支持 | TEXT、BLOB | TEXT |
不支持 | TINYBLOB, TINYTEXT、MEDIUMBLOB, MEDIUMTEXT、LONGBLOB, LONGTEXT、ENUM('value1','value2',...)、SET('value1','value2',...) | 不支持 |
CHARACTER, CHARACTER VARYING, NATIONAL CHARACTER, NATIONAL CHARACTER VARYING |
CHAR(n)、VARCHAR(M) | CHAR, VARCHAR, NCHAR, NVARCHAR |
注意
TIMESTAMP不再作为DATETIME的同义字被支持。
NUMERIC 不再作为 FLOAT或 DOUBLE的同义字被支持。NUMERIC现在被用作DECIMAL的同义字。
LONGTEXT字段总被储存于 Unicode 表示格式.
CHAR字段总被储存于 Unicode 表示格式,和 ANSI SQL NATIONAL CHAR 数据类型等效。
二、标准SQL语句总结
《SQL 语法参考手册(SQL)》
DB2 提供了关连式资料库的查询语言 SQL (Structured Query Language),是一种非常口语化、既易学又易懂的语法。此一语言几乎是每个资料库系统都必须提供的,用以表示关连式的*作,包含了资料的定义(DDL)以及资料的处理(DML)。SQL原来拼成SEQUEL,这语言的原型以“系统 R“的名字在 IBM 圣荷西实验室完成,经过IBM内部及其他的许多使用性及效率测试,其结果相当令人满意,并决定在系统R 的技术基础发展出来 IBM 的产品。而且美国国家标准学会(ANSI)及国际标准化组织(ISO)在1987遵循一个几乎是以 IBM SQL 为基础的标准关连式资料语言定义。
要说明的是,各种数据库引擎对于标准SQL的扩展,导致有些标准SQL在各种数据库引擎中并不能得到很好的支持!即使得到支持,有些语句在不同的数据库引擎中将有可能得到不一样的结果。
(一)、数据定义 DDL(Data Definition Language)
数据定义语言是指对数据的格式和形态下定义的语言,他是每个数据库要建立时候时首先要面对的,举凡数据分哪些表格关系、表格内的有什麽栏位主键、表格和表格之间互相参考的关系等等,都是在开始的时候所必须规划好的。
1、建表格:
Create TABLE table_name(
column1 DATATYPE [NOT NULL] [NOT NULL PRIMARY KEY],
column2 DATATYPE [NOT NULL],
...)
说明:
DATATYPE --是数据的格式,详见表。
NOT NULL --可不可以允许数据有空的(尚未有数据填入)。
PRIMARY KEY --是本表的主键。
2、更改表格
Alter TABLE table_name
ADD COLUMN column_name DATATYPE
说明:增加一个栏位(没有删除某个栏位的语法。
Alter TABLE table_name
ADD PRIMARY KEY (column_name)
说明:更改表得的定义把某个栏位设为主键。
Alter TABLE table_name
Drop PRIMARY KEY (column_name)
说明:把主键的定义删除。
3、建立索引
Create INDEX index_name ON table_name (column_name)
说明:对某个表格的栏位建立索引以增加查询时的速度。
4、删除
Drop table table_name
Drop index index_name
(二)、数据类型 DATATYPEs
smallint
16 位元的整数。
interger
32 位元的整数。
decimal(p,s)
p 精确值和 s 大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数
点後有几位数。如果没有特别指定,则系统会设为 p=5; s=0 。
float
32位元的实数。
double
64位元的实数。
char(n)
n 长度的字串,n不能超过 254。
varchar(n)
长度不固定且其最大长度为 n 的字串,n不能超过 4000。
graphic(n)
和 char(n) 一样,不过其单位是两个字元 double-bytes, n不能超过127。这个形态是为
了支援两个字元长度的字体,例如中文字。
vargraphic(n)
可变长度且其最大长度为 n 的双字元字串,n不能超过 2000。
date
包含了 年份、月份、日期。
time
包含了 小时、分钟、秒。
timestamp
包含了 年、月、日、时、分、秒、千分之一秒。
(三)、数据操作 DML (Data Manipulation Language)
数据定义好之後接下来的就是数据的操作。数据的操作不外乎增加数据(insert)、查询数据(query)、更改数据(update) 、删除数据(delete)四种模式,以下分 别介绍他们的语法:
1、增加数据:
Insert INTO table_name (column1,column2,...)
valueS ( value1,value2, ...)
说明:
1.若没有指定column 系统则会按表格内的栏位顺序填入资料。
2.栏位的资料形态和所填入的资料必须吻合。
3.table_name 也可以是景观 view_name。
Insert INTO table_name (column1,column2,...)
Select columnx,columny,... FROM another_table
说明:也可以经过一个子查询(subquery)把别的表格的资料填入。
2、查询资料:
基本查询
Select column1,columns2,...
FROM table_name
说明:把table_name 的特定栏位资料全部列出来
Select *
FROM table_name
Where column1 = xxx
[AND column2 〉 yyy] [OR column3 〈〉 zzz]
说明:
1.’*’表示全部的栏位都列出来。
2.Where 之後是接条件式,把符合条件的资料列出来。
Select column1,column2
FROM table_name
orDER BY column2 [DESC]
说明:ORDER BY 是指定以某个栏位做排序,[DESC]是指从大到小排列,若没有指明,则是从小到大
排列
组合查询
组合查询是指所查询得资料来源并不只有单一的表格,而是联合一个以上的
表格才能够得到结果的。
Select *
FROM table1,table2
Where table1.colum1=table2.column1
说明:
1.查询两个表格中其中 column1 值相同的资料。
2.当然两个表格相互比较的栏位,其资料形态必须相同。
3.一个复杂的查询其动用到的表格可能会很多个。
整合性的查询:
Select COUNT (*)
FROM table_name
Where column_name = xxx
说明:
查询符合条件的资料共有几笔。
Select SUM(column1)
FROM table_name
说明:
1.计算出总和,所选的栏位必须是可数的数字形态。
2.除此以外还有 AVG() 是计算平均、MAX()、MIN()计算最大最小值的整合性查询。
Select column1,AVG(column2)
FROM table_name
GROUP BY column1
HAVING AVG(column2) 〉 xxx
说明:
1.GROUP BY: 以column1 为一组计算 column2 的平均值必须和 AVG、SUM等整合性查询的关键字
一起使用。
2.HAVING : 必须和 GROUP BY 一起使用作为整合性的限制。
复合性的查询
Select *
FROM table_name1
Where EXISTS (
Select *
FROM table_name2
Where conditions )
说明:
1.Where 的 conditions 可以是另外一个的 query。
2.EXISTS 在此是指存在与否。
Select *
FROM table_name1
Where column1 IN (
Select column1
FROM table_name2
Where conditions )
说明:
1. IN 後面接的是一个集合,表示column1 存在集合里面。
2. Select 出来的资料形态必须符合 column1。
其他查询
Select *
FROM table_name1
Where column1 LIKE ’x%’
说明:LIKE 必须和後面的’x%’ 相呼应表示以 x为开头的字串。
Select *
FROM table_name1
Where column1 IN (’xxx’,’yyy’,..)
说明:IN 後面接的是一个集合,表示column1 存在集合里面。
Select *
FROM table_name1
Where column1 BETWEEN xx AND yy
说明:BETWEEN 表示 column1 的值介於 xx 和 yy 之间。
3、更改资料:
Update table_name
SET column1=’xxx’
Where conditoins
说明:
1.更改某个栏位设定其值为’xxx’。
2.conditions 是所要符合的条件、若没有 Where 则整个 table 的那个栏位都会全部被更改。
4、删除资料:
Delete FROM table_name
Where conditions
说明:删除符合条件的资料。
说明:关于Where条件后面如果包含有日期的比较,不同数据库有不同的表达式。具体如下:
(1)如果是ACCESS数据库,则为:Where mydate〉#
2000-01-01
#
(2)如果是ORACLE数据库,则为:Where mydate〉cast(’
2000-01-01
’ as date)
或:Where mydate〉to_date(’
2000-01-01
’,’yyyy-mm-dd’)
在Delphi中写成:
thedate=’
2000-01-01
’;
query1.SQL.add(’select * from abc where mydate〉cast(’+’’’’+thedate+’’’’+’ as date)’);
如果比较日期时间型,则为:
Where mydatetime〉to_date(’
2000-01-01
10:00:
01’
,’yyyy-mm-dd hh24:mi:ss’)
Recordset对象一些有用的属性"/〉 引用来自 增加一个 :Recordset对象一些有用的属性
rs.CursorType=
rs.CursorLocation=
rs.LockType =
rs.CacheSize=
rs.Pagesize=
rs.Pagecount=
rs.RecordCount=
’’---- CursorType Values ----
Const adOpenForwardOnly = 0 仅向前
Const adOpenKeyset = 1 键集游标
Const adOpenDynamic = 2 动态游标
Const adOpenStatic = 3 静态游标
’’---- LockType Values ----
Const adLockReadOnly = 1 默认值,只读
Const adLockPessimistic = 2 保守式记录锁定
Const adLockOptimistic = 3 开放式记录锁定,只在调用Update方法时锁定记录
Const adLockBatchOptimistic = 4 开放式批更新
’’---- CursorLocation Values ----
Const adUseServer = 2
Const adUseClient = 3
Set rs=Server.CreateObject("ADODB.Rrecordset")
rs.Open.sqlst,conn,1,1 ’读取
rs.Open sqlst,conn,1,2 ’新增,修改,或删除)
三.MySQL与ANSI SQL的比较
MySQL包含了一些可能在其他SQL数据库找不到的扩充。要注意如果你使用他们,你的代码将不与其他SQL服务器兼容。在一些情况下,你可以编写包括MySQL扩展的代码,但是仍然是可移植的,通过使用/*! ... */形式的注释。在这种情况下,MySQL将进行词法分析并且执行在注释内的代码,但是其他SQL服务器将忽略扩展。
例如:
SELECT /*! STRAIGHT_JOIN */ col_name FROM table1,table2 WHERE ...
如果你在'!'后增加一个版本数字,该语法将仅在MySQL版本是等于或比使用的版本数字新时才执行:
CREATE /*!32302 TEMPORARY */ TABLE (a int);
上面的意思是如果你有 3.23.02 或更新,那么MySQL将使用TEMPORARY关键词。
MySQL扩展部分如下:
字段类型MEDIUMINT、SET、ENUM和不同的BLOB和TEXT类型。
字段属性AUTO_INCREMENT、BINARY、UNSIGNED和ZEROFILL。
缺省地,所有的字符串比较是忽略大小写的,由当前的字符集决定了(缺省为ISO-8859-1 Latin1)排序顺序。如果你不喜欢这样,你应该用BINARY属性或使用BINARY强制符声明列,它导致根据MySQL服务器主机的ASCII顺序进行排序。
MySQL将每个数据库映射一个MySQL数据目录下面的目录,将数据库表映射到数据库目录下的数据库文件名。这有2个含义:
在区分大小写文件名的操作系统(象大多数 Unix 系统一样)上的MySQL中数据库名字和表名是区分大小写的。如果有困难记住表名,接受一个一致的约定,例如总是用小写名字创建数据库和表。
数据库、表、索引、列或别名可以以数字开始(但是不能仅由数字组成)。
你可以使用标准的系统命令备份、重命名、移动、删除和拷贝表。例如,重命名一个表,重命名“.MYD”、“.MYI”和“.frm”文件为相应的表。
在SQL语句中,你可以用db_name.tbl_name语法访问不同数据库中的表。一些SQL服务器提供同样的功能但是称它们为User space(用户空间)。MySQL不支持类似在create table ralph.my_table...IN my_tablespace中的表空间。
LIKE允许出现在数字列上。
在一SELECT语句里面使用INTO OUTFILE和STRAIGHT_JOIN。
在一个SELECT语句中SQL_SMALL_RESULT选项。
EXPLAIN SELECT得到如何联结表的描述。
在一个CREATE TABLE语句里面使用索引、在字段前缀上的索引和使用INDEX或KEY。
CREATE TABLE使用TEMPORARY或IF NOT EXISTS。
使用COUNT(DISTINCT list),这里“list”超过一个元素。
在一个ALTER TABLE语句里面使用CHANGE col_name、DROP col_name或DROP INDEX。
在一个ALTER TABLE里面语句使用IGNORE。
在一个ALTER TABLE语句中使用多重ADD、ALTER、DROP或CHANGE子句。
使用带关键词IF EXISTS的DROP TABLE。
你能用单个DROP TABLE语句抛弃多个表。
DELETE语句的LIMIT子句。
INSERT和REPLACE语句的DELAYED子句。
INSERT, REPLACE, DELETE和UPDATE语句的LOW_PRIORITY子句。
使用LOAD DATA INFILE。在多数情况下,这句法与Oracle的LOAD DATA INFILE兼容。
OPTIMIZE TABLE语句。
SHOW语句。
字符串可以被“"”或“'”包围,而不只是“'”。
使用“/”转义字符。
SET OPTION语句。
你不需要命名所有在GROUP BY部分的被选择的列。这为一些很特定的情况给出更好的性能,而不是一般的查询。
为了方便来自于SQL环境其他为用户,MySQL对许多函数支持别名。例如,所有的字符串功能都支持ANSI SQL句法和 ODBC句法。
MySQL理解||和&&意味着逻辑的OR和AND,就像在C程序语言中。在MySQL中,||和OR是同义词,&&和AND是同义词。正因为这个好的句法,MySQL对字符串并置不支持ANSI SQL ||操作符;相反使用CONCAT(),因为CONCAT()接受任何数量的参数,很容易把||操作符使用变换到MySQL。
CREATE DATABASE或DROP DATABASE。
%操作符是MOD()一个同义词,即,N % M等价于MOD(N,M)。%支持C程序员并与PostgreSQL兼容。
=, <>, <=,<, >=,>, <<, >>, <=>, AND, OR或LIKE操作符可以放在SELECT语句的FROM左边用于比较列。例如:
mysql> SELECT col1=1 AND col2=2 FROM tbl_name;
LAST_INSERT_ID()函数。
扩展的正则表达式操作符REGEXP和NOT REGEXP。
CONCAT()或CHAR()有一个参数或超过2个参数。(在MySQL中,这些函数可取任何数量的参数。)
BIT_COUNT(), CASE, ELT(), FROM_DAYS(), FORMAT(), IF(), PASSWORD(), ENCRYPT(), md5(), ENCODE(), DECODE(), PERIOD_ADD(), PERIOD_DIFF(), TO_DAYS(),或WEEKDAY()函数。
使用TRIM()整修子串。ANSI SQL 只支持单个字符的删除。
GROUP BY函数STD(), BIT_OR()和BIT_AND()。
使用REPLACE而不是DELETE+INSERT。
FLUSH flush_option语句。
在语句中用:=设置变量:
SELECT @a:=SUM(total),@b=COUNT(*),@a/@b AS avg FROM test_table;
SELECT @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
以ANSI模式运行MySQL
如果你用--ansi选项启动mysqld,MySQL的下列行为改变。
||是字符串并置而不是OR。
可在一个函数名字之间与“(”有任何数量的空格。这也使所有的功能名字成为保留词。
"将是一个标识符引号字符(象MySQL `引号字符一样)而不是一个字符串引号字符。
REAL将是FLOAT一个同义词,不是DOUBLE一个同义词。
四、T-SQL对比ANSI-SQL的新特性和增强功能
Microsoft® SQL Server™ 2000 中的 Transact-SQL 提供新特性以及增强的语句、存储过程、函数、数据类型、DBCC 语句和信息架构视图。
数据类型
新数据类型 | |
bigint | table |
sql_variant |
|
数据库控制台命令 (DBCC)
新命令 | |
DBCC CHECKCONSTRAINTS | DBCC DROPCLEANBUFFERS |
DBCC CLEANTABLE | DBCC FREEPROCCACHE |
DBCC CONCURRENCYVIOLATION | DBCC INDEXDEFRAG |
增强的命令 | |
DBCC CHECKALLOC | DBCC CHECKFILEGROUP |
DBCC CHECKDB | DBCC SHOWCONTIG |
DBCC CHECKTABLE |
|
函数
新函数 | |
BINARY_CHECKSUM | fn_virtualfilestats |
CHECKSUM | GETUTCDATE |
CHECKSUM_AGG | HAS_DBACCESS |
COLLATIONPROPERTY | IDENT_CURRENT |
COUNT_BIG | INDEXKEY_PROPERTY |
DATABASEPROPERTYEX | OBJECTPROPERTY |
fn_helpcollations | OPENDATASOURCE |
fn_listextendedproperty | OPENXML |
fn_servershareddrives | ROWCOUNT_BIG |
fn_trace_geteventinfo | SCOPE_IDENTITY |
fn_trace_getfilterinfo | SERVERPROPERTY |
fn_trace_getinfo | SESSIONPROPERTY |
fn_trace_gettable | SQL_VARIANT_PROPERTY |
信息架构视图
新信息架构视图 | |
PARAMETERS | ROUTINE_COLUMNS |
ROUTINES |
|
复制存储过程
新复制存储过程 | |
sp_addmergealternatepublisher | sp_getqueuedrows |
sp_addscriptexec | sp_getsubscriptiondtspackagename |
sp_adjustpublisheridentityrange | sp_helparticledts |
sp_attachsubscription | sp_helpmergealternatepublisher |
sp_browsesnapshotfolder | sp_helpreplicationoption |
sp_browsemergesnapshotfolder | sp_ivindexhasnullcols |
sp_changesubscriptiondtsinfo | sp_marksubscriptionvalidation |
sp_copysnapshot | sp_mergearticlecolumn |
sp_disableagentoffload | sp_repladdcolumn |
sp_dropanonymouseagent | sp_repldropcolumn |
sp_dropmergealternatepublisher | sp_restoredbreplication |
sp_enableagentoffload | sp_resyncmergesubscription |
sp_getagentoffloadinfo | sp_vupgrade_replication |
保留关键字
COLLATE、FUNCTION 和 OPENXML 是 SQL Server 2000 中的保留关键字。
以下这些词已不再是保留关键字。
AVG | COMMITTED |
CONFIRM | CONTROLROW |
COUNT | ERROREXIT |
FLOPPY | ISOLATION |
LEVEL | MAX |
MIN | MIRROREXIT |
ONCE | ONLY |
PERM | PERMANENT |
PIPE | PREPARE |
PRIVILEGES | REPEATABLE |
SERIALIZABLE | SUM |
TAPE | TEMP |
TEMPORARY | UNCOMMITTED |
WORK |
|
语句
新语句 | |
ALTER FUNCTION | DROP FUNCTION |
CREATE FUNCTION |
|
增强的语句 | |
ALTER DATABASE | CREATE TABLE |
ALTER TABLE | CREATE TRIGGER |
BACKUP | INDEXPROPERTY |
COLUMNPROPERTY | OBJECTPROPERTY |
CREATE INDEX | RESTORE |
CREATE STATISTICS |
|
系统存储过程
新系统存储过程 | |
sp_addextendedproperty | sp_delete_maintenance_plan_job |
sp_add_log_shipping_database | sp_dropextendedproc |
sp_add_log_shipping_plan | sp_get_log_shipping_monitor_info |
sp_add_log_shipping_plan_database | sp_helpconstraint |
sp_add_log_shipping_primary | sp_helpindex |
sp_add_log_shipping_secondary | sp_help_maintenance_plan |
sp_add_maintenance_plan | sp_invalidate_textptr |
sp_add_maintenance_plan_db | sp_remove_log_shipping_monitor |
sp_add_maintenance_plan_job | sp_resolve_logins |
sp_can_tlog_be_applied | sp_settriggerorder |
sp_change_monitor_role | sp_trace_create |
sp_change_primary_role | sp_trace_generateevent |
sp_change_secondary_role | sp_trace_setevent |
sp_create_log_shipping_monitor_account | sp_trace_setfilter |
sp_define_log_shipping_monitor | sp_trace_setstatus |
sp_delete_log_shipping_database | sp_updateextendedproperty |
sp_delete_log_shipping_plan | sp_update_log_shipping_monitor_info |
sp_delete_log_shipping_plan_database | sp_update_log_shipping_plan |
sp_delete_log_shipping_primary | sp_update_log_shipping_plan_database |
sp_delete_log_shipping_secondary | sp_xml_preparedocument |
sp_delete_maintenance_plan | sp_xml_removedocument |
sp_delete_maintenance_plan_db |
|
增强的系统存储过程 | |
sp_helptrigger | sp_serveroption |
sp_tableoption | sp_who |
系统表
新系统表 | |
logmarkhistory | MSsync_states |
log_shipping_databases | sysdbmaintplan_databases |
log_shipping_monitor | sysdbmaintplan_history |
log_shipping_plan_databases | sysdbmaintplan_jobs |
log_shipping_plan_history | sysdbmaintplans |
log_shipping_plans | sysmergeschemaarticles |
log_shipping_secondaries | sysopentapes |
Mssub_identity_range |
|
五、总结
下面以赛迪网上的一篇文章作为总结:
开发者们应该知道,使用那些非标准的SQL命令(比如Oracle、微软和MySQL等数据库系统)存在程度相当高的危险。也就是说,从跨平台和遵守标准的角度出发,你应该尽量采用ANSI SQL,它是一种和平台无关的数据库语言。不管你在使用哪种数据库系统,如果它完全支持SQL那么它就应该支持ANSI SQL-92标准。可是,“应该支持”和“确实支持”完全是两码事。在进行DBMS跨平台编程的时候,并不是所有的系统都完全支持ANSI SQL标准,其根源就是各种数据库。下面提出使用非标准SQL时所存在的风险及其相关的建议。
别使用存储过程
在某些编程环境下,出于效率和安全等方面的原因,存储过程成为程序员开发数据库应用程序的唯一方法。Visual Basic、C和Java程序员都并不需要了解SQL。然而,在其他某些编程环境下,存储过程又是完全禁用的。MySQL通常和Apache Web服务器组合使用,这是因为这两种软件不仅免费、可靠而且功能强大,但是,恰恰是MySQL不支持存储过程。
存储过程的定义
所谓存储过程就是组成一个逻辑单元而且执行特别任务的一组SQL语句。存储过程用来封装针对数据库服务器的一整套操作或查询。
Oracle和SQL服务器两者都包括了“内建”的存储过程,其使用也是很方便的。可是,如果明智的话千万别指望它们,你无法保证数据库管理员是否锁定、删除或修改了这些存储过程。如果你发现可用的某些存储过程正是你需要的,你这才可以在自己的代码中使用它们的功能。
通常,你能在Oracle或SQL Server上使用存储过程但在MySQL上则无法利用。如果你确实用到了它们,那么你得保证自己没有用到同特定平台相关的命令(以后讨论)。
别使用连接
连接是Oracle和SQL Server 这两种DBMS上令人头痛的一个问题,因为这两种系统在连接的概念上有根本的不同。基本上,各个DBMS的连接工作原理不总是一样的,而且你最终可能会得到意外的结果集合。在我们谈论各个系统有关连接的概念差别以及如何解决这些问题之前,你应该理解基本的连接子句:
连接
Join(连接)是从多个数据源获取数据的SQL数据表创建命令。
等连接
Equi-Join从两个独立的数据源获取数据并把它们组合成一个大表。
内/外连接
内连接(Inner Join)把两个表的内部列连接起来。外连接把两个表的外部列连接起来。
左/右连接
左连接(Left Join)连接两个表左边的列。右连接则连接两个表右边的列。
复合/复杂连接
其他各种连接—左/内、左/外、右/内和右/外等。
反正你得记清楚了,如果你想要自己的应用程序能在各种数据库服务器上都能工作那么就别使用连接。
ANSI SQL:CREATE, DROP, ADD, UPDATE, DELETE, INSERT, SELECT
总之,你应当用到的唯一命令如下:
数据定义语言(DDL)下的CREATE 和DROP。
数据操作语言(DML)下的ADD、UPDATE、DELETE和INSERT 。
获取数据的SELECT。
如果你在这些命令中使用了区分大小写的表格或字段名,或者这些名字包含了空格或其它特殊字符,那么你最好用方括号把名字围起来。这样做有助于防止非标准字符引发DBMS的不正常反应。
引用的完整性:键和数据类型
使用关系数据库的决定性原因就是明确数据之间的关系而且维持那些关系的完整性。这样才能让开发者以最小的冗余性、最高效的方式存储数据。键定义了关系。数据类型定义了存储和操作数据的规则。这些就是一个数据库的基本方面,但是具体的语法却可能因为数据库的不同而不同。
数据类型
只有很少部分的数据类型得到所有数据库服务器的支持。每一种DBMS都有它自己的数据类型以及为什么要这样使用它们的原因。某些专有数据类型(比如Microsoft Access的AUTONUMBER)用起来确实相当方便。
以下是ANSI数据类型:
BIT, CHARACTER, DATE, DECIMAL, DOUBLE PRECISION, FLOAT, INTEGER, INTERVAL, NUMERIC, REAL, SMALLINT, TIMESTAMP, TIME, VARBIT, VARCHAR, CHAR |
以下是Oracle/Access/SQL不支持的“标准”数据类型:
INTERVAL, TIME, VARBIT
只有Oracle才支持DATE,但是以下的“标准”数据类型不被Oracle支持:
BIT, DECIMAL, NUMERIC, TIMESTAMP
以下的“标准”数据类型不被Access支持:
BIT, CHARACTER, DATE, NUMERIC, SMALLINT, TIMESTAMP
这样,只有以下的数据类型可以保证在各类数据库上都能使用:
DOUBLE PRECISION, FLOAT, INTEGER, NUMERIC, REAL, SMALLINT, VARCHAR, CHAR
主/外键
假设某个表内有两个字段,创建这个表的语法如下:
CREATE TABLE [MyTable] ([FieldA] VARCHAR, [FieldB] VARCHAR);
为了添加主键以便表内的每一条记录都唯一标识你可以采用PRIMARY KEY 表达式:
CREATE TABLE [MyTableA] ([RecordID] VARCHAR PRIMARY KEY, [FieldA] VARCHAR, [FieldB] VARCHAR); |
在创建另一个表,其中一个字段索引第1个表,你可以把该字段定义为同第1个表的字段具有关系的外键:
CREATE TABLE [MyTableB] ([RecordID] VARCHAR PRIMARY KEY, [FieldA] VARCHAR, [FieldB] VARCHAR, [FieldC] VARCHAR REFERENCES [MyTableA]([FieldA])) |
在以上例子中,所有的字段都是VARCHAR类型;但是你得记住,某一数据类型字段只能索引同一数据类型的字段。
ODBC 和 JDBC
如果你在编写的应用程序要用到SQL数据库连接,那么你可以用ODBC完成该功能。如果它是一个Java应用程序则可以用JDBC(简而言之就是ODBC的Java接口)。
因为你希望自己的应用程序最好不要引起管理员的注意,所以你应该为你用户的DBMS包括所有必要的ODBC驱动程序。这样,如果用户从一个平台转移到另一个平台,它们所需要的驱动程序却已经事先拥有了。
你的应用程序应该通过编程的方式决定当前用到的ODBC驱动程序对应何种DBMS。这样你才能用上那些数据库服务器上强大的、同特定平台相关的命令。
另类浏览器之战
最流行的浏览器当然是微软的Internet Explorer和Netscape的Navigator了。但是,不管你手头用的是哪一种,它能保证支持现有的所有网站吗?错!很多花哨的东西,比如DHTML、框架以及多媒体等等都各自受到两类浏览器中非标准的HTML标签的支持。
因为程序在这两种国际标准的岔路口无所适从,所以你必须为两种浏览器编写代码或者编写最具普遍性的功能代码而放弃大量的动态内容。
数据库服务器也面临同样的问题。ANSI SQL-92是人人赞同的标准。然而,Oracle、微软以及其他数据库厂商还自作主张加入了很多破坏SQL代码的特性。因此,你不仅得编写遵从基本规范(SQL-92)的代码,而且的代码还得根据具体用到的产品实现不同的特性。
在你自己的应用程序内,你必须正确地决定应用程序将使用什么类型的数据库,而且数据库应该定位在哪里。你还得老练地处理应用程序或用户产生的任何错误。你当然不希望仅仅因为文件被删除或者网线连接松弛就导致程序崩溃(或服务器崩溃)。在经过精心设计的网络上,数据库服务器通常同工作站和Web服务器、应用服务器在物理上相分离,因此断开连接是很常见的。