Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Bagaimana cara membuat Tabel Tertaut ODBC secara terprogram ke Tampilan SQL Server dan membuatnya dapat diedit?

Ini bukan karena tanpa DSN, tetapi karena Anda membuatnya melalui VBA. Jika Anda menautkan tampilan melalui Access GUI, itu akan meminta Anda untuk kunci utama.

Tetapi melalui VBA, ia tidak mengetahui kunci utama, sehingga tampilan tertaut tidak dapat diperbarui. Dengan tabel, Access mendapatkan kunci utama secara otomatis melalui ODBC, sehingga tabel berfungsi.

Solusi: atur kunci utama setelah menautkan tampilan melalui VBA:

S = "CREATE INDEX PrimaryKey ON MyViewName (MyPrimaryKeyField) WITH PRIMARY"
DB.Execute S

Jika Anda memiliki banyak tampilan, dan menautkannya kembali secara teratur (mis. beralih dari dev ke basis data produksi), menjadi tidak praktis untuk membuat hardcode nama dan PK mereka. Saya menulis sebuah fungsi untuk mengambil semua indeks kunci utama dari tampilan yang ditautkan, dan membuatnya kembali setelah menautkan.
Jika Anda mau, saya dapat menggalinya.

Sunting:
Ini yang saya lakukan:

' This function returns the full DSN-less connect string
Private Function ODBC_String() As String
    ' In the real world there are several constants and variable in there
    ODBC_String = "ODBC;DRIVER={SQL Server};SERVER=aaa;DATABASE=bbb;UID=ccc;PWD=ccc;LANGUAGE=us_english;TRUSTED_CONNECTION=No"
End Function

Untuk menautkan tabel atau tampilan pertama kali , saya menggunakan ini (strTable adalah nama tabel/tampilan):

DoCmd.TransferDatabase acLink, "ODBC", ODBC_String(), acTable, strTable, strTable, False, True

Untuk tabel, kunci utama (PK) ditentukan secara otomatis. Untuk tampilan, saya mendapatkan jendela dialog Access untuk menentukan PK, sama seperti jika saya menautkan tampilan secara manual.
Informasi PK disimpan di objek TableDef untuk tampilan tertaut, jadi saya tidak perlu melakukan hardcode di mana pun .

Untuk menyimpan informasi PK untuk semua tampilan yang ditautkan, saya memiliki tabel ini (ini adalah tabel lokal di frontend Access untuk kesederhanaan):

t_LinkedViewPK
    ViewName        Text(100)
    IndexFields     Text(255)

dan fungsi ini. Semua Tampilan (dan hanya Tampilan) disebut "v_*", jadi saya dapat mencantumkannya berdasarkan nama.
Saya sebenarnya tidak yakin apakah Anda dapat menentukan dari objek TableDef apakah objek tersebut menunjuk ke tabel atau tampilan.

Private Sub StoreViewPKs()

    Dim TD As TableDef
    Dim idx As index
    Dim FD As Field
    Dim RS As Recordset
    Dim S As String

    ' DB is a global Database object, set to CurrentDB
    DB.Execute "Delete * From t_LinkedViewPK"
    Set RS = DB.OpenRecordset("t_LinkedViewPK")

    For Each TD In DB.TableDefs
        If TD.Name Like "v_*" Then
            ' Views must have exactly one index. If not: panic!
            If TD.Indexes.Count <> 1 Then
                MsgBox "View " & TD.Name & " has " & TD.Indexes.Count & " Indizes.", vbCritical
                Stop
            End If

            Set idx = TD.Indexes(0)
            ' Build field list (the index may contain multiple fields)
            S = ""
            For Each FD In idx.Fields
                If S <> "" Then S = S & ", "
                S = S & FD.Name
            Next FD

            RS.AddNew
            RS!ViewName = TD.Name
            RS!IndexFields = S
            RS.Update
        End If
    Next TD

    RS.Close

End Sub

Ketika saya membuat perubahan pada tabel atau struktur tampilan, atau mengubah database sumber (ini dilakukan dengan mengubah output ODBC_String() ), saya memanggil fungsi ini:

Public Function Sql_RefreshTables()

    Dim TD As TableDef
    Dim S As String
    Dim IdxFlds As String

    DB.TableDefs.Refresh

    ' save current Indizes for Views (recreated after .RefreshLink)
    Call StoreViewPKs

    For Each TD In DB.TableDefs
        If Len(TD.Connect) > 0 Then
            If Left(TD.Connect, 5) = "ODBC;" Then

                Debug.Print "Updating " & TD.Name
                TD.Connect = ODBC_String()
                TD.RefreshLink

                ' View?
                If TD.Name Like "v_*" Then
                    IdxFlds = Nz(DLookup("IndexFields", "t_LinkedViewPK", "ViewName = '" & TD.Name & "'"))
                    If IdxFlds = "" Then Stop

                    ' Create PK
                    S = "CREATE INDEX PrimaryKey ON " & TD.Name & " (" & IdxFlds & ") WITH PRIMARY"
                    DB.Execute S
                End If

            End If
        End If
    Next TD

    DB.TableDefs.Refresh

End Function

Catatan:
Alih-alih tabel t_LinkedViewPK , objek kamus dapat digunakan. Tapi saat mengembangkan ini, sangat berguna untuk memilikinya sebagai tabel yang sebenarnya.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 13 praktik terbaik keamanan SQL Server

  2. cara menulis fungsi angka ke kata di sql server

  3. Perbarui beberapa tabel di SQL Server menggunakan INNER JOIN

  4. Cara Mengatur Spotlight Cloud dan Memecahkan Masalah SQL Server secara Efisien

  5. Crystal Reports vs. Layanan Pelaporan Microsoft SQL Server