Sql server 使用Access 2010 VBA和链接表,告诉SQL Server 2008 R2使用用户名和密码以避免出现错误18452

Sql server 使用Access 2010 VBA和链接表,告诉SQL Server 2008 R2使用用户名和密码以避免出现错误18452,sql-server,ms-access,vba,linked-tables,Sql Server,Ms Access,Vba,Linked Tables,我正在使用SQL Server 2008 R2和MS Access 2010。我有一个带有链接表的.accdb,使用登录名和密码而不是windows身份验证,因为我们有几个远程用户。使用SSMS或我的Access.adp项目使用此登录名和密码没有问题 我已经使用Doug Steele网站的代码成功地为我的表创建了无DSN连接,但是从MS Office博客创建缓存连接时遇到了问题 我继续得到以下错误: Connection Failed: SQLState ;28000', Server Erro

我正在使用SQL Server 2008 R2和MS Access 2010。我有一个带有链接表的.accdb,使用登录名和密码而不是windows身份验证,因为我们有几个远程用户。使用SSMS或我的Access.adp项目使用此登录名和密码没有问题

我已经使用Doug Steele网站的代码成功地为我的表创建了无DSN连接,但是从MS Office博客创建缓存连接时遇到了问题

我继续得到以下错误:

Connection Failed: SQLState ;28000', Server Error 18452, 
The login is from an untrusted domain and cannot 
be used with Windows authentication.
此时,代码将尝试将测试查询传递给SQL:

Set rst = dbCurrent.OpenRecordset(strTable, dbOpenSnapshot)
然后,当我单击“确定”时,我会看到SQL Server登录屏幕,其中选中了
使用受信任的连接
(我不希望这样),并且自动填充了一个登录ID,该ID不是我通过代码提供的ID

所以,第一,为什么Access/SQL在我不想连接的情况下,却不断尝试使用windows身份验证进行连接。有没有办法指定不允许
Trusted_Connection=NO
似乎不起作用

其次(不太重要,但很奇怪),登录ID是自动填充的,但不是我代码中的登录ID。为什么SQL Server会选择不同的登录ID

注意: 如果我取消选中
Use trusted connection
,并填写正确的登录名和密码(VBA代码正在正确接收该登录名和密码–我使用
debug.print
检查了我的连接字符串),则缓存的连接可以工作。因此,我也知道我的连接字符串在代码中是正确的

我已仔细检查,我的SQL Server设置为“混合模式”,以允许登录和密码。(根据Access 2010发布的MS SQL Server(2008 R2)错误18452)

我确实安装了“本机客户端”(根据“如何设置和ADODB到SQL Server 2008 inf Microsoft Access 2010的连接”一文)

我的代码:

Dim dbCurrent As DAO.Database
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
Dim strConnection As String

Dim strTable As String

strTable = "one of my linked tables"

strConnection = "ODBC;DRIVER={sql Server};" & _
                "DATABASE=MyDatabase;" & _
                "SERVER=MyServer;"

Set dbCurrent = DBEngine.Workspaces(0).Databases(0)
Set qdf = dbCurrent.CreateQueryDef("")

With qdf
    .Connect = strConnection & _
               "UID=" & strUserName & ";" & _
               "PWD=" & strPassword
    .SQL = "Select Current_User ();"

    Set rst = dbCurrent.OpenRecordset(strTable, dbOpenSnapshot)

End Wit
InitConnect = True
有几件事:

首先,确保您创建的SQL登录正常工作。请注意,您既需要SQL登录,也需要为给定数据库创建SQL用户(因此不要混淆SQL server登录和SQL server用户登录之间的区别–这是常见的混淆)

使用SQL studio工具,通过经过身份验证的用户断开与数据库的连接,现在通过新的SQL登录重新连接。换句话说,100%确保此类SQL登录可以从SSM工作。然后(并且只有在那时)因此,在SSMS测试中,请尝试SQL登录+密码以确保其工作并允许您打开/使用表。考虑将SQL登录为数据库的“所有者”,然后创建该表的同名用户。

当然,我假设您将SQL server设置为混合模式?如果用户未登录到您的域,则很可能在解析服务器名称时遇到问题。(请尝试使用\192.0.0.50\sqlExpress或任何SQL ip地址和实例名称)

下一步:

您的“测试”登录语法不正确,将始终返回false。请尝试通过SSMA在sql server中键入选择字符串,并注意它是如何不起作用的(选择永远不会起作用)

删除您拥有的空间和()

我只想使用:

.SQL = "Select Current_User;"
因此,您的空格+the()不起作用,需要删除

此外,我建议您包括网络DBMSSOCN,因为这意味着通过TCP/IP进行连接。您可能是这样,但这会加剧问题

例如:

确保通过SQL登录而不是windows身份验证在SSMS中工作后,请修复登录“选择”命令

还要注意,要使密码缓存作为“常规”规则工作,您使用的测试登录字符串必须与链接字符串+uid/密码相同。因此tabledef链接字符串没有uid/密码

