SSDTのSQLサーバーデータベースプロジェクトにメモリ最適化ファイルグループを追加しようとしています。これは、Visual Studio 2017を使用するSQL Server 2017用です。
ただし、プロジェクトをコンパイル(F5キーを押してビルド)すると、エラーが発生します。このエラーは、(Deployを介して)デプロイするときには発生しません。
ファイルグループは通常どおり作成されます(SSDTによってスクリプト化されたSQLCMD変数を使用)。
ALTER DATABASE [$(DatabaseName)]
ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA
ただし、これによりエラーが発生します。
操作 'AUTO_CLOSE'は、MEMORY_OPTIMIZED_DATAファイルグループを持つデータベースではサポートされていません。
ただし、データベース設定では、自動クローズが実際に無効になっていることが示されています。
SSDTによって何らかの理由で生成された展開スクリプトは、データベースを作成し、ファイルグループを作成し、その後、AUTO_CLOSEをオフに設定するだけです。これがエラーの原因である可能性があります:
CREATE DATABASE [$(DatabaseName)]
ON
PRIMARY(NAME = [$(DatabaseName)], FILENAME = N'$(DefaultDataPath)$(DefaultFilePrefix)_Primary.mdf')
LOG ON (NAME = [$(DatabaseName)_log], FILENAME = N'$(DefaultLogPath)$(DefaultFilePrefix)_Primary.ldf') COLLATE SQL_Latin1_General_CP1_CI_AS
GO
PRINT N'Creating [MemoryOptimizedFilegroup]...';
GO
ALTER DATABASE [$(DatabaseName)]
ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA;
GO
ALTER DATABASE [$(DatabaseName)]
ADD FILE (NAME = [MemoryOptimizedFilegroup_69323650], FILENAME = N'$(DefaultDataPath)$(DefaultFilePrefix)_MemoryOptimizedFilegroup_69323650.mdf') TO FILEGROUP [MemoryOptimizedFilegroup];
GO
USE [$(DatabaseName)];
GO
IF EXISTS (SELECT 1
FROM [master].[dbo].[sysdatabases]
WHERE [name] = N'$(DatabaseName)')
BEGIN
ALTER DATABASE [$(DatabaseName)]
SET ANSI_NULLS ON,
ANSI_PADDING ON,
ANSI_WARNINGS ON,
ARITHABORT ON,
CONCAT_NULL_YIELDS_NULL ON,
NUMERIC_ROUNDABORT OFF,
QUOTED_IDENTIFIER ON,
ANSI_NULL_DEFAULT ON,
CURSOR_DEFAULT LOCAL,
CURSOR_CLOSE_ON_COMMIT OFF,
AUTO_CREATE_STATISTICS ON,
AUTO_SHRINK OFF,
AUTO_UPDATE_STATISTICS ON,
RECURSIVE_TRIGGERS OFF
WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [$(DatabaseName)]
SET AUTO_CLOSE OFF
WITH ROLLBACK IMMEDIATE;
END
CREATE DATABASEの後、デフォルトでAUTO_CLOSEが有効になっているか無効になっているかはわかりません。デフォルトでオンの場合、SSDTが誤った順序で展開スクリプトを生成しているようです。デフォルトでオフの場合、エラーが存在する理由がわかりません。
SSDTプロジェクトでメモリ最適化ファイルグループの作成に成功した人はいますか?
CREATE DATABASEの後、デフォルトでAUTO_CLOSEが有効になっているか無効になっているかはわかりません。デフォルトでオンの場合、SSDTが誤った順序で展開スクリプトを生成しているようです。デフォルトでOFFの場合、エラーが存在する理由がわかりません。
LocalDBはモデルを無視してAUTO_CLOSEをハードコードしているようです
LocalDB/SQLEXPRESS
True、localdbに接続して標準のデータベース作成コマンドを実行する場合
CREATE DATABASE TEST
GO
SELECT name,database_id
FROM sys.databases
WHERE is_auto_close_on = 1;
name database_id
TEST 5
model
でauto_closeが無効になっている場合でも、is_auto_close_on
が1に設定されているようです。
通常、デフォルト設定はmodel
システムデータベースに基づいています。
理論的にこの問題を解決する
新しく作成されたデータベースの自動クローズを自動的に0
に変更するトリガーを作成できます。これは少しハックなアプローチですが、機能します。
自分の責任で試してください/実装してください。
CREATE TRIGGER Change_Auto_Close
ON ALL SERVER
FOR CREATE_DATABASE
AS
DECLARE
@DatabaseName NVARCHAR(128)
,@SQL NVARCHAR(4000);
SELECT
@DatabaseName = EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(128)')
SET @SQL = 'USE [master] ALTER DATABASE ['+@DatabaseName+'] SET AUTO_CLOSE OFF WITH NO_WAIT;';
IF @@TRANCOUNT = 1
COMMIT TRAN; -- commit previous tran, otherwise we cannot alter the database
-- PRINT @SQL;
EXEC (@SQL);
BEGIN TRAN; --begin new tran as not get error that the transaction ended in the trigger
GO
その他のエディション
データベースはmodel
のコピーとして作成されるため、model
データベースにis_auto_close_on = 1
がある可能性があります。以下は、model
データベースでauto_closeを有効および無効にしたいくつかのテストです。
model
の自動クローズをオンに設定
USE [master]
GO
ALTER DATABASE [model] SET AUTO_CLOSE ON WITH NO_WAIT;
GO
デフォルトのデータベースを作成する
CREATE DATABASE AutoClosedDB;
新しく作成されたデータベースの自動クローズ状態を検証します
SELECT name, is_auto_close_on
FROM sys.databases
WHERE name = 'AutoClosedDB';
結果
name is_auto_close_on
AutoClosedDB 1
model
の自動クローズをオフに設定
USE [master]
GO
ALTER DATABASE [model] SET AUTO_CLOSE OFF WITH NO_WAIT;
GO
デフォルト設定でデータベースを作成する
CREATE DATABASE NoAutoClosedDB;
新しく作成されたデータベースの自動クローズ状態を検証します
SELECT name, is_auto_close_on
FROM sys.databases
WHERE name = 'NoAutoClosedDB';
結果
name is_auto_close_on
NoAutoClosedDB 0
両方のデータベースでメモリ最適化ファイルグループを作成してみてください
ALTER DATABASE NoAutoClosedDB
ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA;
成功する
ALTER DATABASE AutoClosedDB
ADD FILEGROUP [MemoryOptimizedFilegroup] CONTAINS MEMORY_OPTIMIZED_DATA;
エラーメッセージで失敗する:
メッセージ10794、レベル16、状態125、行33操作 'AUTO_CLOSE'は、MEMORY_OPTIMIZED_DATAファイルグループを持つデータベースではサポートされていません。
model
データベースの自動クローズ状態を検証するには、以下のスクリプトを実行します
SELECT name, is_auto_close_on
FROM sys.databases
WHERE name = 'model';
自動クローズを無効にする
USE [master]
GO
ALTER DATABASE [model] SET AUTO_CLOSE OFF WITH NO_WAIT;
GO
上記のRandi Vertongenによる回答に加えて、SQL Serverインスタンスをインストールし、LocalDBではなくそれに接続するようにデバッグ設定でSSDTプロジェクトを編集する方法もあります。
たとえば、SQLTの名前付きインスタンスをSSDTビルド(デバッグビルドテストでF5キーを押した場合)にのみインストールし、実際の展開に使用した既定のインスタンス(発行を使用した場合)をインストールしました。
これにより、デフォルトのAUTO_CLOSEが1つだけであるLocalDBの制限が克服されます。