LocalDB v14 mdf फ़ाइलों के लिए गलत पथ बनाता है


34

हाल ही में, मैंने SQL Server एक्सप्रेस इंस्टॉलर और इस निर्देश का उपयोग करके संस्करण 13 से 14 तक लोकलडीबी को अपग्रेड किया । स्थापना के बाद, मैंने 13 संस्करण के मौजूदा डिफ़ॉल्ट उदाहरण (MSSQLLOCALDB) को रोक दिया और एक नया बनाया, जो स्वचालित रूप से v14.0.1000 सर्वर इंजन का उपयोग करता था।

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

क्रिएट फ़ील को ऑपरेटिंग सिस्टम एरर 5 मिला (एक्सेस से वंचित किया गया है) भौतिक फ़ाइल 'C: \ Users \ kepflDBd0811493e18b46febf980ffb8029482.mdf' खोलने या बनाने का प्रयास करते समय

विचित्र बात यह है कि mdf फ़ाइल के लिए लक्ष्य पथ गलत है, C: \ Users \ kepfl और DBd0811493e18b46febf980ffb8029482a.df (जो एकल परीक्षण के लिए यादृच्छिक डेटाबेस नाम है) के बीच एक बैकस्लैश गायब है । डेटाबेस साधारण कमांड के माध्यम से बनाए जाते हैं CREATE DATABASE [databaseName]- यहां कुछ खास नहीं है।

SSMS में, मैं देखता हूं कि डेटा, लॉग और बैकअप के लिए लक्ष्य स्थान निम्नलिखित हैं:

LocalDB लक्ष्य स्थानों

हालाँकि, जब मैं स्थान को अपडेट करने का प्रयास करता हूं, तो मुझे एक और त्रुटि संदेश मिलता है:

अपडेट करने का प्रयास करते समय त्रुटि संदेश

मैं डिफ़ॉल्ट स्थानों को कैसे अपडेट कर सकता हूं ताकि लोकलडीबी फिर से डेटाबेस बनाने में सक्षम हो? यह स्पष्ट है कि LocalDB डिफ़ॉल्ट स्थान निर्देशिका और डेटाबेस फ़ाइल नाम को सही ढंग से संयोजित नहीं करता है - क्या कोई रजिस्ट्री प्रविष्टि है जिसे मैं संपादित कर सकता हूं? या फिर कुछ और?

डौग के उत्तर और सीपिक की टिप्पणी के बाद अपडेट करें

इस Stackoverflow प्रश्न के अनुसार , डिफ़ॉल्ट स्थान को भी रजिस्ट्री के माध्यम से परिवर्तनशील होना चाहिए। हालाँकि, यदि मैं संबंधित कुंजियाँ "DefaultData", "DefaultLog" और "BackupDirectory" खोजने का प्रयास करता हूँ, तो मैं उन्हें अपनी रजिस्ट्री में नहीं ढूँढ सकता। क्या SQL सर्वर v14 ने इन रजिस्ट्री कुंजियों का नाम बदला, या रजिस्ट्री से इन सूचनाओं को स्थानांतरित किया?


FYI करें, मैं SSMS को व्यवस्थापक मोड में चलाते समय डेटाबेस डिफ़ॉल्ट स्थानों को भी अपडेट नहीं कर सकता।
feO2x 11

1
कृपया मेरे उत्तर में अद्यतन देखें। इस बग को CU6 के रूप में तय किया गया है, जो अप्रैल के मध्य में जारी किया गया था ..
सोलोमन रुट्ज़की

जवाबों:


21

अद्यतन करें

SQL Server 2017 के लिए CU 6 के रूप में, यह बग ठीक किया गया है। अब निम्नलिखित सफलतापूर्वक निष्पादित करना संभव है:

CREATE DATABASE [CreateDatabaseTest];
DROP DATABASE [CreateDatabaseTest];

समस्या, और तथ्य यह है कि यह CU6 में तय किया गया है, निम्नलिखित KB आलेख में प्रलेखित है:
FIX: SQL सर्वर 2017 एक्सप्रेस LocalDB में डेटाबेस बनाने का प्रयास करते समय "प्रवेश निषेध है" त्रुटि

संचयी अद्यतन प्राप्त करने के लिए, कृपया निम्न पृष्ठ पर जाएँ और शीर्ष (यानी नवीनतम) बिल्ड को पकड़ें, जो कि CU6 की तुलना में नया हो सकता है जब आप इसे देखते हैं:

SQL सर्वर 2017 बिल्ड संस्करण


SQL सर्वर 2017 CU6 (जारी 2018-04-17) के रूप में जानकारी प्राप्त करें।

