sql >> データベース >  >> RDS >> Sqlserver

SQL ServerビューへのODBCリンクテーブルをプログラムで作成し、編集可能にするにはどうすればよいですか?

    これは、DSNがないためではなく、VBAを介して作成したためです。アクセスGUIを介してビューをリンクすると、主キーの入力を求められます。

    ただし、VBAを介すると、主キーがわからないため、リンクされたビューは更新できません。テーブルを使用すると、AccessはODBCを介して主キーを自動的に取得するため、テーブルは機能します。

    解決策: VBAを介してビューをリンクした後、主キーを設定します:

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

    多くのビューがあり、それらを定期的に再リンクする場合(たとえば、開発データベースから本番データベースに移動する場合)、それらの名前とPKをハードコーディングすることは実用的ではなくなります。リンクされたビューからすべての主キーインデックスを取得し、リンク後にそれらを再作成する関数を作成しました。
    必要に応じて、掘り下げることができます。

    編集:
    これが私がしていることです:

    ' 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
    

    テーブルをリンクしたり、初めて表示したりするには 、私はこれを使用します(strTableはテーブル/ビュー名です):

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

    テーブルの場合、主キー(PK)は自動的に決定されます。ビューの場合、ビューを手動でリンクするのと同じように、[アクセス]ダイアログウィンドウでPKを指定します。
    PK情報はリンクされたビューのTableDefオブジェクトに格納されるため、どこにもハードコーディングする必要はありません。 。

    リンクされたすべてのビューのPK情報を保存するために、次のテーブルがあります(簡単にするためにAccessフロントエンドのローカルテーブルです):

    t_LinkedViewPK
        ViewName        Text(100)
        IndexFields     Text(255)
    

    そしてこの機能。すべてのビュー(およびのみ ビュー)は「v_ *」と呼ばれるので、名前で一覧表示できます。
    TableDefオブジェクトから、テーブルを指しているのかビューを指しているのかを判断できるかどうかは実際にはわかりません。

    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
    

    テーブルまたはビューの構造を変更したり、ソースデータベースを変更したりする場合(これは、ODBC_String()の出力を変更することによって行われます。 )、私はこの関数を呼び出します:

    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
    

    注:
    テーブルの代わりにt_LinkedViewPK 、辞書オブジェクトを使用できます。しかし、これを開発する際に、実際のテーブルとして持つことは非常に役に立ちました。



    1. テーブルの作成中にエラーが発生しました:1行目の'order(order_id INT UNSIGNED NOT NULL AUTO_INCREMENT、user_id'の近くのSQL構文にエラーがあります

    2. PostGISを使用して特定のポイントのn最近傍を検索しますか?

    3. MySQLでのCHARACTER_LENGTH()関数のしくみ

    4. PostgreSQL:タイムスタンプフィールドに「いいね」が付いたデータを選択します