【问题标题】:Pass-through query losing changes made to SQL传递查询丢失对 SQL 所做的更改
【发布时间】:2014-05-21 13:26:22
【问题描述】:

我有一个直通查询MyPassThru。这是查询 SQL 的简化版本:

SET NOCOUNT ON

DECLARE @FromDate datetime = '1/25/2014'
DECLARE @ThruDate datetime = '3/1/2014'

SELECT *
  FROM MtgDailyTrans M
  WHERE M.TransDate >= @FromDate
    AND M.TransDate <= @ThruDate

我需要更改@FromDate 和@ThruDate 参数。为此,我编写了以下函数 (source for RegExReplace):

Private gDb As DAO.Database

Function Db() As DAO.Database
    If gDb Is Nothing Then Set gDb = CurrentDb
    Set Db = gDb
End Function

Sub MyPassThruSetDates(FromDate As Date, ThruDate As Date)
    Const FromPattern As String = "(@FromDate datetime = ')([\d/]+)'"
    Const ThruPattern As String = "(@ThruDate datetime = ')([\d/]+)'"
    Dim qd As DAO.QueryDef
    Set qd = Db.QueryDefs("MyPassThru")
    qd.SQL = RegExReplace(FromPattern, qd.SQL, "$1" & Format(FromDate, "m/d/yyyy") & "'")
    qd.SQL = RegExReplace(ThruPattern, qd.SQL, "$1" & Format(ThruDate, "m/d/yyyy") & "'")
    Set qd = Nothing
End Sub

问题是当我对MyPassThru 的SQL 进行更改然后运行MyPassThruSetDates() 过程时,我对SQL 所做的更改会回滚。为什么?

【问题讨论】:

    标签: ms-access vba dao


    【解决方案1】:

    发生这种情况的原因是持久性Db 对象正在缓存 QueryDef 及其属性的副本(以包括 .SQL 属性)。如果您调用MyPassThruSetDates,然后更改MyPassThru 的SQL,然后再次调用MyPassThruSetDates,原始SQL 将覆盖自原始调用MyPassThruDates 以来所做的任何更改。

    解决方案是刷新 QueryDefs 集合以确保它使用的是最新值:

    Sub MyPassThruSetDates(FromDate As Date, ThruDate As Date)
        Const FromPattern As String = "(@FromDate datetime = ')([\d/]+)'"
        Const ThruPattern As String = "(@ThruDate datetime = ')([\d/]+)'"
        Dim qd As DAO.QueryDef
        Db.QueryDefs.Refresh   ' <--- This is the key!!!
        Set qd = Db.QueryDefs("MyPassThru")
        qd.SQL = RegExReplace(FromPattern, qd.SQL, "$1" & Format(FromDate, "m/d/yyyy") & "'")
        qd.SQL = RegExReplace(ThruPattern, qd.SQL, "$1" & Format(ThruDate, "m/d/yyyy") & "'")
        Set qd = Nothing
    End Sub
    

    要进一步解释为什么会发生这种情况,请参阅以下注释较多的测试例程:

    Sub TestDbCache()
        Const QName As String = "TempQry"
    
        Dim qd As DAO.QueryDef, db As DAO.Database
    
        'First, we create a querydef
        Set db = CurrentDb
        Set qd = db.CreateQueryDef(QName, "SELECT 'original'")
        Debug.Print qd.SQL                           '--> SELECT 'original';
    
        'Next, we update the querydef's .SQL outside the scope of our db object
        CurrentDb.QueryDefs(QName).SQL = "SELECT 'changed'"
    
        'The querydef and db objects are unaware of the change to .SQL
        Debug.Print qd.SQL                           '--> SELECT 'original';
        Debug.Print db.QueryDefs(QName).SQL          '--> SELECT 'original';
        Debug.Print CurrentDb.QueryDefs(QName).SQL   '--> SELECT 'changed';
    
        'Refreshing the collection updates both the db and qd objects
        db.QueryDefs.Refresh
        Debug.Print qd.SQL                           '--> SELECT 'changed';
        Debug.Print db.QueryDefs(QName).SQL          '--> SELECT 'changed';
    
        'Note that the .SQL is "SELECT 'changed'" when we set the NewDb object
        Dim NewDb As DAO.Database
        Set NewDb = CurrentDb
    
        'We change the .SQL without refreshing the NewDb's QueryDefs collection
        CurrentDb.QueryDefs(QName).SQL = "SELECT 'changed again'"
    
        'Since the NewDb object never cached the contents of the query,
        '   it returns the correct current value of .SQL
        Debug.Print NewDb.QueryDefs(QName).SQL       '--> SELECT 'changed again';
    
        'The other db object has not refreshed its QueryDefs collection,
        '   so it is wrong once again
        Debug.Print qd.SQL                           '--> SELECT 'changed';
        Debug.Print db.QueryDefs(QName).SQL          '--> SELECT 'changed';
    End Sub
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-01
      • 2019-12-11
      • 1970-01-01
      • 2011-01-07
      • 2011-06-17
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      相关资源
      最近更新 更多