मैं sql स्क्रिप्ट में "निकट मौजूदा कनेक्शन" कैसे निर्दिष्ट कर सकता हूं


153

मैं SQL Server 2008 में अपने स्कीमा पर सक्रिय विकास कर रहा हूं और बार-बार मेरा ड्रॉप / डेटाबेस स्क्रिप्ट बनाना चाहता हूं। जब मैं दौड़ता हूं

USE [master]
GO

IF  EXISTS (SELECT name FROM sys.databases WHERE name = N'MyDatabase')
DROP DATABASE [MyDatabase]
GO

मुझे अक्सर यह त्रुटि मिलती है

Msg 3702, Level 16, State 4, Line 3
Cannot drop database "MyDatabase" because it is currently in use.

यदि आप ऑब्जेक्ट एक्सप्लोरर फलक में डेटाबेस पर राइट क्लिक करते हैं और संदर्भ मेनू से हटाएं कार्य का चयन करते हैं, तो एक चेकबॉक्स है जो "मौजूदा कनेक्शन बंद करें" है

क्या मेरी स्क्रिप्ट में इस विकल्प को निर्दिष्ट करने का कोई तरीका है?

जवाबों:


247

आप सभी को डिस्कनेक्ट कर सकते हैं और उनके साथ अपना लेन-देन वापस कर सकते हैं:

alter database [MyDatbase] set single_user with rollback immediate

उसके बाद, आप डेटाबेस को सुरक्षित रूप से छोड़ सकते हैं :)


8
मैंने इसका उपयोग किया है लेकिन अक्सर सोचता हूं कि क्या किसी अन्य उपयोगकर्ता के लिए "एकल उपयोगकर्ता" के रूप में अवसर की एक खिड़की थी - क्या यह संभव है? संभावित विकल्प बदल रहा है [MyDatabaseName] रोलमार्क के साथ ऑफ़लाइन सेट
क्रिस्टन

9
Single_user में उपयोगकर्ता आप हैं; जब तक आप एकल उपयोगकर्ता मोड सेट करने के बाद डिस्कनेक्ट नहीं करते हैं। फिर एक (1) अन्य उपयोगकर्ता लॉग ऑन कर सकता है।
23

एक बार जब आप डेटाबेस को गिरा देते हैं, यदि आप एक ही नाम के साथ एक नया बनाते हैं तो मुझे लगता है कि यह मल्टी_यूज़र मोड में होगा? इसलिए आपको दौड़ने की ज़रूरत नहीं है: डेटाबेस को बदल दें [MyDatbase] सेट करें mult_user
AndyM

@AndyM: हाँ, मल्टी_सर शायद डिफ़ॉल्ट है
एंडोमर

2
@Kristen आपके दृष्टिकोण का उपयोग कर मैंने पाया कि sql सर्वर mdf और ldf फ़ाइलों को नहीं हटाता है। एकल_युसर मेरे लिए ठीक काम करता है (मुझे लगातार डीबी को फिर से बनाने की आवश्यकता है)।
2xMax

36

प्रबंधन स्टूडियो पर जाएं और आपके द्वारा वर्णित सब कुछ करें, केवल ओके पर क्लिक करने के बजाय स्क्रिप्ट पर क्लिक करें। यह उस कोड को दिखाएगा जो वह चलाएगा जिसे आप अपनी स्क्रिप्ट में शामिल कर सकते हैं।

इस मामले में, आप चाहते हैं:

ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

1
मैं इस सवाल का जवाब देने की कोशिश करने जा रहा था कि आप क्या वर्णन करते हैं ("डिलीट डेटाबेस" डायलॉग को स्क्रिप्ट कर रहे हैं), लेकिन यदि आप "नज़दीकी मौजूदा कनेक्शन" चेकबॉक्स को चेक करते हैं, तो यह स्क्रिप्ट में परिवर्तन नहीं करता है
मैट हैमिल्टन

विज़ार्ड से उत्पन्न स्क्रिप्ट में मेरे लिए 'परिवर्तन डेटाबेस' लाइन शामिल थी।
निक

अजीब। कौन सा प्रबंधन स्टूडियो संस्करण? मैं 2008 x64 पर हूं।
मैट हैमिल्टन

मुझे भी: Microsoft SQL सर्वर प्रबंधन स्टूडियो 10.0.1600.22 ऑपरेटिंग सिस्टम 6.0.6001
निक

