DoCmd.RunSQL प्रश्नों को निष्पादित करते समय त्रुटि 3340 क्वेरी '' भ्रष्ट है


83

Office 2010 के लिए Windows अद्यतन को स्थापित करने के बाद से KB 4484127 को हल करने पर मुझे उन प्रश्नों को निष्पादित करते समय एक त्रुटि मिलती है जिनमें WHERE क्लॉज होता है।

उदाहरण के लिए इस क्वेरी को निष्पादित करना:

DoCmd.RunSQL "update users set uname= 'bob' where usercode=1"

इस त्रुटि के परिणाम:

त्रुटि संख्या = 3340 क्वेरी '' भ्रष्ट है

सवाल में अद्यतन वर्तमान में अभी भी स्थापित किया गया है:

Microsoft Office 2010 सर्विस पैक 2 को दिखाने वाला स्क्रीनशॉट 448127 अपडेट करता है

मैं अपने प्रश्नों को सफलतापूर्वक कैसे चला सकता हूं? क्या मुझे इस अद्यतन की स्थापना रद्द करनी चाहिए?

जवाबों:


92

सारांश

यह 12 नवंबर, 2019 को जारी किए गए कार्यालय अपडेट के कारण ज्ञात बग है । बग Microsoft द्वारा समर्थित वर्तमान में एक्सेस के सभी संस्करणों को प्रभावित करता है (एक्सेस 2010 से 365 तक)।

इस बग को ठीक कर दिया गया है।

  • यदि आप Office के C2R (क्लिक-टू-रन) संस्करण का उपयोग करते हैं , तो "अभी अपडेट करें" का उपयोग करें :
    • एक्सेस 2010 C2R: बिल्ड 7243.5000 में फिक्स्ड
    • एक्सेस 2013 C2R: बिल्ड 5197.1000 में फिक्स्ड
    • एक्सेस 2016 C2R: बिल्ड 12130.20390 में फिक्स्ड
    • एक्सेस 2019 (v1910): बिल्ड 12130.20390 में फिक्स्ड
    • एक्सेस 2019 (वॉल्यूम लाइसेंस): बिल्ड 10353.20037 में फिक्स्ड
    • ऑफिस 365 मंथली चैनल: बिल्ड 12130.20390
    • ऑफिस 365 सेमी-एनुअल: बिल्ड 11328.20480 में फिक्स्ड
    • Office 365 अर्ध-वार्षिक विस्तारित: बिल्ड 10730.20422 में फिक्स्ड
    • Office 365 अर्ध-वार्षिक लक्षित: बिल्ड 11929.20494 में फिक्स्ड
  • यदि आप Office के किसी MSI संस्करण का उपयोग करते हैं, तो अपने Office संस्करण से मेल खाते का अद्यतन स्थापित करें। ये सभी पैच Microsoft अद्यतन पर जारी किए गए हैं, इसलिए सभी लंबित Windows अपडेट स्थापित करना पर्याप्त होना चाहिए:
    • एक्सेस 2010 MSI: KB4484193 में फिक्स्ड
    • एक्सेस 2013 MSI: KB4484186 में फिक्स्ड
    • एक्सेस 2016 MSI: KB4484180 में फिक्स्ड

उदाहरण

यहाँ एक न्यूनतम रेप्रो उदाहरण दिया गया है:

  1. एक नया एक्सेस डेटाबेस बनाएँ।
  2. डिफ़ॉल्ट आईडी फ़ील्ड के साथ एक नया, खाली टेबल "Table1" बनाएं और एक लॉन्ग इंटेगर फ़ील्ड "myint"।
  3. VBA के संपादक विंडो में निम्नलिखित कोड निष्पादित करें:

    CurrentDb.Execute "UPDATE Table1 SET myint = 1 WHERE myint = 1"

अपेक्षित परिणाम : कथन सफलतापूर्वक समाप्त होता है।

इंस्टॉल किए गए बगगी अपडेट में से एक के साथ वास्तविक परिणाम : रन-टाइम त्रुटि 3340 होती है ("क्वेरी '' भ्रष्ट है")।


सम्बंधित लिंक्स:


9
यह पोस्ट 64-बिट एक्सेस रनटाइम और OLEDB का उपयोग करके उसी त्रुटि का सामना करता है। डरावना सामान, यह कई एप्लिकेशन बना देगा जो डेटा को बेकार करने के लिए एक्सेस का उपयोग करते हैं।
एरिक

4
मैंने सिर्फ Office 2013 32-बिट के साथ एक सिस्टम की जाँच की और उस विशेष मशीन पर अपडेट के लिए UUID है 90150000-006E-0409-0000-0000000FF1CE... वह -0409-, नहीं -0407-
गॉर्ड थॉम्पसन

