简体   繁体   English

用于打开链接表访问-> SQL Server(VBA)的连接字符串

[英]Connection string for opening linked table Access -> SQL server (vba)

I've been looking for the answer as there are many similar questions, but haven´t found this particular case. 我一直在寻找答案,因为有很多类似的问题,但是还没有发现这种特殊情况。

I have an SQL server, and an Access File (front-end). 我有一个SQL Server和一个访问文件(前端)。 This Access file has linked tables, linked with the SQL server, and every time I try to open one table, a prompt appears asking for user and password. 该Access文件具有链接表,该链接表与SQL Server链接,并且每次我尝试打开一个表时,都会出现提示要求输入用户名和密码的提示。

OK, this is perfect, as it is (almost) the behaviour I want. 好的,这很完美,因为这几乎是我想要的行为。

Also, there's a local table, that contains User/Pass with passwords encrypted. 另外,还有一个本地表,其中包含带有加密密码的User / Pass。 Every time the user opens the file, his/her pass is decrypted and I would like to open a connection, so linked tables won´t ask for pass. 每次用户打开文件时,他/她的通行证都会被解密,而我想打开一个连接,因此链接表不会要求通行证。

Does anybody know how to code this connection? 有人知道如何编码此连接吗?

Thanks in advance! 提前致谢!

I think what you want is a "DSN-LESS connection" . 我认为您想要的是“ DSN-LESS连接” I've done something similar in the past. 我过去做过类似的事情。 Basically, at user login you re-link the tables using a connection string that you build based on the user's credentials. 基本上,在用户登录时,您将使用基于用户凭据构建的连接字符串重新链接表。

Take a look at this prior SO Question for more details. 请查看此先前的SO问题以获取更多详细信息。

Also, here are a few routines I've used in the past that you are free to use \\ modify. 另外,这里有一些我过去使用过的例程,您可以随意使用\\ modify。 Call these from your login process. 从您的登录过程中调用它们。

Public Function RelinkDSNTables( _
      ByVal ServerName As String, _
      ByVal DatabaseName As String, _
      ByVal UserName As String, _
      ByVal Password As String) As Boolean
On Error GoTo Err_Handler

Dim dsn As String
dsn = GetDSNLink(ServerName, DatabaseName, UserName, Password)
Dim td As TableDef
Dim db As DAO.Database
Set db = CurrentDb
Dim rst As ADODB.Recordset

'Get a list of tables that need to be relinked'
If GetLocalRecordSet(rst, "SELECT * FROM TableMapping") < 1 Then
   Err.Raise 1000, "Missing Tables!", "Missing Table Mappings!"
End If

Dim fNeedToRefresh As Boolean

'See if we actually need to relink the tables'
For Each td In db.TableDefs
   If td.Connect <> vbNullString Then
      If td.Connect <> dsn Then
         fNeedToRefresh = True
         Exit For
      End If
   End If
Next td

If fNeedToRefresh = False Then
   RelinkDSNTables = True
   GoTo Err_Handler
End If

'Drop linked table in Access'
For Each td In CurrentDb.TableDefs
   If td.Connect <> vbNullString Then
      CurrentDb.TableDefs.Delete td.Name
   End If
Next td

'Create new linked table using new DSN'
rst.MoveFirst
Do Until rst.EOF
   Set td = db.CreateTableDef(rst!LocalTableName, dbAttachSavePWD, rst!RemoteTableName, dsn)
   db.TableDefs.Append td
   rst.MoveNext
Loop

'Because I am paranoid, refresh the link'
db.TableDefs.Refresh
For Each td In db.TableDefs
   If td.Connect <> "" Then td.RefreshLink
Next td

RelinkDSNTables = True

Err_Handler:
   If Err.Number = 3011 Then
      'Happens if user does not have permission in SQL Server; Nothing to see here, move along'
      Err.Clear
      Resume Next
   ElseIf Err.Number = 3010 Then
      'already exists; should not occur, but if it does eat the exception and move on'
      Err.Clear
      Resume Next
   ElseIf Err.Number <> 0 Then
      Err.Raise Err.Number, Err.Source, Err.Description
   End If
End Function

Private Function GetDSNLink( _
      ByVal ServerName As String, _
      ByVal DatabaseName As String, _
      ByVal UserName As String, _
      ByVal Password As String) As String
On Error GoTo Err_Handler

If ServerName = "" Or DatabaseName = "" Then
   Err.Raise -1220, "Missing Server \ DB", _
      "Unable to refresh table links because you are missing the server or database name!"
End If

Dim dsnLink As String

If UserName = "" Then
   'trusted connection'
   dsnLink = "ODBC;DRIVER=SQL Server;SERVER=" & ServerName & _
            ";DATABASE=" & DatabaseName & ";Trusted_Connection=Yes"
Else
   'MixedMode connection'
     '//WARNING: This will save the username and the password with the linked table information.
   dsnLink = "ODBC;DRIVER=SQL Server;SERVER=" & ServerName & _
            ";DATABASE=" & DatabaseName & ";UID=" & UserName & ";PWD=" & Password
End If

GetDSNLink = dsnLink

Err_Handler:
   If Err.Number <> 0 Then
      Err.Raise Err.Number, Err.Source, Err.Description
   End If
End Function

Edit: Added sample GetLocalRecordSet Function 编辑:添加了示例GetLocalRecordSet函数

Public Function GetLocalRecordSet(ByRef rs As ADODB.Recordset, ByVal sql As String) As Long
On Error GoTo Err_Handler

If sql = vbNullString Then
   Err.Raise vbObjectError + 1001, _
      "Empty SQL String", "Empty SQL String Passed to GetLocalRecordset Function!"
End If

Set rs = New ADODB.Recordset

rs.Open sql, CurrentProject.Connection, adOpenKeyset, adLockOptimistic

If rs Is Nothing Then
   GetLocalRecordSet = -1
   GoTo Err_Handler
End If

If rs.State = adStateOpen Then
   If Not rs.EOF Then
      rs.MoveLast
      GetLocalRecordSet = rs.RecordCount                 'store number of records
      rs.MoveFirst
   Else
      GetLocalRecordSet = 0
   End If
Else
   GetLocalRecordSet = -2
End If

Err_Handler:
   If Err.Number <> 0 Then
      Err.Raise Err.Number, Err.Source, Err.Description
   End If
End Function

You can write a code to programmatically connect to the SQL database with username/password stored in your local table. 您可以编写代码以使用存储在本地表中的用户名/密码以编程方式连接到SQL数据库。 This should happen on Access app load (eg using Autoexec macro). 这应该在Access应用程序加载时发生(例如,使用Autoexec宏)。

You can read about Autoexec macro here: http://www.vb123.com/toolshed/05_map/ch04_autoexec.htm 您可以在此处阅读有关Autoexec宏的信息: http : //www.vb123.com/toolshed/05_map/ch04_autoexec.htm

So, you would have a function eg OpenConnection() which is called from Autoexec macro at application start. 因此,您将拥有一个函数,例如OpenConnection(),该函数在应用程序启动时从Autoexec宏调用。 Any subsequent table openings should not prompt for the password. 随后的任何表格打开都不应提示输入密码。

I am not sure if this will work with the SQL back-end, though. 我不确定这是否可以与SQL后端一起使用。 Hopefully, it will. 希望会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM