为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕仙森 2019-09-26 14:37:13
这按预期工作:SELECT "Mike" AS FName这将失败,并显示错误“查询输入必须至少包含一个表或查询”:SELECT "Mike" AS FNameUNION ALLSELECT "John" AS FName这仅仅是Jet / ACE数据库引擎的怪癖/局限性,还是我缺少某些东西?
查看完整描述

3 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

你什么都没忽略。Access的数据库引擎将允许SELECT没有FROM数据源的单行。但是,如果你想UNIONUNION 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 1WHERE子句的语句,将结果集限制为单行。

注意检查约束是随Jet 4添加的,仅可用于从ADO执行的语句。CurrentProject.Connection.Execute strSql之所以有效,CurrentProject.Connection是因为它是一个ADO对象。如果尝试使用DAO执行同CurrentDb.Execute一条语句(即从Access查询设计器或从Access查询设计器执行),则会收到语法错误,因为DAO无法创建检查约束。


查看完整回答
反对 回复 2019-09-26
?
呼如林

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

例如,这就是在jOOQ中实现为语法元素的内容


查看完整回答
反对 回复 2019-09-26
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

当您限制了对数据库的只读访问(即,您无法创建新表或访问系统资源)时,这可能会起作用:

SELECT "Mike" AS FNameFROM (SELECT COUNT(*) FROM anyTable WHERE 1=0) AS dual
  1. anyTable是您找到的第一个用户表(我很难想象没有用户表的真实数据库!)。

  2. 即使在一张大桌子上,WHERE 1 = 0也应该快速返回0计数(希望Jet引擎足够智能以识别这种琐碎的情况)。


查看完整回答
反对 回复 2019-09-26
  • 3 回答
  • 0 关注
  • 782 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信