【问题标题】:MS Access to SQL query issueMS Access 到 SQL 查询问题
【发布时间】:2011-10-25 15:53:12
【问题描述】:

我有这个查询应该在 MS Access 中使用,但数据库是 SQL 数据库。当我在 SQL 环境中运行此查询时,它运行良好。但是,当在 MS Access 中运行时,我得到了错误。我一开始对 SQL 知之甚少(来自 MySQL),对 MS Access 更是知之甚少。

该查询应该向我提供某种投标人类型中对某件商品进行投标的总人数(无论他们是否中标)、该投标人类型中中标的物品的总价格以及投标人类型,全部用于一次拍卖。这是下面的查询。

SELECT     Total.count, SUM(dbo_tblItem.item_premium + dbo_tblItem.item_pr) AS SumTotal, dbo_tblBidder.bidder_type
FROM         dbo_tblBidder LEFT OUTER JOIN
                  dbo_tblItem ON dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number   AND 
                  dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id LEFT OUTER JOIN
                      (SELECT     COUNT(bidder_type) AS count, bidder_type
                        FROM          dbo_tblBidder AS tblBidder_1
                        WHERE      (bidder_sale_id = 235)
                        GROUP BY bidder_type) AS Total ON dbo_tblBidder.bidder_type = Total.bidder_type
WHERE     (dbo_tblBidder.bidder_sale_id = 235)
GROUP BY dbo_tblBidder.bidder_type, Total.count
ORDER BY dbo_tblBidder.bidder_type

MS Access 告诉我:

查询表达式“中的语法错误(缺少运算符)。

然后,它突出显示 dbo_tblBidder.bidder_number 中的“mber”,其中显示:

dbo_tblItem ON dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number

我不知道突出显示是否真的是任何东西的一部分。

【问题讨论】:

    标签: sql sql-server ms-access


    【解决方案1】:

    当您加入 2 个以上的表时,Access 需要括号并且对它们的位置非常挑剔。 (虽然您的查询的数据源之一是子查询而不是实际表,但它在连接和括号方面被视为与表相同。)建议您在 Access 的查询设计器中将其构建为新查询,以查看它如何放置括号为您连接的表。

    “count”是一个保留字,所以我在查询中出现的所有地方都用括号括起来,以减少混淆数据库引擎的机会。

    Access 数据库引擎使用 LEFT JOIN 而不是 LEFT OUTER JOIN。

    我认为这可能接近您的需要。

    SELECT
        Total.[count],
        SUM(dbo_tblItem.item_premium + dbo_tblItem.item_pr) AS SumTotal,
        dbo_tblBidder.bidder_type
    FROM         
        (dbo_tblBidder LEFT JOIN dbo_tblItem
            ON (dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number
               AND dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id)
            )
        LEFT JOIN (
            SELECT     COUNT(bidder_type) AS [count], bidder_type
            FROM          dbo_tblBidder
            WHERE      bidder_sale_id = 235
            GROUP BY bidder_type
            ) AS Total
            ON dbo_tblBidder.bidder_type = Total.bidder_type
    WHERE     dbo_tblBidder.bidder_sale_id = 235
    GROUP BY dbo_tblBidder.bidder_type, Total.[count]
    ORDER BY dbo_tblBidder.bidder_type;
    

    【讨论】:

    • 天哪,成功了!你是我的新英雄~非常感谢。
    • “您的查询的数据源之一是子查询,而不是实际的表”——这就是 SQL 标准所说的“派生表”,并进一步规定,“表要么是基础表、查看的表或派生表。”
    • 但是使用 Access 查询设计器的另一面是生成的 SQL 代码通常很冗长,并且 (([full] [of]) (([pointless])(([brackets] 和[parens])))),使人类更难阅读。
    • @onedaywhen 对。如果一个人不能容忍那些多余的括号和括号,一个人会辱骂查询设计者。我平静了。 :-)
    【解决方案2】:

    尝试在 ON 子句周围加上括号,例如,

    left outer join dbo_tblItem on (dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number
        and dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id)
    

    【讨论】:

    • 我试过了,但是它说同样的错误,但是 'dbo_tblItem.item_bidder_number = dbo_tblBidder.bidder_number AND dbo_tblItem.item_sale_id = dbo_tblBidder.bidder_sale_id LEFT OUTER JOIN (SELECT COUNT(bidder_type) AS count, bidder_type' 而不是空引号。
    【解决方案3】:

    您的问题听起来像是在 Access 中链接了 SQL Server 表。
    您是尝试通过代码还是在 Access 查询设计器中执行查询?

    无论您如何准确地执行查询,也可以将其直接发送到 SQL Server,从而绕过 Access。

    这样做的好处是可以使用 SQL Server 的 SQL 方言,IMO 比 Access 的 SQL 方言更强大。
    另外,根据我的经验,SQL Server 比 Access 更快。

    如果您使用的是查询设计器:

    您可以在查询设计器中创建传递查询:
    How to create an SQL pass-through query in Access

    如果要通过代码执行查询:
    这是一个示例函数,它将直接向 SQL Server 发送查询并返回记录集:

    Public Function OpenRecordset(ByVal SQL As String) As DAO.Recordset    
        Dim QD As QueryDef
        Set QD = CurrentDb.CreateQueryDef("")
        With QD
            .Connect = "Your connection string to the SQL Server database"
            .ReturnsRecords = True
            .SQL = SQL
            Set OpenRecordset= QD.OpenRecordset
            QD.Close
        End With
        Set QD = Nothing    
    End Function
    

    使用示例:

    Public Function Test()    
        Dim RS As DAO.Recordset        
        Set RS = OpenRecordset("select getdate()")        
        MsgBox RS.Fields(0)        
        RS.Close
        Set RS = Nothing    
    End Function
    

    这将使用 SQL Server 函数 getdate() 返回当前日期和时间。

    【讨论】:

    • 我想看看 James 的查询如何从 SQL Server 的 SQL 方言的额外功能中受益。我在那个上面画了一个空白。
    • @HansUp:“在那上面画一个空白”是什么意思? (英语不是我的母语)
    • 对不起!画一个空白意味着我无法确定任何好处。另一个类似的美国成语是“空手而归”。 (这可能也无济于事!)在某事上不成功。
    • 好的,我明白了 :-) 当然,SQL Server 与 Access 的性能可能取决于数据库大小、查询复杂性等。我只能讲述我的经验:在工作中,我们在 Access 2003 上运行一个完整的 ERP 系统,并带有一个 SQL Server 2005 后端(>80 GB 数据库大小)。在这种情况下,如果我们直接在 SQL Server 上运行查询(与上面的 OpenRecordset 函数基本相同)而不是查询链接的 SQL Server 表,那么复杂的查询(尤其是连接)会方式更快在 Access 中。
    • 这对我来说也很有趣,克里斯蒂安。我不知道 ODBC 在不将其作为传递查询提交的情况下会将多少处理负载移交给 SQL Server。如果詹姆斯尝试两种方式并告诉我们影响,那就太好了。但我的第一条评论是关于如何使用 SQL Server 的 SQL 方言优化这个查询。那是我看不到的部分......我“画了一个空白”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多