संयुक्त पथ + फ़ाइल नाम में एक बैकस्लैश की कमी SQL सर्वर 2017 के साथ एक बग प्रतीत होती है। मैं बस इसे खुद में चलाता था। मैंने सी केDefaultData लिए एक स्ट्रिंग मान जोड़ने के लिए रजिस्ट्री को संपादित करने का भी प्रयास किया : निम्न उपयोगकर्ताओं दोनों में C: \ Users \ MyAccountName \ के लिए (3 डिफ़ॉल्ट पथ किसी भी स्थानीयडीबी रजिस्ट्री कुंजियों में नहीं हैं जिन्हें मैंने देखा था):

  • कंप्यूटर \ HKEY_CURRENT_USER \ Software \ Microsoft \ Microsoft SQL सर्वर \ UserInstances \ {कुछ-GUID- मूल्य}
  • कंप्यूटर \ HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Microsoft SQL सर्वर \ MSSQL14E। LOCALDB \ MSSQLServer

और हां, मैंने शटडाउन किया और फिर से दोनों प्रयासों में लोकलडीबी का उदाहरण दिया।

हालाँकि, मुझे विश्वास नहीं है कि डिफ़ॉल्ट पथों को बदलने में सक्षम नहीं होना एक बग है क्योंकि यह केवल खराब प्रलेखन और खराब त्रुटि हैंडलिंग हो सकता है। मैं ऐसा इसलिए कहता हूं क्योंकि मैंने सिर्फ SQL Server LocalDB संस्करणों के लिए डिफ़ॉल्ट स्थानों को संपादित करने की कोशिश की 2014, 2016 और 2017, और सभी में एक ही त्रुटि हुई, जो अपने आप में विषम होने के कारण है RegCreateKeyEx(), जो रजिस्ट्री के साथ काम करना चाहिए और फाइल सिस्टम नहीं।

उपयोग करने के लिए फ़ाइलों को निर्दिष्ट किए बिना एक नया डेटाबेस बनाते समय बैकस्लैश की कमी के कारण पथ को बदलने में सक्षम नहीं होना दुर्भाग्यपूर्ण है। हालाँकि, मैं पूर्ण CREATE DATABASEसिंटैक्स का उपयोग करके एक नया डेटाबेस बनाने में सक्षम था :

CREATE DATABASE [XXXXX]
 CONTAINMENT = NONE
 ON PRIMARY 
( NAME = N'XXXXX_sys', FILENAME = N'C:\Users\MyAccountName\XXXXX_sys.mdf',
  SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB ), 
 FILEGROUP [Tables] DEFAULT
( NAME = N'XXXXX_data', FILENAME = N'C:\Users\MyAccountName\XXXXX_data.ndf',
  SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 LOG ON 
( NAME = N'XXXXX_log', FILENAME = N'C:\Users\MyAccountName\XXXXX_log.ldf',
  SIZE = 8192KB , MAXSIZE = UNLIMITED, FILEGROWTH = 65536KB )
 COLLATE Latin1_General_100_CS_AS_KS_WS_SC;
GO

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

@tgharold कृपया मेरे उत्तर के शीर्ष पर अद्यतन देखें। यह बग बहुत हाल ही में नए CU6 पैच :-) में तय किया गया था।
सोलोमन रटज़की

5

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

DECLARE @databaseName NVARCHAR(MAX) = 'MyDatabase'

DECLARE @dataFilePath NVARCHAR(MAX) = CAST(SERVERPROPERTY('InstanceDefaultDataPath') AS NVARCHAR) 
    + FORMATMESSAGE('\%s.mdf', @databaseName)

DECLARE @sql NVARCHAR(MAX) = FORMATMESSAGE(
    'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = ''%s'' )', 
    quotename(@databaseName), quotename(@databaseName), @dataFilePath
)

EXEC (@sql)

यह डायनेमिक sql का उपयोग करता है और यह बिल्कुल सुंदर नहीं है, लेकिन यह तब तक काम करता है जब तक कि समस्या का आधिकारिक निर्धारण न हो।


1
दिलचस्प। यह हो सकता है 2 स्थानांतरित करने के लिए थोड़ा बेहतर हो QUOTENAMEके 2 परम करने के लिए FORMATMESSAGEऔर फ़ाइल पथ को दोहरे उद्धरण चिह्नों डाल: FORMATMESSAGE(N'CREATE DATABASE %s ON PRIMARY ( NAME = %s, FILENAME = "%s" )', QUOTENAME(@databaseName), QUOTENAME(@databaseName), @dataFilePath);। लेकिन ऐसा लगता है कि आपके पास यह काम है, इसलिए इस दृष्टिकोण के लिए +1 करें। नाम को हार्ड-कोडिंग या पथ में पास करने के लिए अभी भी एक मामला है: जब आप USERPROFILEरूट का उपयोग नहीं करना चाहते हैं । लेकिन आप यहाँ के लिए अनुमति दे सकते हैं और InstanceDefaultDataPathयदि डिफ़ॉल्ट हो तो @Path IS NULL। :-)
सोलोमन रटज़की

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