4
मैंने सिर्फ कार्यालय में एक और मशीन की जाँच की जिसमें कार्यालय 2013 64-बिट है और यूयूआईडी -006E-0409-भी है। दोनों मशीनों में Microsoft Office 2013 (KB2850036) के लिए सर्विस पैक 1 स्थापित है।
गॉर्ड थॉम्पसन

4
Office 2010 Pro Plus (SP2) के लिए हमें {90140000-0011-0000-0000-0000000FF1CE}बैच स्क्रिप्ट में उपयोग करने की आवश्यकता है । नोट {9014...नहीं{9114..}
AdamsTips

2
मैंने समस्या को हल करने के लिए आधिकारिक अद्यतन के साथ समझौता किया है लेकिन मुझे अभी भी त्रुटि मिल रही है। किसी और को वह समस्या मिल गई?
user218076

33

सबसे सरल उपाय

मेरे उपयोगकर्ताओं के लिए, Microsoft से एक निश्चित रिलीज़ के लिए 10 दिसंबर तक लगभग एक महीने तक इंतजार करना एक विकल्प नहीं है। न ही कई सरकारी लॉक डाउन वर्कस्टेशनों में आपत्तिजनक Microsoft अद्यतन की स्थापना रद्द कर रहे हैं।

मुझे वर्कअराउंड लागू करने की आवश्यकता है, लेकिन माइक्रोसॉफ्ट ने जो सुझाव दिया है उससे बिल्कुल रोमांचित नहीं हूं - प्रत्येक तालिका के लिए एक क्वेरी बनाना और प्रतिस्थापित करना।

समाधान तालिका नाम को (SELECT * FROM Table)सीधे UPDATEआदेश में एक साधारण क्वेरी के साथ बदलना है । इसके लिए अतिरिक्त क्वेरी, टेबल या फ़ंक्शंस के एक टन को बनाने और सहेजने की आवश्यकता नहीं है।

उदाहरण:

इससे पहले:

UPDATE Table1 SET Field1 = "x" WHERE (Field2=1);  

उपरांत:

UPDATE (SELECT * FROM Table1) SET Field1 = "x" WHERE (Field2=1);  

यह कई डेटाबेस और अनुप्रयोगों (और बाद में रोलबैक) को लागू करने के लिए बहुत आसान होना चाहिए।


20

यह विंडोज अपडेट की समस्या नहीं है, बल्कि एक समस्या है जिसे नवंबर पैच मंगलवार ऑफिस रिलीज के साथ पेश किया गया था। सुरक्षा भेद्यता को ठीक करने के लिए परिवर्तन के कारण कुछ वैध प्रश्नों के भ्रष्ट होने की सूचना मिलती है। चूँकि परिवर्तन एक सुरक्षा फ़िक्स था, इसलिए यह 2010, 2013, 2016, 2019 और O365 सहित ऑफिस के सभी बिल्ड पर असर डालता है।

सभी चैनलों में बग को ठीक कर दिया गया है, लेकिन वितरण का समय इस बात पर निर्भर करेगा कि आप किस चैनल पर हैं।

2010, 2013, और 2016 के MSI और 2019 वॉल्यूम लाइसेंस के लिए, और O365 अर्ध-वार्षिक चैनल बनाता है, यह फिक्स दिसंबर पैच मंगलवार बिल्ड, दिसंबर 10 में होगा। O365, मासिक चैनल और अंदरूनी सूत्रों के लिए, यह तय हो जाएगा जब अक्टूबर कांटा जारी किया जाता है, तो वर्तमान में 24 नवंबर के लिए योजना बनाई गई है।

सेमी-एनुअल चैनल के लिए, बग को 11328.20468 में पेश किया गया था, जिसे 12 नवंबर को रिलीज़ किया गया था, लेकिन यह सभी को एक साथ रोल आउट नहीं करता है। यदि आप कर सकते हैं, तो आप 10 दिसंबर तक अपडेट जारी रखना चाहते हैं।

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

यानी, यदि आपके पास एक क्वेरी है जैसे:

UPDATE Table1 SET Table1.Field1 = "x" WHERE ([Table1].[Field2]=1);

फिर, एक नई क्वेरी (क्वेरी 1) को इस प्रकार परिभाषित करें:

Select * from Table1;

और अपनी मूल क्वेरी को इसमें अपडेट करें:

UPDATE Query1 SET Query1.Field1 = "x" WHERE ([Query1].[Field2]=1);

आधिकारिक पृष्ठ: प्रवेश त्रुटि: "प्रश्न भ्रष्ट है"


13
क्या आप वास्तव में सीधे चेहरे के साथ कह रहे हैं कि हम कई अनुप्रयोगों में तैनात कोड की हजारों-हज़ारों पंक्तियों में जाते हैं और सभी एसक्यूएल अपडेट को ठीक करते हैं जो डेटा की एक पंक्ति को अपडेट करते हैं? मुझे लगता है कि यदि आप आज एक नई क्वेरी लिख रहे हैं, और अभी, तो ऐसा समाधान संभव है। लेकिन मौजूदा कोड और अनुप्रयोगों के लिए यह विचार कि sql अपडेट को बदलना है, निश्चित रूप से किसी भी possbile तरीके से हल करने के लिए व्यावहारिक दृष्टिकोण नहीं है।
अल्बर्ट डी। कल्लल

5
@ AlbertD.Kallal, आपको MVP सूची से पता होना चाहिए, कि मैं इस मुद्दे के स्रोत के लिए स्पष्टीकरण का संदर्भ देता हूं। समस्या से कैसे निपटा जाए, यह वास्तव में आप पर निर्भर करता है और जो आपके परिदृश्य के अनुकूल हो सकता है। यहाँ वर्णित विधि कई में से एक है।
गुस्ताव

1
@ AlbertD.Kallal को टेबल का नाम नहीं बदलना चाहिए और पुराने टेबल-नाम के साथ QueryDefs बनाना चाहिए? (मैं परीक्षण करूँगा और यदि यह काम करता है तो स्क्रिप्ट पोस्ट करेगा)
ComputerVersteher

आप इसे बिना किसी प्रोग्रामिंग के साथ कर सकते हैं, उदाहरण के लिए टेबल "यूजर्स" को "यूजरस्ट" नाम दें और फिर क्वेरी नाम "यूजर्स" बनाएं - और फिर यह बिना किसी प्रोग्राम के काम करेगा ....
Zvi Redler

9
@ AlbertD.Kallal: मैं आपके दर्द को साझा करता हूं - अगर यह बग वीसी रनटाइम लाइब्रेरी को प्रभावित कर रहा था, तो मुझे नहीं लगता कि एमएस एक महीने के लिए तय करने में देरी करेगा और "फिर से लिखना, recompile और redeploy" वर्कअराउंड का सुझाव देगा। (निष्पक्ष होने के लिए, उन्होंने अगस्त के अंत में वीबीए मुद्दे को जल्दी से जारी किया और जारी किया।) लेकिन चलो दूत को गोली न दें - गुस्ताव एक एमएस कर्मचारी नहीं लगते हैं। चलो आशा करते हैं कि वे पुनर्विचार करें और पहले एक पैच जारी करें; आखिरकार, यह अन्य भाषाओं में लिखे गए अनुप्रयोगों को भी प्रभावित करता है जो सिर्फ एक्सेस डीबी इंजन का उपयोग करने के लिए होता है
हिनजी

15

अस्थायी रूप से इस समस्या को हल करने के लिए उपयोग में प्रवेश संस्करण पर निर्भर करता है:
Access 2010 की स्थापना रद्द करें KB4484127 अद्यतन
2013 की स्थापना रद्द करें स्थापना रद्द करें KB4484119
Access 2016 की स्थापना रद्द करें KB4484113 अद्यतन की स्थापना रद्द करें
2019 IF REQUIRED (tbc)। संस्करण 1808 से डाउनग्रेड (10352.20042 पर निर्माण) से संस्करण 1808 (बिल्ड 10351.20054) तक,
Office 365 ProPlus डाउनग्रेड संस्करण 1910 से (बिल्ड 12130.20344) पिछले निर्माण के लिए, https://support.microsoft.com/en-gb/help/2770432/ देखें। कैसे करने के लिए वापस लाएं करने वाली एक-पहले-संस्करण कार्यालय-से-2013 या कार्यालय-2016-CLIC


मैंने इसे अनइंस्टॉल कर दिया, लेकिन अगली बार जब मैंने विंडोज शुरू किया, तो इसे फिर से इंस्टॉल कर लिया। आप इसे पुनः स्थापित करने से कैसे रोकेंगे?
dsteele

5
@dsteele यदि MSI संस्करण और कोई WSUS, support.microsoft.com/en-us/help/3073930/… समस्या निवारण टूल का उपयोग करें । CTR को ऑफिस-अकाउंट-सेटिंग्स में अपडेट डिसेबल कर दें ..
ComputerVersteher

5

हम और हमारे ग्राहक पिछले दो दिनों से इससे जूझ रहे हैं और अंत में इस मुद्दे पर कुछ समाधानों के साथ विस्तार से चर्चा करने के लिए एक पत्र लिखा है: http://fmsinc.com/MicrosoftAccess/Errors/query_is_corrupt/

इसमें हमारे निष्कर्ष शामिल हैं जो स्थानीय तालिकाओं, लिंक किए गए एक्सेस तालिकाओं और यहां तक ​​कि SQL सर्वर तालिकाओं पर अद्यतन क्वेरी चलाते समय पहुंच समाधान को प्रभावित करते हैं।

यह ADO का उपयोग करके एक्सेस डेटाबेस से कनेक्ट करने के लिए Access डेटाबेस इंजन (ACE) का उपयोग करके गैर-Microsoft एक्सेस समाधानों को भी प्रभावित करता है। इसमें विजुअल स्टूडियो (WinForm) ऐप्स, VB6 ऐप और यहां तक ​​कि वे वेब साइटें शामिल हैं जो उन मशीनों पर एक्सेस डेटाबेस को अपडेट करती हैं जिनके पास कभी एक्सेस या ऑफिस स्थापित नहीं था।

यह क्रैश उन Microsoft ऐप्स को भी प्रभावित कर सकता है जो ACE का उपयोग करते हैं जैसे कि PowerBI, Power Query, SSMA, आदि (पुष्टि नहीं की गई), और निश्चित रूप से, एक्सेल, पॉवरपॉइंट या वर्ड जैसे अन्य प्रोग्राम एक्सेस डेटाबेस को संशोधित करने के लिए VBA का उपयोग करते हैं।

आपत्तिजनक सुरक्षा अपडेट की स्पष्ट स्थापना रद्द करने के अलावा, हम कुछ विकल्प भी शामिल करते हैं जब बाहरी ग्राहकों को जिनके पीसी आपके नियंत्रण से परे हैं, उन्हें अनुमति या वितरण के कारण अनइंस्टॉल करना संभव नहीं है। इसमें सभी अपडेट क्वेरी को बदलना और एक्सेस 2007 (रिटेल या रनटाइम) का उपयोग करके एक्सेस एप्लिकेशन को वितरित करना शामिल है क्योंकि उस संस्करण को सुरक्षा अपडेट से प्रभावित नहीं किया गया है।


4

स्वचालित रूप से सुझाए गए माइक्रोस्फ़ोट्स (तालिका के बजाय क्वेरी का उपयोग करके) को स्वचालित रूप से कार्यान्वित करने के लिए निम्न मॉड्यूल का उपयोग करें। सावधानी के तौर पर, पहले अपने डेटाबेस का बैकअप लें।

AddWorkaroundForCorruptedQueryIssue()वर्कअराउंड को जोड़ने और RemoveWorkaroundForCorruptedQueryIssue()इसे किसी भी समय निकालने के लिए उपयोग करें ।

Option Compare Database
Option Explicit

Private Const WorkaroundTableSuffix As String = "_Table"

Public Sub AddWorkaroundForCorruptedQueryIssue()
    On Error Resume Next

    With CurrentDb
        Dim tableDef As tableDef
        For Each tableDef In .tableDefs
            Dim isSystemTable As Boolean
            isSystemTable = tableDef.Attributes And dbSystemObject

            If Not EndsWith(tableDef.Name, WorkaroundTableSuffix) And Not isSystemTable Then
                Dim originalTableName As String
                originalTableName = tableDef.Name

                tableDef.Name = tableDef.Name & WorkaroundTableSuffix

                Call .CreateQueryDef(originalTableName, "select * from [" & tableDef.Name & "]")

                Debug.Print "OldTableName/NewQueryName" & vbTab & "[" & originalTableName & "]" & vbTab & _
                            "NewTableName" & vbTab & "[" & tableDef.Name & "]"
            End If
        Next
    End With
End Sub

Public Sub RemoveWorkaroundForCorruptedQueryIssue()
    On Error Resume Next

    With CurrentDb
        Dim tableDef As tableDef
        For Each tableDef In .tableDefs
            Dim isSystemTable As Boolean
            isSystemTable = tableDef.Attributes And dbSystemObject

            If EndsWith(tableDef.Name, WorkaroundTableSuffix) And Not isSystemTable Then
                Dim originalTableName As String
                originalTableName = Left(tableDef.Name, Len(tableDef.Name) - Len(WorkaroundTableSuffix))

                Dim workaroundTableName As String
                workaroundTableName = tableDef.Name

                Call .QueryDefs.Delete(originalTableName)
                tableDef.Name = originalTableName

                Debug.Print "OldTableName" & vbTab & "[" & workaroundTableName & "]" & vbTab & _
                            "NewTableName" & vbTab & "[" & tableDef.Name & "]" & vbTab & "(Query deleted)"
            End If
        Next
    End With
End Sub

'From https://excelrevisited.blogspot.com/2012/06/endswith.html
Private Function EndsWith(str As String, ending As String) As Boolean
     Dim endingLen As Integer
     endingLen = Len(ending)
     EndsWith = (Right(Trim(UCase(str)), endingLen) = UCase(ending))
End Function

आप मेरे GitHub भंडार पर नवीनतम कोड पा सकते हैं ।

AddWorkaroundForCorruptedQueryIssue()_Tableसभी गैर-सिस्टम तालिकाओं में प्रत्यय जोड़ देगा , उदाहरण के लिए तालिका IceCreamsका नाम बदल दिया जाएगा IceCreams_Table

यह मूल तालिका नाम का उपयोग करके एक नई क्वेरी भी बनाएगा, जो नामांकित तालिका के सभी स्तंभों का चयन करेगा। हमारे उदाहरण में, क्वेरी का नाम IceCreamsहोगा और SQL निष्पादित करेगा select * from [IceCreams_Table]

RemoveWorkaroundForCorruptedQueryIssue() रिवर्स एक्शन करता है।

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

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

मेरे मामले में, यह फिक्स काफी हद तक बिना किसी साइड इफेक्ट के काम करता है, मुझे बस मैन्युअल रूप से USysRibbons_Tableवापस नाम बदलने की आवश्यकता थी USysRibbons, क्योंकि मैंने इसे सिस्टम टेबल के रूप में चिह्नित नहीं किया था जब मैंने इसे अतीत में बनाया था।


मुझे आपके TableDef.Attributesउत्तर के साथ एक सिस्टमटेबल का निर्धारण करना पसंद है और इसे मेरे उत्तर में कॉपी करें;) और एक पूर्ववत कार्य एक अच्छा विचार है (लेकिन पुराने और नए नाम को तालिका में संग्रहित किया जाना चाहिए क्योंकि नाम के साथ प्रत्यय के बिना कोई तालिकाओं के आधार पर)। कुछ अन्य भाग दोषपूर्ण हैं (उदाहरण के लिए टेबल प्रत्यय के साथ समाप्त हो सकते हैं या नया नाम पहले से ही उपयोग में है या On Error Resume Nextबाद में त्रुटियों से निपटने के बिना)। क्या आप रबरडाकवीबीए जानते हैं ? यह Addin आपके कोड का निरीक्षण कर सकता है और अन्य सभी सुविधाओं के अलावा, बेहतरी के लिए अच्छे सुझाव देता है।
ComputerVersteher

