SQL betiğinde "mevcut bağlantıları kapat" ı nasıl belirtebilirim?


153

SQL Server 2008'deki şemam üzerinde etkin geliştirme yapıyorum ve sık sık bırak / veritabanı komut dosyası oluştur'u yeniden çalıştırmak istiyorum. Koştuğumda

USE [master]
GO

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

Sık sık bu hatayı alıyorum

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

Nesne gezgini bölmesinde veritabanını sağ tıklatıp bağlam menüsünden Sil görevini seçerseniz, "varolan bağlantıları kapatmak" için bir onay kutusu bulunur.

Komut dosyamda bu seçeneği belirtmenin bir yolu var mı?

Yanıtlar:


247

Herkesin bağlantısını kesebilir ve işlemlerini aşağıdakilerle geri alabilirsiniz:

alter database [MyDatbase] set single_user with rollback immediate

Bundan sonra, veritabanını güvenle bırakabilirsiniz :)


8
Bunu kullandım ama sık sık başka bir kullanıcının "tek kullanıcı" olarak girmesi için bir fırsat penceresi olup olmadığını merak ettim - bu mümkün mü? Olası alternatif ALTER DATABASE [MyDatabaseName] GERİ DÖNÜŞ İLE BAĞLI AYARLA
Kristen

9
Single_user içindeki kullanıcı sizsiniz; tek kullanıcı modunu ayarladıktan sonra bağlantıyı kesmezseniz. Sonra bir (1) kullanıcı daha oturum açabilir.
Andomar

Veritabanını bıraktıktan sonra, aynı adla yeni bir tane oluşturursanız, bunun çok kullanıcılı modda olacağını varsayıyorum? Yani çalıştırmak zorunda değilsiniz: alter database [MyDatbase] set multi_user
AndyM

@AndyM: Evet, multi_user muhtemelen varsayılan
Andomar

2
@Kristen Yaklaşımınızı kullanarak sql sunucusunun mdf ve ldf dosyalarını kaldırdığını fark ettim. Set single_user benim için iyi çalışıyor (Ben sürekli db yeniden oluşturmanız gerekir).
2xMax

36

Yönetim stüdyosuna gidin ve açıkladığınız her şeyi yapın, sadece Tamam'ı tıklamak yerine Komut Dosyası'nı tıklayın. Daha sonra komut dosyalarınıza dahil edebileceğiniz kodu çalıştıracaktır.

Bu durumda, şunu istersiniz:

ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

1
Sana ( "silme veritabanı" iletişim scripting) tarif tam olarak ne yaparak bu soruyu cevaplamak için çalışacaktı ama değil siz "yakın mevcut bağlantıları" onay kutusunu eğer komut ALTER DATABASE satırı ekleyin.
Matt Hamilton

Sihirbazdan oluşturulan komut dosyası benim için 'veritabanını değiştir' satırını içeriyordu.
nick

Tuhaf. Hangi Management Studio sürümü? 2008 x64'deyim.
Matt Hamilton

Ben de: Microsoft SQL Server Management Studio 10.0.1600.22 İşletim Sistemi 6.0.6001
nick

8
ALTER DATABASE'in betiğe eklenmemesi ile aynı sorunu yaşadı. Komut dosyasına eklenmesini sağlamak için, komut dosyası oluşturulduğunda bu veritabanında çalışan (etkin bağlantı) bir işlemim olduğundan emin olmalıydım.
Gilbert

16

Göre alter database SET dokümantasyon, SINGLE_USER moduna bir veritabanı ayarladıktan sonra erişmek o veritabanı mümkün olmayacak bir olasılık hala var:

Veritabanını SINGLE_USER olarak ayarlamadan önce, AUTO_UPDATE_STATISTICS_ASYNC seçeneğinin KAPALI olarak ayarlandığını doğrulayın. AÇIK olarak ayarlandığında, istatistikleri güncellemek için kullanılan arka plan iş parçacığı veritabanıyla bağlantı kurar ve veritabanına tek kullanıcı modunda erişemezsiniz.

Bu nedenle, mevcut bağlantılar ile veritabanını bırakmak için tam bir komut dosyası şöyle görünebilir:

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]


2

SQL Server 2012'de ne hgmnz saids denedim.

Yönetim benim için yarattı:

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
Bu, etkin bağlantıları kapatmaz.
Jens

"Mevcut bağlantıları kapat" seçeneğini işaretlediğinizden emin olun; Eğer yaparsanız ROLLBACK IMMEDIATEifade dahil edilecektir. sp_delete_database_backuphistory"Sil yedekleme ve veritabanları için geçmiş bilgileri geri" kontrol geliyor.
Christian.K

"Mevcut bağlantıları kapat" seçeneğini işaretlemek, ALTER DATABASE SET SINGLE_USER ...kapatılacak geçerli bağlantı yoksa üretmez.
ahwm

-1

veritabanınızı bırakmak için bu C # kodunu deneyin

public static void DropDatabases (dize dataBase) {

        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();
            }
        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.