8
ALTER DATABASE के साथ भी यही समस्या थी कि इसे स्क्रिप्ट में नहीं जोड़ा गया। मेरे लिए इसे स्क्रिप्ट में शामिल करने के लिए मुझे यह सुनिश्चित करना था कि स्क्रिप्ट के उत्पन्न होने पर मुझे उस डेटाबेस के खिलाफ एक प्रक्रिया (सक्रिय कनेक्शन) चलनी थी।
गिलबर्ट

16

ALTER DATABASE SET प्रलेखन के अनुसार , अभी भी एक संभावना है कि SINGLE_USER मोड पर डेटाबेस सेट करने के बाद आप उस डेटाबेस तक नहीं पहुँच पाएंगे:

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

इसलिए, मौजूदा कनेक्शन वाले डेटाबेस को छोड़ने के लिए एक पूरी स्क्रिप्ट इस तरह दिख सकती है:

DECLARE @dbId int
DECLARE @isStatAsyncOn bit
DECLARE @jobId int
DECLARE @sqlString nvarchar(500)

SELECT @dbId = database_id,
       @isStatAsyncOn = is_auto_update_stats_async_on
FROM sys.databases
WHERE name = 'db_name'

IF @isStatAsyncOn = 1
BEGIN
    ALTER DATABASE [db_name] SET  AUTO_UPDATE_STATISTICS_ASYNC OFF

    -- kill running jobs
    DECLARE jobsCursor CURSOR FOR
    SELECT job_id
    FROM sys.dm_exec_background_job_queue
    WHERE database_id = @dbId

    OPEN jobsCursor

    FETCH NEXT FROM jobsCursor INTO @jobId
    WHILE @@FETCH_STATUS = 0
    BEGIN
        set @sqlString = 'KILL STATS JOB ' + STR(@jobId)
        EXECUTE sp_executesql @sqlString
        FETCH NEXT FROM jobsCursor INTO @jobId
    END

    CLOSE jobsCursor
    DEALLOCATE jobsCursor
END

ALTER DATABASE [db_name] SET  SINGLE_USER WITH ROLLBACK IMMEDIATE

DROP DATABASE [db_name]

3

मुझे पता है कि बहुत देर हो चुकी है, लेकिन हो सकता है कि यह किसी की मदद करे। इसका उपयोग करने पर अपने डेटाबेस को ऑफ़लाइन ले जाएं

ALTER DATABASE dbname SET OFFLINE

टिप्पणी: "ऑफ़लाइन डेटाबेस को छोड़ दें" के बाद, फ़ाइल Mdf को गिराया नहीं गया! stackoverflow.com/questions/33154141/…
bob217

2

मैंने कोशिश की कि hgmnz ने SQL Server 2012 पर क्या कहा।

प्रबंधन ने मुझे बनाया:

EXEC msdb.dbo.sp_delete_database_backuphistory @database_name = N'MyDataBase'
GO
USE [master]
GO
/****** Object:  Database [MyDataBase]    Script Date: 09/09/2014 15:58:46 ******/
DROP DATABASE [MyDataBase]
GO

4
यह सक्रिय कनेक्शन को बंद नहीं करेगा।
जेन्स

सुनिश्चित करें कि आपने "मौजूदा कनेक्शन बंद करें" चेक किया है; यदि आप दान करते हैं तो ROLLBACK IMMEDIATEकथन को शामिल किया जाएगा। sp_delete_database_backuphistory"हटाएँ बैकअप और डेटाबेस के लिए इतिहास जानकारी को बहाल" जाँच से आता है।
क्रिश्चियन.के

"मौजूदा कनेक्शन बंद करें" की जाँच करने ALTER DATABASE SET SINGLE_USER ...से कोई चालू कनेक्शन बंद होने की स्थिति उत्पन्न नहीं होती है ।
आह्वान

-1

अपने डेटाबेस को छोड़ने के लिए इस C # कोड को आज़माएं

सार्वजनिक स्थैतिक शून्य DropDat डेटाबेस (स्ट्रिंग डेटाबेस) {

        string sql =  "ALTER DATABASE "  + dataBase + "SET SINGLE_USER WITH ROLLBACK IMMEDIATE" ;

        using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings["DBRestore"].ConnectionString))
        {
            connection.Open();
            using (System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, connection))
            {
                command.CommandType = CommandType.Text;
                command.CommandTimeout = 7200;
                command.ExecuteNonQuery();
            }
            sql = "DROP DATABASE " + dataBase;
            using (System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand(sql, connection))
            {
                command.CommandType = CommandType.Text;
                command.CommandTimeout = 7200;
                command.ExecuteNonQuery();
            }
        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.