访问QueryDefs错误保存的子查询SQL

访问QueryDefs错误保存的子查询SQL

Access以一种奇怪的方式存储它的SQL用于子查询:s似乎用方括号“ []”代替括号“()”,并且(通常)添加了多余的“”。 之后。

例如,一个简单的例子说明了它如何

作品
SELECT subA.*
FROM ( SELECT [fA], [fB]
      FROM [MyTable] ) AS subA
成为(在Access中另存为querydef后):
SELECT subA.*
FROM [ SELECT [fA], [fB]
      FROM [MyTable] ]. AS subA
我不知道为什么Access会这样做,但这似乎是一致的。 在某些版本中,Access可以识别生成的SQL,但在较早版本中,它无法识别自己的SQL。

从访问QueryDef访问SQL基本上有两种方法。

  1. 设计QueryDef时,选择“视图” /“ SQL视图”。 这显示(并允许编辑)QueryDef后面的SQL。
  2. 以编程方式,QueryDef对象具有一个名为.SQL的可更新字符串属性。 这将访问相同的数据。
如果要直接更新SQL,则通常使用前一种方法将这些括号更新为括号。

在代码中,这更是一个问题。 考虑到这一点,我开发了一个简短的例程来安全地读取QueryDef的SQL。

'GetSQL gets the SQL component from a named query OR a SQL string.
'When subqueries are specified in MS Access they are changed internally
'from   "FROM (SELECT blah blah blah) AS" to
'either "FROM [SELECT blah blah blah]. AS"
'or     "FROM [SELECT blah blah blah] AS" both of which are invalid SQL.
'This code assumes any effected subquery will start with " [SELECT ".
'This reverts SQL to correct format and loses ';' at end if requested.
' 11/11/2004    Updated to detect second problem and to use InStr
Public Function GetSQL(strQuery As String, _
                       Optional blnLoseSC As Boolean = True) As String
    Dim intDepth As Integer
    Dim lngLeft As Long, lngOpen As Long, lngRight As Long, lngAdjust As Long 
    'If param passed is already SQL then leave as is - Otherwise get from query
    If Left(strQuery, 1) = "(" Then
        GetSQL = strQuery
    Else
        On Error Resume Next
        GetSQL = CurrentDb.QueryDefs(strQuery).SQL
    End If
    lngLeft = -7
    Do
        'Check for corrupted subquery
        lngLeft = InStr(lngLeft + 8, GetSQL, " [SELECT ", vbTextCompare)
        If lngLeft = 0 Then Exit Do
        'To find end correctly we must treat '[' & ']' as matched pairs
        intDepth = 1
        lngRight = lngLeft + 8
        lngOpen = -lngRight
        Do
            'Find next ']'
            lngRight = InStr(lngRight + 1, GetSQL, "]", vbBinaryCompare)
            If lngRight = 0 Then
                GetSQL = ""
                Exit Function
            End If
            intDepth = intDepth - 1
            Do
                'For lngOpen negative numbers mean that item has been counted
                'If already counted get next one - Otherwise drop through
                If lngOpen < 0 Then _
                    lngOpen = InStr(-lngOpen + 1, GetSQL, "[", vbBinaryCompare)
                'we're only interested (now) if it found one BEFORE the ']'
                If lngOpen > lngRight Or lngOpen = 0 Then Exit Do
                intDepth = intDepth + 1
                lngOpen = -lngOpen
            Loop
        Loop While intDepth > 0
        'If '].' found then be sure to drop the '.' too
        lngAdjust = IIf(Mid(GetSQL, lngRight + 1, 1) = ".", 1, 0)
        GetSQL = Left(GetSQL, lngLeft) & "(" & _
                 Mid(GetSQL, lngLeft + 2, lngRight - lngLeft - 2) & ")" & _
                 Right(GetSQL, Len(GetSQL) - (lngRight + lngAdjust))
    Loop
    'Lose ";" at end if requested and it exists
    If blnLoseSC And Right(GetSQL, 3) = ";" & vbCrLf Then _
        GetSQL = Left(GetSQL, Len(GetSQL) - 3)
End Function
好。 也许不太短。

From: https://bytes.com/topic/access/insights/794178-access-querydefs-mis-save-subquery-sql

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值