OUTER APPLYとともに使用すると、テーブル値関数で奇妙な動作が発生します。私は別のテーブルの行に基づいていくつかの簡単な計算を返す単純なインライン関数を持っています。 TVFの入力値がハードコードされたスカラーの場合、返される行はありません。私が同じスカラーを取り、CTEでそれらの中から1行を作成すると、CROSS APPLYを使用して列としてフィードします。結果セットはありません。 OUTER APPLYで同じことをすると、(期待通りに)1行が得られますが、出力列のうちの2つがNULL
で、残りの2つがNOT NULL
です。 BOLに基づいて、それはOUTER APPLY
で起こるべきではありません。これはユーザーエラーですか?私は問題を示すために簡単なバージョンを書いた。外部適用予期せず返す列が一致しないときにNULLを返しません。
--Test set-up
CREATE FUNCTION dbo.TVFTest
(
@keyID INT,
@matchValue1 MONEY,
@matchValue2 MONEY
)
RETURNS TABLE AS RETURN
(
WITH TestRow
AS (SELECT @keyID AS KeyID,
@matchValue1 AS MatchValue1,
@matchValue2 AS MatchValue2)
SELECT KeyID,
MatchValue1,
MatchValue2,
CASE
WHEN MatchValue1 <> MatchValue2
THEN 'Not equal'
ELSE 'Something else'
END AS MatchTest
FROM TestRow
WHERE MatchValue1 <> MatchValue2
)
GO
クエリ
WITH Test AS
(
SELECT 12 AS PropertyID,
$350000 AS Ap1,
350000 AS Ap2
)
SELECT LP.*
FROM Test T
OUTER APPLY dbo.TVFTest
(
T.PropertyID,
T.Ap1,
T.Ap2
) LP;
結果、予想通りCross Apply
返さない行を使用して
+-------+-------------+-------------+-----------+
| KeyID | MatchValue1 | MatchValue2 | MatchTest |
+-------+-------------+-------------+-----------+
| 12 | 350000.00 | NULL | NULL |
+-------+-------------+-------------+-----------+
。また、CTEを削除してインライン定数を使用すると、行が返されません。
--Scalars, no row here...
SELECT LP.*
FROM dbo.TVFTest
(
12,
$350000,
350000
) LP;
私はあなたのTVFでフィルタ '' MatchValue1を持っているので、それがあると信じて! = MatchValue2''であり、それぞれのテストは一致する値を提供します。それで、それは一致するものを返しません。その状態を取り除くと、期待した結果が得られると思います。 ... nvrの心は、あなたの質問を誤っているかもしれません... – cocogorilla
OUTER APPLYは、関数に対する外部結合と同様に動作しなければなりません。この例では0の結果が返されました。しかし、TVFによって返されるすべての列はNULLでなければなりません。最初のものはそうではありません。私の質問は - なぜですか?私のコードにバグはありますか? – CDC
あなたは絶対に正しいです...それはWEIRDです...あなたは実際にそれを5列をダンプすることができます...何らかの理由で、マッチドイドがTVPエイリアスの下に来ている...そしてなぜそれがすべきかわからない。 – cocogorilla