Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर व्यू में प्रोग्रामेटिक रूप से ODBC लिंक्ड टेबल कैसे बनाएं और क्या यह संपादन योग्य है?

ऐसा इसलिए नहीं है क्योंकि यह डीएसएन-कम है, बल्कि इसलिए कि आपने इसे वीबीए के माध्यम से बनाया है। यदि आप एक्सेस GUI के माध्यम से दृश्य को लिंक करते हैं, तो यह आपसे प्राथमिक कुंजी मांगता है।

लेकिन वीबीए के माध्यम से, यह प्राथमिक कुंजी नहीं जानता है, इसलिए लिंक किया गया दृश्य अद्यतन करने योग्य नहीं है। तालिका के साथ, ओडीबीसी के माध्यम से एक्सेस को प्राथमिक कुंजी स्वचालित रूप से मिलती है, इसलिए तालिका काम करती है।

समाधान: VBA के माध्यम से दृश्य को जोड़ने के बाद प्राथमिक कुंजी सेट करें:

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

यदि आपके पास कई विचार हैं, और उन्हें नियमित रूप से फिर से लिंक करें (जैसे देव से उत्पादन डेटाबेस में जाना), तो उनके नाम और पीके को हार्डकोड करना अव्यावहारिक हो जाता है। मैंने लिंक किए गए दृश्यों से सभी प्राथमिक कुंजी अनुक्रमणिका पुनर्प्राप्त करने और लिंक करने के बाद उन्हें फिर से बनाने के लिए एक फ़ंक्शन लिखा था।
यदि आप चाहें, तो मैं इसे खोद सकता हूं।

संपादित करें:
मैं यही करता हूं:

' 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

तालिकाओं के लिए, प्राथमिक कुंजी (पीके) स्वचालित रूप से निर्धारित होती है। एक दृश्य के लिए, मुझे पीके निर्दिष्ट करने के लिए एक्सेस डायलॉग विंडो मिलती है, जैसे कि मैं मैन्युअल रूप से दृश्य को लिंक करता हूं। पीके जानकारी टेबलडिफ ऑब्जेक्ट में लिंक किए गए दृश्य के लिए संग्रहीत होती है, इसलिए मुझे इसे कहीं भी हार्डकोड नहीं करना पड़ता है ।

सभी लिंक किए गए दृश्यों के लिए पीके जानकारी संग्रहीत करने के लिए, मेरे पास यह तालिका है (यह सरलता के लिए एक्सेस फ्रंटएंड में एक स्थानीय तालिका है):

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर 2017 स्थापना

  2. SQL सर्वर इंडेक्स फ़्रेग्मेंटेशन को ठीक करने के लिए टिप्स

  3. varbinary डेटा को डिस्क में सहेजने के लिए स्क्रिप्ट

  4. SQL सर्वर में वर्तमान तिथि कैसे प्राप्त करें

  5. SQL सर्वर संग्रहीत कार्यविधि से API को कॉल करना