【问题标题】:How to fix 'ODCB call failed during OpenRecordSet'如何修复“OpenRecordSet 期间 ODBC 调用失败”
【发布时间】:2020-01-18 11:23:48
【问题描述】:

我目前正在对现有的 Access(vba) 应用程序进行一些更改。但突然我在运行 QueryDef 时遇到了 ODCB 调用失败错误。这些表链接到 SQL 服务器数据库。

我尝试通过链接表管理器重置表的链接。 还进行了调试以查看查询是否确实已定义以及其中的 SQL 是否正确。

    Call makePassThroughQuery("qryName", qSQL, True)
    Dim SQL As String
    SQL = "select * from qryName"
    Set rsNew = DB.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
    ' continue to use rsNew 

makePassThroughQuery 函数如下所示:

Function makePassThroughQuery(qryName As String, SQLString As String, 
             Optional isSQL As Boolean = True, 
             Optional ConnectString As String = "string", 
             Optional timeout As Integer = 120)

   Dim isTestingEnvironment As Boolean
   isTestingEnvironment = True
   If isSQL = False Then
     With CurrentDb
         On Error Resume Next
         .QueryDefs.Delete (qryName)
         On Error GoTo 0
         Dim qdfNew As Object
         Set qdfNew = .CreateQueryDef(qryName, SQLString)
         .Close
     End With

   Else
     Dim curDB As Database, curQdef As QueryDef
     '    Dim ConnectString As String
     'ConnectString = "string"
     Set curDB = CurrentDb
     On Error Resume Next
     CurrentDb.QueryDefs.Delete (qryName)
     On Error GoTo 0
     Set curQdef = curDB.CreateQueryDef(qryName)
     curQdef.Connect = ConnectString '& ";Returns Records=false;"
     curQdef.ODBCTimeout = timeout
     curQdef.sql = SQLString
     curQdef.Close

   End If
End Function

调用应该可以工作,因为这与我们对数据库进行大多数调用的方式相同,但不知何故,这个查询不起作用。

--编辑 By request 这是放置在 QueryDef 中的 SQL。