और आपको उन बिंदुओं की ओर इशारा करना चाहिए जो हमारे दृष्टिकोण का कारण बन सकते हैं (देखें मेरे उत्तर पर @ टिप्पणियाँ देखें)
ComputerVersteher

आह, मैंने नहीं देखा कि यहाँ पहले से ही एक समान उत्तर था, इसलिए समीक्षा के लिए धन्यवाद! प्रत्यय को अपने आप में परिभाषित किया गया है, इसलिए इसे आसानी से बदला जा सकता है अगर पहले से ही प्रत्यय का उपयोग करने वाली कोई पूर्व-निर्धारित वस्तु है। अन्यथा स्क्रिप्ट के रूप में काम करता है, लेकिन किसी को भी अपनी व्यक्तिगत जरूरतों को संशोधित करने के लिए प्रोत्साहित महसूस करना चाहिए। स्क्रिप्ट का परीक्षण काफी बड़ी परियोजनाओं (400+ तालिकाओं) पर किया गया है, जिसमें बाहरी / बाहरी डेटाबेस से बाहरी / लिंक की गई सारणियाँ शामिल हैं। मुझे रबडक के बारे में नहीं पता था (केवल एमजेड-टूल्स के बारे में)। मैं निश्चित रूप से उन्हें बाहर की जाँच करेगा!
lauxjpn

