现在 Access 用的人应该不多了,本来我以为我也不可能用这玩意儿,但最近在用 VBA 通过 SQL 处理数据时,发现它的语法是 Access 的语法。平时对 SQL Server 语法相对熟悉一些。下文总结了 Access 和 SQL Server 语法的差异。

1、 数据类型

1.1、 Yes/No vs. BIT

对比布尔类型的列, Access 中可以使用 True/False 来比较或赋值,但 SQL 中,最好直接使用整数。

-- DETERMINING TRUE  
-- Access:  
[...] WHERE ynColumn = TRUE  
[...] WHERE ynColumn = -1  
-- SQL Server:  
[...] WHERE ynColumn <> 0  
------------------------------  
-- DETERMINING FALSE  
-- Access:  
[...] WHERE ynColumn = FALSE  
[...] WHERE ynColumn = 0  
-- SQL Server:  
[...] WHERE ynColumn = 0

1.2、Currency vs. Money

Currency 类型的好处是可以使用 Format 函数去添加货币符号和合适的小数点、千分位位置。但在 SQL Server 内部做不到这一点,需要先将结果取出然后使用外部函数去实现。

1.3、Date/Time vs. Datetime

Access 里的日期两边用「#」号包括起来,在 SQL Server 则用单引号「'」:

-- Access: 
[...] WHERE dtColumn >= #2001-11-05# 
-- SQL Server: 
[...] WHERE dtColumn >= '2013-10-01'

另外,获取当时日期时间的函数也不一样。Access 里获取时间用 Now(),获取日期用 Date(), SQL 中则使用 GetDate()或者 Current_TIMESTAMP。

1.4、Access 和 SQL 类型对比

2、字符串处理

2.1、字符串语法

Access 中的字符串两边可以使用双引号和单引号, SQL 则只能使用单引号; Access 里使用「&」连接字符串,而 SQL 中使用「+」; Access 使用 Chr()将 ASCII 码转为字符,而 SQL 中类似函数为 Char()。

-- Access: 
SELECT CHR(13) & CHR(10) 
-- SQL Server: 
SELECT CHAR(13) + CHAR(10)

2.2、字符串处理函数

Access 的字符串函数不光可以在查询数据库的语句内部使用,也可以在 VBA 中直接使用。

Access SQL Server TEXT Equivalent

2.3、字符串排序

Access 和 SQL Server 的排序顺序并不严格一致。主要区别是 Access 对特殊字符如下划线和引号的处理和普通 ASCII 顺序不一样。

Access 和 Windows 程序一致,将下划线视为最大的非字母字符,同时它在排序中会忽略引号(')以及中划线(-)。

2.4、比较 NULL

SQL 中用 is 去判断是否 NULL ,而 Access可以直接使用等于或不等于的符号:

-- Access: 
[...] WHERE column <> NULL 
-- SQL Server: 
[...] WHERE column IS NULL 
[...] WHERE column IS NOT NULL

为了保持一致性,最好在 SQL Server 和 Access 里都是用 is null 语法。

3、其它语法改变

3.1、Case vs. IIF

SQL Server 使用 Case 语法控制多分支输出,在 Access 中只有功能相对较弱的 IIF 函数:

-- Access: 
SELECT alias = IIF(Column<>0, "Yes", "No") 
    FROM table 
-- SQL Server: 
SELECT alias = CASE WHEN Column<>0 THEN 'Yes' Else 'No' END 
    FROM table

3.2、Case vs. Switch

Access 中还有 switch 函数功能和 SQL Server 中的 Case 关键词类似:

-- Access: 
SELECT Switch( 
    On=1,'On', 
    On=0,'Off' 
) FROM table 
-- SQL Server 
SELECT CASE  
    WHEN On=1 THEN 'On' 
    WHEN On=0 THEN 'Off' 
END FROM table

3.3、DistinctRow

Access 支持 SQL Server 中没有的关键词 DistinctRow。

DISTINCTROW 关键字和 DISTINCT 关键字类似,但前者是基于整行而非个别的域的。他只有在处理多个表时,并且只有在用户从某几个但非全部的表中选择数据域时才是有用的。如果用户的查询是基于一个表的,或者要从所有的表中选择数据域,则 DISTINCTROW 关键字本质上和 ALL 关键字相同。

3.4、列别名的关键字 As

Access 里列别名必须使用 As 进行标记, SQL Server 则可要可不要。例如:

-- Access 
select column1 as col1 from table1 t1
-- SQL Server 
select column1 col1 from table1 t1

表的别名则都是可用可不用。

3.5、Access 的 NOT IN 速度慢

在通过 VBA 的 JET 引擎调用 Access 语法时, NOT IN 速度非常慢,上千行的数据可能就需要好几分钟。替代方法是:

Select t1.id from t1 
left join t2 on t1.id = t2.id 
where t2.id is null
        

Q. E. D.