it-swarm-ja.tech

SQLスクリプトで「既存の接続を閉じる」を指定する方法

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.

オブジェクトエクスプローラーペインでデータベースを右クリックし、コンテキストメニューから[削除]タスクを選択すると、[既存の接続を閉じる]チェックボックスがあります。

スクリプトでこのオプションを指定する方法はありますか?

142
nick

すべてのユーザーを切断し、トランザクションをロールバックできます:

alter database [MyDatbase] set single_user with rollback immediate

その後、データベースを安全に削除できます:)

230
Andomar

管理スタジオに移動し、説明するすべての操作を行います。[OK]をクリックする代わりに、[スクリプト]をクリックします。実行するコードが表示され、スクリプトに組み込むことができます。

この場合、以下が必要です。

ALTER DATABASE [MyDatabase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
35
hgmnz

ALTER DATABASE SET ドキュメントによると、データベースをSINGLE_USERモードに設定した後、そのデータベースにアクセスできなくなる可能性がまだあります。

データベースをSINGLE_USERに設定する前に、AUTO_UPDATE_STATISTICS_ASYNCオプションがOFFに設定されていることを確認してください。 ONに設定すると、統計の更新に使用されるバックグラウンドスレッドがデータベースに対する接続を取得し、シングルユーザーモードでデータベースにアクセスできなくなります。

したがって、既存の接続でデータベースを削除する完全なスクリプトは次のようになります。

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]
16
AlexD

SQL Server 2012でhgmnzの言うことを試しました。

私に作成された管理:

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
2
Deiwys

私はそれが遅すぎることを知っていますが、その助けになるかもしれません。これを使用すると、データベースがオフラインになります

ALTER DATABASE dbname SET OFFLINE
2

データベースを削除するには、このC#コードを試してください

public static void DropDatabases(string 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();
            }
        }
    }
0
Shailesh Tiwari