3 回答
TA贡献1818条经验 获得超3个赞
你什么都没忽略。Access的数据库引擎将允许SELECT
没有FROM
数据源的单行。但是,如果你想UNION
或UNION ALL
多个行,你必须包括一个FROM
......即使你不是从数据源中引用的任何字段。
我创建了一个只有一行的表,并添加了一个检查约束以确保它始终只有一行。
Public Sub CreateDualTable() Dim strSql As String strSql = "CREATE TABLE Dual (id COUNTER CONSTRAINT pkey PRIMARY KEY);" Debug.Print strSql CurrentProject.Connection.Execute strSql strSql = "INSERT INTO Dual (id) VALUES (1);" Debug.Print strSql CurrentProject.Connection.Execute strSql strSql = "ALTER TABLE Dual" & vbNewLine & _ vbTab & "ADD CONSTRAINT there_can_be_only_one" & vbNewLine & _ vbTab & "CHECK (" & vbNewLine & _ vbTab & vbTab & "(SELECT Count(*) FROM Dual) = 1" & vbNewLine & _ vbTab & vbTab & ");" Debug.Print strSql CurrentProject.Connection.Execute strSqlEnd Sub
该Dual
表对于以下查询很有用:
SELECT "foo" AS my_textFROM DualUNION ALLSELECT "bar"FROM Dual;
我见过的另一种方法是使用SELECT
带有TOP 1
或WHERE
子句的语句,将结果集限制为单行。
注意检查约束是随Jet 4添加的,仅可用于从ADO执行的语句。CurrentProject.Connection.Execute strSql
之所以有效,CurrentProject.Connection
是因为它是一个ADO对象。如果尝试使用DAO执行同CurrentDb.Execute
一条语句(即从Access查询设计器或从Access查询设计器执行),则会收到语法错误,因为DAO无法创建检查约束。
TA贡献1798条经验 获得超3个赞
如果您有权访问某些系统表,则可以通过以下方式模拟双重表:
(SELECT COUNT(*) FROM MSysResources) AS DUAL
不幸的是,我不知道任何系统表...
总是可用的,可读的(并非每个连接都可以访问MSysObjects)
仅包含一条记录,例如Oracle
DUAL
或DB2的记录SYSIBM.DUAL
所以你会写:
SELECT 'Mike' AS FNameFROM (SELECT COUNT(*) FROM MSysResources) AS DUALUNION ALLSELECT 'John' AS FNameFROM (SELECT COUNT(*) FROM MSysResources) AS DUAL
TA贡献1802条经验 获得超4个赞
当您限制了对数据库的只读访问(即,您无法创建新表或访问系统资源)时,这可能会起作用:
SELECT "Mike" AS FNameFROM (SELECT COUNT(*) FROM anyTable WHERE 1=0) AS dual
anyTable是您找到的第一个用户表(我很难想象没有用户表的真实数据库!)。
即使在一张大桌子上,WHERE 1 = 0也应该快速返回0计数(希望Jet引擎足够智能以识别这种琐碎的情况)。
添加回答
举报