2009-10-14 29 views
1

我管理一個SQL Server 2005數據庫,我想給一組20-30誰是能夠使用網絡的用戶只讀必要的表訪問在MS Access 2007中的圖形用戶界面編寫或修改自己的查詢到數據庫,有一些幫助。編程方式鏈接SQL Server表2007數據庫

我想分發一個Access數據庫與一個單一的形式,將創建必要的表的鏈接。所有這些用戶都包含在對SQL Server數據庫具有隻讀權限的組中。我可以爲連接分發一個dsn文件,但是我還沒有找到一種方法來編程創建鏈接到他們可能需要的50個左右表格,以及來自其他空白Access數據庫的網絡憑證。

我發現一行VB代碼從答案到一個類似的問題onstackoverflow(下面),但我想知道是否有任何簡單的方法比每次運行修改後的命令一次50表左右。

DoCmd.TransferDatabase acLink,「ODBC數據庫」,「ODBC; DRIVER = Microsoft ODBC for Oracle; SERVER = myserver; UID = myuser; PWD = mypassword」,acTable,「SCHEMA.TABLE」,「TABLE」,False ,真

回答

1

如果你的SQL Server使用Windows的安全,而不是SQL Server的安全性,那麼你不必在你的連接字符串提供用戶名/密碼。

下面是做到這一點的標準方式:

  1. 開發機器上,爲您的SQL Server數據庫的DSN。

  2. 使用FILE |獲取外部數據| LINK TABLES通過ODBC鏈接到表。

  3. 得到Doug Steele's code to convert to DSN-less connect strings

  4. 然後就分發前端爲的是你的用戶。

此方案的關鍵是使用Windows安全性而不是SQL Server安全性 - Access通過ODBC請求連接時靜靜地傳遞憑據。這是我永遠不會使用SQL Server安全性的一個原因 - 太麻煩了!

+0

@大衛:當用戶不在域中時,SQL Server安全性是好的(也是必需的)。 – 2009-10-15 06:01:05

+0

試過了,mdb中的鏈接包含我的憑據和我的權限。 – 2009-10-15 17:14:37

+0

用該用戶的憑據構建字符串,而不是你的! – 2009-10-15 18:17:34

2

除了大衛什麼建議,你可以有一個本地(客戶端)表中列出的通過SQL連接可用表的列表。然後,你可以寫一段VBA代碼,將瀏覽此表來建立所有相應的連接:

Dim rsTable as DAO.recordset 

set rsTable = currentDb.openRecordset("Tbl_Tables") 
if rsTable.EOF and rsTable.BOF then 
else 
    rsTable.moveFirst 
    Do while not rsTable.EOF 
     DoCmd.openDatabase .... 'enumerate here all needed paarmeters with rsTable.fields("tableName") in the string' 
     rsTable.moveNext 
    Loop 
Endif 
rsTable.close 
set rsTable = Nothing 

這段代碼寫在飛,所以我不能garantee它會工作「是」。例如,此代碼可以在啓動時(通過autoexec宏)啓動,以便用戶在打開應用程序時可以準備好鏈接。

的「僅查看」的東西可以通過列出相應的用戶輕鬆進行管理(或者,如果你有一個域名,用戶對應的組)爲您的SQL服務器上的「數據讀取器」。

+0

當我以前發佈了一個mdb的鏈接時,用戶有我的權限(我是dbowner)。 用戶需要能夠讀取和下載當前數據。 約150張桌子,他們只需要看〜50。創建鏈接(一次)將爲他們提供一個_automated_流程來創建他們憑據的訪問權限,而不需要我與整個州的20-30名用戶進行個人交互,或者使用冗長的cookbook方法(嘗試),列出流程並向所有人展示好奇心的表格。 – 2009-10-15 17:13:06

+0

我建議你調查SQL用戶角色。您可以爲每個用戶(或一組用戶)授予數據庫等的權利,從連接到刪除數據庫。在您的情況下,您必須在數據庫級別提供「有限的數據讀取器」權限,並將此權限與一個用戶名和密碼相關聯。然後,您可以選擇該用戶有權查看的表格或視圖。然後,在爲您的客戶端訪問接口構建連接字符串時,您將使用此「有限數據讀取器」憑據,從而限制用戶對所需數據的訪問權限。 – 2009-10-15 18:16:24

1

是否有一個特殊的原因,你想每次重新創建鏈接? 使用鏈接表創建一次mdb並將該mdb分發給用戶會簡單得多。
您可能還想要將SQL Server視圖(而不是表)鏈接到Access表,以確保它是隻讀的,可能需要預先連接某些表,並刪除一些不需要的字段。

+0

不,只有一次,當用戶決定他或她想要「查看」數據庫時。鏈接完成後,他們可以自由創建自己的查詢並將數據下載到本地表中。隨着他們的數據庫建立,他們可以引用先前的查詢,而不需要隱藏數據庫。 – 2009-10-30 17:48:49

+0

然後我給你最好的答案8-)) – 2009-10-31 12:04:50

1

爲什麼不在Access中使用Active Data Project?

鏈接表只有在您還需要本地(未鏈接)表時纔有用。如果您可以保留SQL Server上的所有表和視圖並將表單保留在Access中,則ADP將正常工作,並且不需要手動或通過腳本「鏈接」任何表。

爲了迴應Patrick下面的問題,如果您不希望他們在真正的SQL Server存儲中創建查詢,請創建第二個SQL Server數據庫,以便他們有權創建和更新查詢,並創建VIEW以下:

CREATE VIEW mytable AS SELECT * FROM [real database].dbo.mytable 

因此,當你改變你的主數據表,你只需要做出改變的查看他們的共享SQL Server數據庫中,而不是改變每個Access數據庫。