SELECT IIf([Brand]='Somebrand','SO',IIf(left([Brand],6)='SomeOtherBrand',IIf(CHARINDEX('168/2013', [WVTA])=0,'FOOBAR','BARFOO'),IIf([Brand]='Anotherbrand','BAR',IIf([Brand]='YetAnotherBrand','Foo','ander')))) AS Company,  
qtmpgetVINApprovalData.VIN, qtmpgetVINApprovalData.WVTA, qtmpgetVINApprovalData.Variant,  qtmpgetVINApprovalData.Version, qtmpgetVINApprovalData.NKS, qtmpgetVINApprovalData.productionDate AS Production, 
qtmpgetVINApprovalData.color, qtmpgetVINApprovalData.actualMass,  qtmpgetVINApprovalData.NKS_YYYY,qtmpgetVINApprovalData.NKS_SSSS, '' AS engine, qtmpgetVINApprovalData.EmisTestMassWLTP, 
qtmpgetVINApprovalData.FrontalAreaWLTP, qtmpgetVINApprovalData.RoadLoadCoefF0WLTP,  qtmpgetVINApprovalData.RoadLoadCoefF1WLTP, qtmpgetVINApprovalData.RoadLoadCoefF2WLTP, 
qtmpgetVINApprovalData.WLTPCOMBINED_REPORTING_CO2 AS CombinedCo2ConditionA,  qtmpgetVINApprovalData.WLTPCOMBINED_REPORTING_CO2 AS CombinedCo2ConditionB, 
qtmpgetVINApprovalData.WLTPCOMBINED_REPORTING_FC AS CombinedFuelConsConditionA,  qtmpgetVINApprovalData.WLTPCOMBINED_REPORTING_FC AS CombinedFuelConsConditionB, 
qtmpgetVINApprovalData.OVCEnergyConsPureElectric AS ElectricEnergyConsConditionA, qtmpgetVINApprovalData.OVCEnergyConsPureElectric AS ElectricEnergyConsConditionB,  
qtmpgetVINApprovalData.ElectricEnergyConsPureElectric , qtmpgetVINApprovalData.ElectricRange, OVCEnergyConsPureElectric, OVCRange, OVCRangeCity,  
qtmpgetVINApprovalData.OVCRange AS ElectricRangeExternChargeable, qtmpgetVINApprovalData.WLTPLowCO2, qtmpgetVINApprovalData.WLTPMediumCO2, qtmpgetVINApprovalData.WLTPHighCO2,  
qtmpgetVINApprovalData.WLTPExtraHighCO2, qtmpgetVINApprovalData.WLTPCombinedCO2, qtmpgetVINApprovalData.WLTPWeightedCombinedCO2, qtmpgetVINApprovalData.WLTPLowFuelConsumption,  
qtmpgetVINApprovalData.WLTPMediumFuelConsumption, qtmpgetVINApprovalData.WLTPHighFuelConsumption, qtmpgetVINApprovalData.WLTPExtraHighFuelConsumption, 
qtmpgetVINApprovalData.WLTPCombinedFuelCons,  qtmpgetVINApprovalData.WLTPWeightedCombinedFuelCons, 0 as WltpElecEnergyConsPureElectric,0 as WltpElectricRangePureElectric,
0 as WltpElectricRangeCityPureElec,0 as WltpElectEnergyConsExternCharg,  0 as WltpElectricRangeExternCharg,0 as WltpElectricRangeCityExtCharg, qtmpgetVINApprovalData.EMISSIONSTAGE, 
colorahosid, UrbanConditionsCO2, UrbanConditionsFuelConsumption, ExtraUrbanConditionsCO2,  ExtraUrbanConditionsFuelCons, CombinedCO2, CombinedConditionsFC, WeightedCombinedCO2, 
WeightedCombinedFuelCons, ElectricEnergyConsWeightedComb, ElectricRangeNEDC, ElectricRangeCity  FROM (SELECT DISTINCT     


CASE WHEN isnull(WLTPLowFuelConsumption,0)>15
THEN 'Error: Fuel consumption value too high'
ELSE
    CASE WHEN isnull(WLTPMediumCO2,0)>800
    THEN 'Error: WLTP Medium CO2 value too high'
    ELSE
        case when isnull(RoadLoadCoefF1WLTP,0)>1000
        THEN 'Error: RoadLoadCoeff too high'
        ELSE        
            case when isnull(qvtvv.tvvid,0)=0 
                THEN 'ERROR: TVV (PCOC) data missing' 
                ELSE                   
                case when isnull(qvtvv.eurolevel,'X')='X' 
                        THEN 'ERROR: EmissionLegislation Missing' 
                        ELSE                   
                        CASE when isnull(cocVINList.prodDate,'1900-01-01')='1900-01-01' 
                                THEN 'ERROR: Production Date Missing' 
                                ELSE                      
                                CASE when isnull(qvTVV.colorAHOSID,999)=999 
                                        THEN 'ERROR: Color missing' 
                                        ELSE
                                            CASE when isnull(nkstvv.wvta,'X')='X' 
                                                then    --NKS                    
                                                    case when isnull(nkstvv.wvta,'X')='X' 
                                                            then --NKS   
                                                            case when isnull(dbo.cocVINList.[actualMass],0)=0 
                                                                    THEN 'ERROR: Actual Mass missing'
                                                                    else 'OK'
                                                            END                       
                                                            else --BASE VEH  
                                                            case when isnull(NKS_PCOC.NKS_MassRunningOrder,0)=0 
                                                                    THEN 'ERROR: Actual Mass missing' 
                                                                    else 'OK'
                                                            END
                                                        end                       
                                                ELSE  
                                                    case when [WVTACOCLayoutVersions].description like '%2018%WLTP%' 
                                                            THEN 
                                                            case when isnull(EmisTestMassWLTP,0)=0 
                                                                    THEN 'ERROR: WLTP data missing' 
                                                                    else 'OK'
                                                            end
                                                            ELSE 'OK' 
                                                    END                    
                                            END                  
                                END                     
                        END              
                END
            END
        END
    END
END
as VALIDATION,   

dbo.cocVINList.VIN,        
dbo.cocVINList.NKS,             
case when isnull(nkstvv.wvta,'X')='X' then dbo.qvTVV.WVTA else nkstvv.wvta end as WVTA,           
case when isnull(nkstvv.Variant,'X')='X' then dbo.qvTVV.Variant else nkstvv.Variant end as Variant,          
case when isnull(nkstvv.Version,'X')='X' then dbo.qvTVV.Version else nkstvv.Version end as Version,             
case when isnull(nkstvv.wvta,'X')='X' then dbo.cocVINList.[actualMass] else NKS_PCOC.NKS_MassRunningOrder end as actualMass,             
case when isnull(nkstvv.wvta,'X')='X' then cocVINList.prodDate else NKS_PCOC.COC_Datum end as productionDate,             
case when isnull(nkstvv.wvta,'X')='X' then dbo.qvTVV.wvtadate else nkstvv.wvtadate end as WVTADate,             
qvTVV.color, qvTVV.colorAHOSID,              
qvTVV.Type_watermark_paper as Brand,     
case when isnull(nkstvv.wvta,'X')<>'X' THEN 
    case when charindex('2007/46',nkstvv.wvta)= 0 then qvtvv.NKS_YYYY END
END as NKS_YYYY,
case when isnull(nkstvv.wvta,'X')<>'X' THEN 
    case when charindex('2007/46',nkstvv.wvta)= 0 then qvTVV.NKS_SSSS END
END as NKS_SSSS,

 [EmisTestMassWLTP],             
 [FrontalAreaWLTP],             
 [RoadLoadCoefF0WLTP],             
 [RoadLoadCoefF1WLTP],             
 [RoadLoadCoefF2WLTP],             
 [CombinedConditionsCO2],             
 [CombinedConditionsFC],             
 [OVCEnergyConsPureElectric],             
 [OVCRange],             
 [OVCRangeCity],           
[ElectricEnergyConsPureElectric],    
         [ElectricRange],
         ElectricRangeCity,    
          [WLTPLowCO2],   

[WLTPMediumCO2],           
  [WLTPHighCO2],       
[WLTPExtraHighCO2],      
[WLTPCombinedCO2],   
[WLTPWeightedCombinedCO2],           
[WLTPLowFuelConsumption],     

[WLTPMediumFuelConsumption],            
[WLTPHighFuelConsumption],    
[WLTPExtraHighFuelConsumption],         
[WLTPCombinedFuelCons],       

[WLTPWeightedCombinedFuelCons],
ElectricEnergyConsWeightedComb,ElectricRangeNEDC,  
UrbanConditionsCO2, 
ExtraUrbanConditionsCO2, 
CombinedConditionsCO2 as CombinedCO2,    
UrbanConditionsFuelConsumption, 
ExtraUrbanConditionsFuelCons, 
WeightedCombinedCO2, 
WeightedCombinedFuelCons,             
case when [WLTPCombinedFuelCons]=0 
     THEN 
        CASE WHEN WLTPWeightedCombinedFuelCons=0 
             THEN NULL 
             ELSE WLTPWeightedCombinedFuelCons
        END 
     ELSE [WLTPCombinedFuelCons] 
END AS WLTPCOMBINED_REPORTING_FC ,             
case when [WLTPCombinedCO2]=0 
     THEN 
        CASE WHEN WLTPWeightedCombinedCO2=0 
             THEN NULL 
             ELSE WLTPWeightedCombinedCO2 
        END 
     ELSE [WLTPCombinedCO2]
END AS WLTPCOMBINED_REPORTING_CO2,              
case when isnull(EmisTestMassWLTP,0)>0 
     THEN 'WLTP' 
     else 
        case when [WVTACOCLayoutVersions].description like '%2018%WLTP%' 
             THEN 'WLTP' 
             ELSE 'NEDC' 
        END 
END AS EMISSIONSTAGE,             
qvtvv.EmissionLegislation  , qvTVV.fname
FROM dbo.qvTVV 
inner join cocvinlist on qvTVV.vin=cocvinlist.vin      
left join qvtvvshort NKSTVV on nkstvvid=nkstvv.tvvid      
left join [WVTATVV] on [WVTATVV].tvvid=qvtvv.tvvid      
left join [WVTACOCLayoutVersions] 
    on [VersionNr]=case when isnull(nkstvv.cat,'X')='X' 
                        then dbo.qvTVV.LayoutVersion 
                        else nkstvv.LayoutVersion 
                   end      
    and [WVTACOCLayoutVersions].cat=case when isnull(nkstvv.cat,'X')='X' 
                                         then left(dbo.qvTVV.cat+'   ',2) 
                                         else left(nkstvv.cat+'   ',2) 
                                    end      
    and [WVTACOCLayoutVersions].completion=case when isnull(nkstvv.cat,'X')='X' 
                                                then dbo.qvTVV.completion 
                                                else nkstvv.completion 
                                            end      
left join NKS_PCOC on NKS_PCOC.VIN=qvTVV.VIN 
WHERE 
dbo.cocVINList.vin in (select VIN from codap_exportvins where cuser ='USER.NAME')  
and case when [WVTACOCLayoutVersions].description like '%2018%WLTP%' then case when [EmisTestMassWLTP]=0 then 0 else 1 end else 1 end=1) as qtmpgetVINApprovalData where validation ='OK';