3

PowerShell के माध्यम से इस प्रक्रिया को स्वचालित करने की तलाश करने वालों के लिए , यहां कुछ लिंक दिए गए हैं जो मुझे मददगार हो सकते हैं:

पता लगाना और अपमानजनक अद्यतन हटा दें

यहाँ एक PowerShell स्क्रिप्ट उपलब्ध है https://www.arcath.net/2017/09/office-update-remover जो एक विशिष्ट कार्यालय अद्यतन के लिए रजिस्ट्री की खोज करती है (एक केबी नंबर के रूप में पारित) और इसे कॉल का उपयोग करके हटा देती है msiexec.exe। यह स्क्रिप्ट उपयुक्त अद्यतन को निकालने के लिए कमांड बनाने के लिए रजिस्ट्री कुंजी से दोनों GUIDs को पार्स करती है।

एक परिवर्तन जिसका मैं सुझाव दूंगा कि केबी ४०११६२६ और अन्य कार्यालय अद्यतन (अतिरिक्त संदर्भ: https://docs.microsoft.com/en-us/windows/win32/msi/uninstalling-patches ) की स्थापना रद्द करने के/REBOOT=REALLYSUPPRESS तरीके के अनुसार उपयोग किया जाएगा । आपके द्वारा बनाई जा रही कमांड लाइन इस प्रकार है:

msiexec /i {90160000-0011-0000-0000-0000000FF1CE} MSIPATCHREMOVE={9894BF35-19C1-4C89-A683-D40E94D08C77} /qn REBOOT=REALLYSUPPRESS

स्क्रिप्ट चलाने की कमांड कुछ इस तरह दिखाई देगी:

OfficeUpdateRemover.ps1 -kb 4484127

अद्यतन स्थापित करने से रोकें

यहाँ अनुशंसित दृष्टिकोण अद्यतन को छुपाता हुआ प्रतीत होता है । जाहिर है यह मैन्युअल रूप से किया जा सकता है, लेकिन कुछ पॉवरशेल स्क्रिप्ट हैं जो स्वचालन के साथ मदद कर सकते हैं। यह लिंक: https://www.maketecheasier.com/hide-updates-in-windows-10/ विस्तार से प्रक्रिया का वर्णन करता है, लेकिन मैं इसे यहां संक्षेप में बताऊंगा।

  1. Windows अद्यतन PowerShell मॉड्यूल स्थापित करें ।
  2. KB नंबर द्वारा अपडेट छिपाने के लिए निम्न कमांड का उपयोग करें:

    छिपाएँ-वूपडेट -KBArticleID KB4484127

उम्मीद है कि यह वहाँ से किसी और को मदद मिलेगी।


3

एमएस-वर्कअराउंड के लिए VBA- स्क्रिप्ट:

कम से कम एमएसआई संस्करणों के लिए, यदि संभव हो तो (यदि मेरे कोड की कोशिश नहीं की जाती है), तो छोटी गाड़ी अद्यतन को हटाने की सिफारिश की जाती है। जवाब देखें https://stackoverflow.com/a/58833831/9439330

CTR (क्लिक-टू-रन) संस्करणों के लिए, आपको सभी Office नवंबर-अपडेट्स को निकालना होगा, जो गंभीर सुरक्षा समस्याओं का कारण हो सकता है (यदि कोई महत्वपूर्ण सुधार हटा दिया जाएगा तो निश्चित नहीं)।

@ एरिक की टिप्पणियों से:

  • यदि आप Table.Tablenameप्रपत्रों को बाइंड करने के लिए उपयोग करते हैं, तो वे अनबाउंड हो जाते हैं क्योंकि पूर्व तालिका-नाम अब एक क्वेरी-नाम है!
  • OpenRecordSet(FormerTableNowAQuery, dbOpenTable) विफल हो जाएगा (इसकी एक क्वेरी के रूप में, अब एक तालिका नहीं)

सावधान! बस Office 2013 x86 CTR नो वारंटी पर Northwind.accdb के खिलाफ त्वरित परीक्षण किया गया !

Private Sub RenameTablesAndCreateQueryDefs()
With CurrentDb
    Dim tdf As DAO.TableDef
    For Each tdf In .TableDefs

        Dim oldName As String
        oldName = tdf.Name

        If Not (tdf.Attributes And dbSystemObject) Then 'credit to @lauxjpn for better check for system-tables
            Dim AllFields As String
            AllFields = vbNullString

            Dim fld As DAO.Field

            For Each fld In tdf.Fields
                AllFields = AllFields & "[" & fld.Name & "], "
            Next fld

            AllFields = Left(AllFields, Len(AllFields) - 2)
            Dim newName As String
            newName = oldName

            On Error Resume Next
            Do
                Err.Clear
                newName = newName & "_"
                tdf.Name = newName
            Loop While Err.Number = 3012
            On Error GoTo 0

            Dim qdf As DAO.QueryDef

            Set qdf = .CreateQueryDef(oldName)
            qdf.SQL = "SELECT " & AllFields & " FROM [" & newName & "]"
        End If
    Next
    .TableDefs.Refresh

End With
End Sub

परीक्षण के लिए:

Private Sub TestError()
With CurrentDb
    .Execute "Update customers Set City = 'a' Where 1=1", dbFailOnError 'works

    .Execute "Update customers_ Set City = 'b' Where 1=1", dbFailOnError 'fails
End With
End Sub

4
ध्यान दें कि यह वर्कअराउंड टेबल के लिए बाध्य सबफॉर्म को बर्बाद कर देगा (प्रश्नों के लिए रिबाउंड करने की आवश्यकता होगी) और कोड एक हार्डकोड किए गए टेबल नाम के साथ tabledefs के साथ काम कर रहा है। बहुत सावधानी के साथ उपयोग करें, ऑड्स हैं यह एक बग केवल दो नए बनाने के लिए एक बग को ठीक करता है जो आपके आवेदन पर निर्भर करता है।
एरिक

@ErikA पाठ्यक्रम केवल एक समाधान है, लेकिन मुझे लगता है बाध्य कर सकते हैं Inventory to reorder Subform for Homeकरने के लिए Inventoryतालिका में Homeफार्म, समस्याओं के बिना। यहां तक ​​कि यह तालिकाओं के बजाय प्रश्नों को रूपों में बाँधने के लिए नहीं है (तालिका की तरह बाध्यकारी नहीं है Select * From table?)।
ComputerVersteher

2
यदि मैं किसी तालिका के लिए एक सबफ़ॉर्म बाँधता हूं, तो मैं आमतौर पर इसका उपयोग करता हूं Table.TableName अंकन । यदि तुम करोSELECT * FROM TableName बजाय हैं, तो आप निश्चित रूप से ठीक हैं। लेकिन अगर आप उपयोग करते हैं Table.TableName, तो टेबल को नाम बदलने पर आपका सबफॉर्म अनबाउंड हो जाएगा।
एरिक

@ एरिक: यह सच है। ऐसा करने से कोई लाभ?
ComputerVersteher

3
जहां तक ​​मुझे पता है, इसके अलावा यह अधिक संक्षिप्त नहीं है। TableDefs!MyTableName.OpenRecordset(dbOpenTable)हालाँकि, इसका पर्याप्त लाभ है , हालांकि (सूचकांक मांग का समर्थन), जिसका मैं भी उपयोग करता हूँ और आपके दृष्टिकोण के साथ त्रुटियां भी पैदा करेगा
एरिक

2

मैंने एक सहायक समारोह के साथ currentDb.Executeऔर उसकी जगह ले ली Docmd.RunSQL। यदि कोई अद्यतन विवरण में केवल एक तालिका है, तो SQL कथन को पूर्व-संसाधित और बदल सकता है। मेरे पास पहले से ही dual(एकल पंक्ति, एकल स्तंभ) तालिका है, इसलिए मैं एक नकली विकल्प के साथ गया था।

नोट : यह आपकी क्वेरी ऑब्जेक्ट नहीं बदलेगा। यह केवल VBA के माध्यम से SQL निष्पादन में मदद करेगा।If you would like to change your query objects, use FnQueryReplaceSingleTableUpdateStatements and update your sql in each of your querydefs. Shouldn't be a problem either.

यह सिर्फ एक अवधारणा है (If it's a single table update modify the sql before execution)। अपनी आवश्यकताओं के अनुसार इसे अपनाएं। यह पद्धति प्रत्येक तालिका के लिए प्रतिस्थापन प्रश्न नहीं बनाती है (जो कि सबसे आसान तरीका हो सकता है, लेकिन इसकी अपनी कमियां हैं। अर्थात प्रदर्शन समस्याएं)

+ अंक: एमएस बग को ठीक करने के बाद भी आप इस सहायक का उपयोग करना जारी रख सकते हैं यह कुछ भी नहीं बदलेगा। मामले में, भविष्य एक और समस्या लाता है, आप pre-processएक जगह अपने SQL के लिए तैयार हैं । मैं अपडेट विधि को अनइंस्टॉल करने के लिए नहीं गया था क्योंकि इसके लिए एडमिन एक्सेस + की आवश्यकता होती है, सही वर्जन पर सभी को प्राप्त करने के लिए बहुत लंबा समय लगता है + फिर भी अगर आप अनइंस्टॉल करते हैं, तो कुछ एंड यूजर्स की ग्रुप पॉलिसी नवीनतम अपडेट को फिर से इंस्टॉल करती है। आप उसी समस्या पर वापस आ रहे हैं।

यदि आपके पास स्रोत-कोड तक पहुंच है, use this methodऔर आप 100% सुनिश्चित हैं कि कोई एंड्यूसर समस्या नहीं है।

Public Function Execute(Query As String, Optional Options As Variant)
    'Direct replacement for currentDb.Execute

    If IsBlank(Query) Then Exit Function

    'invalid db options remove
    If Not IsMissing(Options) Then
        If (Options = True) Then
            'DoCmd RunSql query,True ' True should fail so transactions can be reverted
            'We are only doing this so DoCmd.RunSQL query, true can be directly replaced by helper.Execute query, true.
            Options = dbFailOnError
        End If
    End If

    'Preprocessing the sql command to remove single table updates
    Query = FnQueryReplaceSingleTableUpdateStatements(Query)

    'Execute the command
    If ((Not IsMissing(Options)) And (CLng(Options) > 0)) Then
        currentDb.Execute Query, Options
    Else
        currentDb.Execute Query
    End If

End Function

Public Function FnQueryReplaceSingleTableUpdateStatements(Query As String) As String
    ' ON November 2019 Microsoft released a buggy security update that affected single table updates.
    '/programming/58832269/getting-error-3340-query-is-corrupt-while-executing-queries-docmd-runsql

    Dim singleTableUpdate   As String
    Dim tableName           As String

    Const updateWord        As String = "update"
    Const setWord           As String = "set"

    If IsBlank(Query) Then Exit Function

    'Find the update statement between UPDATE ... SET
    singleTableUpdate = FnQueryContainsSingleTableUpdate(Query)

    'do we have any match? if any match found, that needs to be preprocessed
    If Not (IsBlank(singleTableUpdate)) Then

        'Remove UPDATe keyword
        If (VBA.Left(singleTableUpdate, Len(updateWord)) = updateWord) Then
            tableName = VBA.Right(singleTableUpdate, Len(singleTableUpdate) - Len(updateWord))
        End If

        'Remove SET keyword
        If (VBA.Right(tableName, Len(setWord)) = setWord) Then
            tableName = VBA.Left(tableName, Len(tableName) - Len(setWord))
        End If

        'Decide which method you want to go for. SingleRow table or Select?
        'I'm going with a fake/dual table.
        'If you are going with update (select * from T) as T, make sure table aliases are correctly assigned.
        tableName = gDll.sFormat("UPDATE {0},{1} SET ", tableName, ModTableNames.FakeTableName)

        'replace the query with the new statement
        Query = vba.Replace(Query, singleTableUpdate, tableName, compare:=vbDatabaseCompare, Count:=1)

    End If

    FnQueryReplaceSingleTableUpdateStatements = Query

End Function

Public Function FnQueryContainsSingleTableUpdate(Query As String) As String
    'Returns the update ... SET statment if it contains only one table.

    FnQueryContainsSingleTableUpdate = ""
    If IsBlank(Query) Then Exit Function

    Dim pattern     As String
    Dim firstMatch  As String

    'Get the pattern from your settings repository or hardcode it.
    pattern = "(update)+(\w|\s(?!join))*set"

    FnQueryContainsSingleTableUpdate = FN_REGEX_GET_FIRST_MATCH(Query, pattern, isGlobal:=True, isMultiline:=True, doIgnoreCase:=True)

End Function

Public Function FN_REGEX_GET_FIRST_MATCH(iText As String, iPattern As String, Optional isGlobal As Boolean = True, Optional isMultiline As Boolean = True, Optional doIgnoreCase As Boolean = True) As String
'Returns first match or ""

    If IsBlank(iText) Then Exit Function
    If IsBlank(iPattern) Then Exit Function

    Dim objRegex    As Object
    Dim allMatches  As Variant
    Dim I           As Long

    FN_REGEX_GET_FIRST_MATCH = ""

   On Error GoTo FN_REGEX_GET_FIRST_MATCH_Error

    Set objRegex = CreateObject("vbscript.regexp")
    With objRegex
        .Multiline = isMultiline
        .Global = isGlobal
        .IgnoreCase = doIgnoreCase
        .pattern = iPattern

        If .test(iText) Then
            Set allMatches = .Execute(iText)
            If allMatches.Count > 0 Then
                FN_REGEX_GET_FIRST_MATCH = allMatches.item(0)
            End If
        End If
    End With

    Set objRegex = Nothing

   On Error GoTo 0
   Exit Function

FN_REGEX_GET_FIRST_MATCH_Error:
    FN_REGEX_GET_FIRST_MATCH = ""

End Function

अब बस CTRL+F

खोजें और बदलें docmd.RunSQLके साथhelper.Execute

खोजें और बदलें [currentdb|dbengine|or your dbobject].executeके साथhelper.execute

मज़े करो!


0

ठीक है, मैं यहाँ भी झंकार करूँगा, क्योंकि भले ही यह बग ठीक कर लिया गया हो, लेकिन यह फिक्स अभी तक पूरी तरह से विभिन्न उद्यमों के माध्यम से पूरी तरह से आबाद है जहाँ अंत उपयोगकर्ता अपडेट नहीं कर सकते (जैसे मेरे नियोक्ता ...)

यहाँ के लिए मेरा समाधान है DoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"। बस नीचे दिए गए कोड में अपमानजनक क्वेरी और ड्रॉप करें।

    'DoCmd.RunSQL "UPDATE users SET uname= 'bob' WHERE usercode=1"
    Dim rst As DAO.Recordset
    Set rst = CurrentDb.OpenRecordset("users")
    rst.MoveLast
    rst.MoveFirst
    rst.FindFirst "[usercode] = 1" 'note: if field is text, use "[usercode] = '1'"
    rst.Edit
    rst![uname] = "bob"
    rst.Update
    rst.Close
    Set rst = Nothing

मैं यह नहीं कह सकता कि यह सुंदर है, लेकिन यह काम पूरा कर लेता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.