概要
In our application we use Entity Framework 6 and SQL Server 2016. 複雑なロジックを持つストアド プロシージャを EF モデルにインポートする場合、特に一時テーブルを使用する場合は、次のようにします。
SET FMTONLY OFF
これにより、ストアド プロシージャは完全なロジックを実行し、正しい出力形式を返すため、EF モデルは複合型を正しく生成できます。
一般的に、問題なく動作します。ただし、Microsoft のドキュメントhttps://docs.microsoft.com/en-us/sql/t-sql/statements/set-fmtonly-transact-sql?view=sql-server-ver15には次のように記載されています。この機能を使用しないでください。だから、ストアドプロシージャをインポートして複合型を正しく生成するための推奨される方法は何だろうと思っています。
詳細
まず、 Microsoft の Web サイトでこの機能を使用しないでくださいというメモに混乱していますFMTONLY
。ON
EF モデル アップデーターによって呼び出されるのと同じコマンド (オプション付き) ではありませんか? これは、EF モデル アップデーターが使用すべきではない機能を使用していることを意味します。
次に、この EF モデル アップデーターの動作は、すべての入力引数が equal でストアド プロシージャが実行されたときに、望ましくない DB データ操作を防ぐことを目的としていると思いますNULL
。しかし、実際の動作はこの仮定と一致していないようです。
の使用を避けようとした以下の単純なストアド プロシージャを考えてみましょうSET FMTONLY OFF
。Visual Studio (2013、CU 5、Pro) から EF モデルを更新しながら、SQL プロファイラーを使用して正確な動作を分析しました。
SET NOCOUNT ON;
IF (1=0) --FOR EF edmx update this will actually execute
BEGIN
DECLARE @tempTable TABLE
(
[id] [int],
[date_local] [datetime2](7),
[value] [float] NULL
)
SELECT * FROM @tempTable
RETURN 0
END
CREATE TABLE #TempValue
(
[id] [int] NOT NULL,
[date_local] [datetime2](7) NOT NULL,
[value] [float] NULL
CONSTRAINT [PK_TempValue]
PRIMARY KEY CLUSTERED ([id] ASC, [date_local] ASC)
WITH (PAD_INDEX =OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO #TempValue (id, date_local, value)
SELECT @id, *
FROM OPENJSON(@valueJson)
WITH (
date_local datetime2(7) '$.dateTime',
value float '$.value'
);
SELECT * FROM #TempValue
ポイント:
EF モデル アップデーターはそれを呼び出し、内部に入り
IF (1=0)
(期待どおりSET FMTONLY ON
)、SELECT * from @tempTable
正しく実行されます。ストアド プロシージャ本体の残りの部分は無視され
return 0
、引き続き実行されます。スキップしますが、もちろん存在しないもの
CREATE TABLE #TempValue
を実行しようとするため、ここで停止して実行しません。これも失敗します。INSERT INTO #TempValue
SELECT * FROM #TempValue
この場合、最後に成功した select は だったので、複合型は正しく生成されましたSELECT * from @tempTable
。しかし、実際に実行される後続の選択がないため、これは単なる運だと思います。私にとって、この動作全体には欠陥があり、特にスキップしreturn 0
て; あなたが許可した場合、DBデータを保存していませんか?CREATE TABLE #TempValue
INSERT INTO
INSERT INTO
したがって、実際に機能する 2 つの回避策は次のとおりです。
上に置く
SET FMTONLY OFF
。動作しますが、これが少し心配ですMicrosoft Web サイトでこの機能を使用しないでください。SP 本体全体をコメントアウトし
DECLARE @tempTable table ... SELECT * from @tempTable
、上記の例のように追加します。EF モデルを更新した後、追加されたチャンクを削除し、元のコードのコメントを外します。EF モデルが更新されるたびにこれを行うため、あまり効率的ではありません。
それを行うための適切で推奨される方法は何ですか?