MS Access(Jet / ACE)中的无表UNION查询

这按预期工作:

SELECT "Mike" AS FName

这将失败,并显示错误“查询输入必须至少包含一个表或查询”:

SELECT "Mike" AS FNameUNION ALLSELECT "John" AS FName

这仅仅是Jet / ACE数据库引擎的怪癖/局限性,还是我缺少某些东西?


慕仙森
浏览 739回答 3
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无法创建检查约束。

呼如林

如果您有权访问某些系统表,则可以通过以下方式模拟双重表:(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例如,这就是在jOOQ中实现为语法元素的内容。

慕虎7371278

当您限制了对数据库的只读访问(即,您无法创建新表或访问系统资源)时,这可能会起作用:SELECT "Mike" AS FNameFROM (SELECT COUNT(*) FROM anyTable WHERE 1=0) AS dualanyTable是您找到的第一个用户表(我很难想象没有用户表的真实数据库!)。即使在一张大桌子上,WHERE 1 = 0也应该快速返回0计数(希望Jet引擎足够智能以识别这种琐碎的情况)。
打开App,查看更多内容
随时随地看视频慕课网APP