2016-12-30 20 views
0

我们得到了这是在2000年开发了一些旧的遗留应用程序,我们已经从接入移动2003至2007年当我试图运行的应用程序的模块,它给我的错误:如何将代码从DAO重写到ADO?

"Run-time error 3847. ODBCDirect is no longer supported. Rewrite the code to use ADO instead of DAO".

而且它突出显示为Set WS = CreateWorkspace("NewWS", "", "", dbUseODBC)。由于我对Access非常陌生,因此在发布此问题之前,我做了一些研究,但没有成功。我试图重写代码以使用ADO而不是DAO。

以下是我的老VBA代码:

Public Function GetID (ByRef SegmentItem As clsSegmentDefinitions) As Long 
    Dim qdf As QueryDef 
    Dim qdfNewID As QueryDef 
    Dim rs As Recordset 
    Dim rsNewID As Recordset 
    Dim NaturalDescription As String 
    Dim WS As Workspace 
    Dim con As Connection 
    Set WS = CreateWorkspace("NewWS", "", "", dbUseODBC) 
    WS.DefaultCursorDriver = dbUseODBCCursor 
    Set con = WS.OpenConnection("", , , SQLConnectString) 
    DoCmd.Hourglass False 
    DoCmd.OpenForm " frmQuickAdd_AddNatural ", , , , , acDialog, SegmentItem.AddValue 
    DoCmd.Hourglass True 
    If Form_frmQuickAdd_AddNatural.Tag Then 
     Set qdf = con.CreateQueryDef("", "{ ? = call sp_Insert(?, ?, ?) }") 
     qdf.Parameters.Refresh 
     qdf![@prmDescription] = Left(Form_frmQuickAdd_AddNatural.txtSegmentDescription, 34) 
     qdf![@prmCreateUser] = CurrentUser 
     qdf![@prmProjectID] = 0 
     qdf.Execute 
     Set qdfNewID = CodeDb.CreateQueryDef("") 
     qdfNewID.Connect = SQLConnectString 
     qdfNewID.ReturnsRecords = True 
     qdfNewID.SQL = "sp_GetNewSegmentID" 
     Set rsNewID = qdfNewID.OpenRecordset 
     If Not IsNull(rsNewID!MaxOfSegmentID) Then 
      GetID = rsNewID!MaxOfSegmentID 
     Else 
      GetID = 0 
     End If   
    Else 
     GetID = 0 
    End If 
    DoCmd.Close acForm, "frmQuickAdd_AddNatural"  
End Function 

我开始重写代码,但我不知道如果想是这样的。

Dim cnn As New ADODB.Connection 
Dim rst As New ADODB.Recordset 

cnn.Open "Provider=mssql;Data Source=" & dbq & ";User Id=" & uid & ";Password=" & pwd 
With rst 
    .Open "SELECT COUNT(*) FROM " & tbl, cnn, adOpenKeyset, adLockOptimistic 
    num = .Fields(0) 
    .Close 
End With 
cnn.Close 
Set rst = Nothing 
Set cnn = Nothing 
+0

重写ADO会有很多工作要做。或者,修改 - 仍然使用DAO - 在没有ODBC WorkSpace的情况下工作。 – Gustav

+1

我会把整个东西移植到SQL Server免费版。我最近在Access上花费了大量的时间和精力。可怕。 –

+1

我已经重新格式化了您的问题以修复代码块,但您的问题本质上*太宽泛*。您可以在[Documentation.SO](http://stackoverflow.com/documentation/vba/3578/working-with-ado#t=201612301821243706514)中找到有关ADO的信息;一旦你被困在一个特定的问题上,你就会有一个*特定的问题,我们将能够给你特定的答案。现在看起来你要求其他人为你做“翻译”工作,这不是Stack Overflow的目的。 –

回答

2

首先,您真的不想将ADO引入到围绕DAO构建和设计的应用程序中。更糟的是,ADO现在已经走了15年了。实际上SQL服务器正在放弃对ADO工作的oleDB的支持。 (所以不要去那里)。

请参阅有关SQL服务器删除OLEDB支持此链接:

http://blogs.msdn.com/b/sqlnativeclient/archive/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access.aspx

行业已经从ADO和所有主要供应商远所提出的建议使用开放式数据库连接的行业标准。 (这意味着ODBC)。

我会在Access中创建并保存传递查询。您的代码可以重写为:

Public Function GetID(ByRef SegmentItem As String) As Long 

    Dim strSQL  As String 

    strSQL = "sp_Insert('" & _ 
      Left(Form_frmQuickAdd_AddNatural.txtSegmentDescription, 34) & "'," & _ 
      "'" & CurrentUser & "', 0)" 

    With CurrentDb.QueryDefs("qryPass") 
    .SQL = strSQL 
    .ReturnsRecords = False 
    .Execute 
    End If 

    With CurrentDb.QueryDefs("qryPass") 
    .SQL = "sp_GetNewSegmentID" 
    .ReturnsRecords = True 
    GetID = Nz(.OpenRecordset()("MaxOfSegmentID"),0) 
    End With 

End Function 

因此,创建一个传递查询。你可以在你使用JET-DIRECT的所有地方使用它。在2007年的访问中,jet-direct支持被放弃了,但使用简单的传递查询将绰绰有余,而且上面的代码显示了节省编码和开发人员时间的空间。如果你有的“left”表达式可以返回null,那么你可能需要将该表达式包装在nz()中以返回“”(空字符串)或适当的值。

+0

谢谢你的回复。我正在研究在线传递查询。所以,上面的“qrypass”是传递查询,对吧?传递查询的内容是什么?它是存储过程sp_insert吗? – toofaced

+0

您可以在传递查询中放置任何您想要的内容。所以只需用tblCustomers中的简单选择计数(*)来测试PT。 PT查询可以从任何合法的t-sql语句开始。上面显示您将“经常”将该PT查询的.SQL文本属性修改为任何即时操作。因此,首先通过点击它来运行PT查询来运行它。一旦工作,上面的代码将按照上面的动态改变.SQL属性。这可以让你在PT查询中使用任何t-sql。这也意味着你不会在代码中弄乱连接字符串,并且很适合替换jet-direct代码。 –

+0

任何在上面qryPass是我用于PT查询的名称 - 它可以是任何你想要的名字。由于DAO记录集代码的其余部分不需要重新编写,并且可以像以前一样工作,所以此方法是首选。因此,这种方法对现有的DAO记录集代码进行最少量的更改。 –