方面優勢#1:用戶可以看到彼此的查詢,從而給出了一個社交方面,可以輕鬆分享好的查詢。

副優點2:因爲它們都在同一個位置,所以如果您更改其中一個只讀表(通過搜索由其創建的視圖定義),則可以使用SQL Server檢測哪些用戶查詢會中斷訪問)。

+0

不是一個好主意。使用ADP,您將很快破壞您的數據庫,並且用戶將創建所有醜陋的查詢。 – 2009-10-15 11:45:16

+1

不使用和ADP的原因之一是因爲它是一種過時的技術,從未在Access版本中始終如一地或可靠地工作,並且正在被微軟逐步淘汰。他們推薦的Access/SQL Server平臺是帶有ODBC鏈接的MDB/ACCDB。這已經是MS至少2 - 3年的陳述立場。 – 2009-10-15 23:54:31

4

上週我剛剛寫了一個article,詳細介紹了將SQL數據庫中的所有錶快速鏈接到Access的方法。以下是一些有助於解決的Access方法。閱讀文章以獲取使用它的更多說明。

您將需要引用Microsoft ActiveX Data Objects庫。

Sub LinkAllTables(Server As String, database As String, OverwriteIfExists As Boolean) 
    'Usage Example (link all tables in database "SQLDB" on SQL Server Instance SQO01, overwriting any existing linked tables. 
    'linkalltables "SQL01","SQLDB", true 

    'This will also update the link if the underlying table definition has been modified. 

    Dim rsTableList As New ADODB.Recordset 
    Dim sqlTableList As String 

    sqlTableList = "SELECT [name] as tablename FROM sysObjects WHERE (type = 'U')" 

    rsTableList.Open sqlTableList, BuildSQLConnectionString(Server, database) 
    While Not rsTableList.EOF 
     If LinkTable(rsTableList("tableName"), Server, database, rsTableList("tableName"), OverwriteIfExists) Then 
      Debug.Print "Linked: " & rsTableList("tableName") 
     End If 
     rsTableList.MoveNext 
    Wend 

    rsTableList.Close 
    Debug.Print "Done." 

End Sub 

Function LinkTable(LinkedTableAlias As String, Server As String, database As String, SourceTableName As String, OverwriteIfExists As Boolean) 
    'This method will also update the link if the underlying table definition has been modified. 

    'The overwrite parameter will cause it to re-map/refresh the link for LinktedTable Alias, but only if it was already a linked table. 
    ' it will not overwrite an existing query or local table with the name specified in LinkedTableAlias. 

    'Links to a SQL Server table without the need to set up a DSN in the ODBC Console. 
    Dim dbsCurrent As database 
    Dim tdfLinked As TableDef 

    ' Open a database to which a linked table can be appended. 
    Set dbsCurrent = CurrentDb() 

    'Check for and deal with the scenario ofthe table alias already existing 
    If TableNameInUse(LinkedTableAlias) Then 

     If (Not OverwriteIfExists) Then 
      Debug.Print "Can't use name '" + LinkedTableAlias + "' because it would overwrite existing table." 
      Exit Function 
     End If 

     'delete existing table, but only if it is a linked table 
     If IsLinkedTable(LinkedTableAlias) Then 
      dbsCurrent.TableDefs.Delete LinkedTableAlias 
      dbsCurrent.TableDefs.Refresh 
     Else 
      Debug.Print "Can't use name '" + LinkedTableAlias + "' because it would overwrite an existing query or local table." 
      Exit Function 
     End If 
    End If 

    'Create a linked table 
    Set tdfLinked = dbsCurrent.CreateTableDef(LinkedTableAlias) 
    tdfLinked.SourceTableName = SourceTableName 
    tdfLinked.Connect = "ODBC;DRIVER={SQL Server};SERVER=" & Server & ";DATABASE=" & database & ";TRUSTED_CONNECTION=yes;" 

    On Error Resume Next 
    dbsCurrent.TableDefs.Append tdfLinked 
    If (Err.Number = 3626) Then 'too many indexes on source table for Access 
      Err.Clear 
      On Error GoTo 0 

      If LinkTable(LinkedTableAlias, Server, database, "vw" & SourceTableName, OverwriteIfExists) Then 
       Debug.Print "Can't link directly to table '" + SourceTableName + "' because it contains too many indexes for Access to handle. Linked to view '" & "vw" & SourceTableName & "' instead." 
       LinkTable = True 
      Else 
       Debug.Print "Can't link table '" + SourceTableName + "' because it contains too many indexes for Access to handle. Create a view named '" & "vw" & SourceTableName & "' that selects all rows/columns from '" & SourceTableName & "' and try again to circumvent this." 
       LinkTable = False 
      End If 
      Exit Function 
    End If 
    On Error GoTo 0 

    tdfLinked.RefreshLink 
    LinkTable = True 

End Function 

Function BuildSQLConnectionString(Server As String, DBName As String) As String 
    BuildSQLConnectionString = "Driver={SQL Server};Server=" & Server & ";Database=" & DBName & ";TRUSTED_CONNECTION=yes;" 
End Function 

Function TableNameInUse(TableName As String) As Boolean 
    'check for local tables, linked tables and queries (they all share the same namespace) 
    TableNameInUse = DCount("*", "MSYSObjects", "(Type = 4 or type=1 or type=5) AND [Name]='" & TableName & "'") > 0 
End Function 

Function IsLinkedTable(TableName As String) As Boolean 
    IsLinkedTable = DCount("*", "MSYSObjects", "(Type = 4) AND [Name]='" & TableName & "'") > 0 
End Function 
相關問題