【问题讨论】:

  • 共享直通查询SQL。这就是您可能出错的地方。
  • @ErikA 你的意思是不是有效的 SQL 可能是 SQL?
  • 是的,但整个情况对我来说有点不清楚。您的直通查询创建代码集curQdef.Connect = ConnectString '&amp; ";Returns Records=false;",这意味着您没有返回记录,但您仍然尝试创建记录集?而不是使用QueryDef.OpenRecordset,而是查询查询,这也很奇怪
  • 是的,这个函数的唯一目的是创建一个 QueryDef 供以后使用。这很奇怪,但恐怕已经习惯了很多次开始弄乱它。我正在研究如何在不共享太多细节的情况下共享 SQL。
  • 永远不要使用这个On Error Resume NextOn Error GoTo 0,因为你会抑制错误。是的,检查 SQLString 是否是有效的 SQL Server 查询。

标签: sql sql-server vba ms-access odbc


【解决方案1】:

本质上,您将 SQL 方言混为一谈。使用 DAO 的Database.OpenRecordset 调用只能读取 MS Access SQL 方言(而不是 SQL Server)的 Access 引擎。此操作将在 dbo.CASECHARINDEX 等上失败。

相反,将@ErikA cmets 视为使用QueryDef.OpenRecordset 底层记录集,该记录集将决定运行哪个后端SQL 引擎:

Dim qdef As QueryDef
Set qdef = DB.QueryDefs("qryName")
Set rsNew = qdef.OpenRecordset(dbSeeChanges)
...

延伸阅读:SQL Server Passthrough query as basis for a DAO recordset in Access .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    相关资源
    最近更新 更多