因此,如果保存的表链接中有“APP”等内容,或者连接字符串中有其他不需要的部分,那么您的测试登录连接字符串应该与额外的uid/logon具有相同的额外值。因此,如果您的测试登录和测试连接字符串相当“不同”然后是现有的已保存链接,然后缓存可能会在匹配正确的表和服务器时出现问题

我用于测试登录的代码是:

Function TestLogin(strcon As String) As Boolean

  On Error GoTo TestError

  Dim dbs          As DAO.Database
  Dim qdf          As DAO.QueryDef

  Set dbs = CurrentDb()
  Set qdf = dbs.CreateQueryDef("")

   qdf.Connect = strcon

   qdf.ReturnsRecords = False

   'Any VALID SQL statement that runs on server will work below.
    qdf.SQL = "Select Current_User;"
   qdf.Execute

   TestLogin = True

   Exit Function

 TestError:
   TestLogin = False
   Exit Function

End Function
创建字符串的代码为:

Public Function dbCon(ServerName As String, _
                     DataBaseName As String, _
                     USERid As String, _
                     USERpw As String, _
                     Optional APP As String = "Office 2010", _
                     Optional WSID As String = "SC", _
                     Optional IntegratedSecurity As Boolean = False) As String

      ' returns a SQL server conneciton string
  If IntegratedSecurity = False Then
     dbCon = "ODBC;DRIVER={" & SQLDRIVER & "};" & _
             "SERVER=" & ServerName & ";" & _
             "DATABASE=" & DataBaseName & ";" & _
             "UID=" & USERid & ";" & _
             "PWD=" & USERpw & ";" & _
             "Network=DBMSSOCN"

  Else
     dbCon = "ODBC;DRIVER=" & SQLDRIVER & ";" & _
             "SERVER=" & ServerName & ";" & _
             "DATABASE=" & DataBaseName & ";" & _
             "APP=" & APP & ";" & _
             "WSID=" & WSID & ";" & _
             "Network=DBMSSOCN" & ";" & _
             "Integrated Security= SSPI"
  End If


End Function
我的登录“测试”是:


我会在不启动任何访问表单等的情况下运行/测试上述例程。因此,只需测试/使用上述代码即可。您需要让您的登录正常工作,当登录正常工作时,提示就会消失。

看看另一个问题的最新答案。我确信@AlbertD.Kallal可以比我更好地解释它,但我的理解是您的SQL Server凭据在首次建立连接时经过验证,并在应用程序的生命周期内保持有效。因此,您创建的链接不带“保存密码”选项,并让应用程序启动代码进行第一次连接(这将提示输入用户名和密码).从那时起,你应该没事了。另外,AFAIK
Trusted_Connection=no
应该可以工作……谢谢汤普森先生!A.D.Kallal所说的电源提示就是我正在使用的。就像他们建议的,我不想保存密码,所以我不想使用“MyTableDef.Attributes=DB_AttachSavePwd”。事实上,我遇到的问题是在建立第一个连接时验证SQL Server凭据。我想在连接字符串中传递用户名和pswd,但它一直尝试使用产生错误的受信任连接进行连接。我还查看了这一点,建议重新链接表(或者全部都是通过代码实现的)-我尝试过了,但它基本上做了我在部署它后试图避免给用户做的事情(必须取消选中“可信连接”框并输入我的UID和Pwd),我只希望他们这样做
Public Function dbCon(ServerName As String, _
                     DataBaseName As String, _
                     USERid As String, _
                     USERpw As String, _
                     Optional APP As String = "Office 2010", _
                     Optional WSID As String = "SC", _
                     Optional IntegratedSecurity As Boolean = False) As String

      ' returns a SQL server conneciton string
  If IntegratedSecurity = False Then
     dbCon = "ODBC;DRIVER={" & SQLDRIVER & "};" & _
             "SERVER=" & ServerName & ";" & _
             "DATABASE=" & DataBaseName & ";" & _
             "UID=" & USERid & ";" & _
             "PWD=" & USERpw & ";" & _
             "Network=DBMSSOCN"

  Else
     dbCon = "ODBC;DRIVER=" & SQLDRIVER & ";" & _
             "SERVER=" & ServerName & ";" & _
             "DATABASE=" & DataBaseName & ";" & _
             "APP=" & APP & ";" & _
             "WSID=" & WSID & ";" & _
             "Network=DBMSSOCN" & ";" & _
             "Integrated Security= SSPI"
  End If


End Function
Public Sub Logon()

  ' this simply tests + logs in the user to the default database.
  ' once this occurs, then a odbc logon prompt for each linked table
  ' should not occur - this works WHEN the connection string used here
  ' matches the odbc connection string exaclty.

    Dim strcon     As String


   ' con string settings are:

   ' server , DataBaseName, User, Password, [Optional Application name], [Optional work station]
   ' last two optional are for sql performance tracing etc. - not required

   strcon = dbCon("albertkallal-pc\SQLEXPRESS", "MyTestDec222", "test", "test")

   Debug.Print TestLogin(strcon)


End Sub