4

मैं इस मुद्दे का भी सामना कर रहा हूं। मुझे जो एकमात्र हल मिला, वह होगा c:\Users\सबको (या ऐसा ही कुछ) लिखने की पहुँच प्रदान करना और इसे जहाँ चाहे वहाँ mdf फाइल बनाने दें।


1
धन्यवाद, यह मेरे लिए भी हल कर दिया! यह वर्कअराउंड बेकार है, लेकिन यह केवल हमारे स्थानीय बिल्ड सर्वर पर है, इसलिए मुझे अतिरिक्त उपयोगकर्ता अधिकारों की परवाह नहीं है।
हेंस साचसेनहोफर

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

सभी के लिए ग्रांट लिखना मुझे बहुत बुरा लगता है
राफेल

@ राफेल: क्यों? आपके पास देव बॉक्स पर कई उपयोगकर्ता हैं? और तुम किस पर भरोसा नहीं करते?
अबिशशेव '’१at

2

इस समस्या के आपके संक्षिप्त स्पष्टीकरण के लिए धन्यवाद। मैं कल इसी मुद्दे पर भागा। मुझे अभी भी एक स्थायी समाधान नहीं मिला है, लेकिन यहां मेरा वर्तमान समाधान है।

मैं डेटाबेस बनाने के लिए Database.EnsureCreated () फ़ंक्शन का उपयोग कर रहा हूं।

' AttachDBFilename = ' सेटिंग शामिल करने के लिए कनेक्शन स्ट्रिंग सेट करें ।

Server=(LocalDB)\\MSSQLLocalDB;Database=ExploreCalifornia;AttachDbFilename=.\\ExploreCalifornia.mdf;Trusted_Connection=True;MultipleActiveResultSets=true

एप्लिकेशन चलाएँ। यह एक त्रुटि उत्पन्न करेगा:

डेटाबेस 'explCalifornia' के रूप में फ़ाइल '। \ ExplCalifornia.mdf' संलग्न नहीं कर सकता।

लेकिन यह डेटाबेस बनाएगा।

उसके बाद, कनेक्शन स्ट्रिंग बदलें और ' AttachDBFilename = ' निकालें ।

 Server=(localdb)\\MSSQLLocalDB;Database=ExploreCalifornia;Trusted_Connection=True;MultipleActiveResultSets=true

मैंने एप्लिकेशन को फिर से चलाया जिसमें कोई त्रुटि नहीं थी और तालिकाएँ बनाई गई थीं।


कुछ सवालों के जवाब: पहला, सिर्फ यह सुनिश्चित करने के लिए - आपको शुरू में एक (प्रवेश निषेध) त्रुटि मिल रही थी, और इसने यह हल किया, सही? दूसरा - एसक्यूएल सर्वर मैनेजमेंट स्टूडियो आईपी द्वारा उल्लिखित एकमात्र एप्लिकेशन है, और यह आपके द्वारा वहां से की गई किसी चीज की तरह नहीं है - आपने यह सब किस एप्लीकेशन से किया है?
RDFozz

आपके उत्तर के लिए धन्यवाद, लेकिन यह वास्तव में मेरी समस्या का समाधान नहीं करता है। मेरा परीक्षण कोड CREATE DATABASE [databasename]LocalDB के खिलाफ एक सरल के साथ एक नया डेटाबेस बनाता है और यह बहुत ही समस्या पैदा कर रहा है क्योंकि LocalDB गलत तरीके से उत्पन्न डेटाबेस निर्देशिका को बेतरतीब ढंग से उत्पन्न डेटाबेस नाम (पैराग्राफ 3 और मेरे प्रश्न के 4 देखें) के साथ गलत करता है । मुझे डिफ़ॉल्ट स्थानों को ठीक करने के लिए एक तरीका चाहिए ताकि यह समस्वरता समस्या उत्पन्न न हो।
feO2x

वर्तमान में, मैं SQL / DDL के माध्यम से एक डेटाबेस बनाने में सक्षम नहीं हूँ। इससे कोई फर्क नहीं पड़ता कि मैं SSMS के माध्यम से, या कोड से, या कहीं और भी स्टेटमेंट चलाता हूं, क्योंकि LocalDB हमेशा उपयोगकर्ता निर्देशिका में सीधे डेटाबेस बनाने की कोशिश करता है (जो पूरी तरह से गलत है, इस निर्देशिका में कोई भी फाइल मौजूद नहीं है) ।
feO2x

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