私はSQL Server 2005を使用していますが、パラメーターで多くの値を渡すことができる状況にありました。
これに基づいて: 1つのSQLパラメータに複数の値を渡す このプロシージャはXMLをパラメータとして使用します。
ストアドプロシージャのコードは次のとおりです。
CREATE PROCEDURE [DENORMV2].[udpProductBulletPointSelectByTier1NoteTypeCode] (
@Tier1 VARCHAR(10),
@LanguageID INT,
@SeasonItemID VARCHAR(5) = NULL,
@ListNoteTypeCode XML,
@CacheDuration INT OUTPUT )
WITH EXECUTE AS 'webUserWithRW'
AS
SELECT pbp.Tier1, pbp.LanguageId, pbp.NoteText, pbp.NoteTypeCode,
pbp.NoteGroup, pbp.SortOrder
FROM dbo.ProductBulletPoint pbp
WHERE Tier1 = @Tier1
AND LanguageId = @LanguageID
AND ( SeasonItemId = @SeasonItemID
OR
@SeasonItemID is null
)
AND pbp.NoteTypeCode IN (
SELECT NoteTypeCode=BulletPoint.NoteTypeCode.value('./text()[1]', 'varchar(50)')
FROM @ListNoteTypeCode.nodes('/BulletPoint/NoteTypeCode') AS BulletPoint ( NoteTypeCode )
)
SELECT @CacheDuration = Duration
FROM dbo.CacheDuration
WHERE [Key] = 'Product'
GO
この手順の詳細 ここ
これは、それを呼び出す方法の例です。
declare @p5 int set @p5=86400
exec DenormV2.udpProductBulletPointSelectByTier1NoteTypeCode
@Tier1=N'WW099',
@LanguageID=3,
@SeasonItemID=N'16AUT',
@ListNoteTypeCode=N'<BulletPoint><NoteTypeCode>GarmentComposition</NoteTypeCode><NoteTypeCode>FootwearAccessoryComposition</NoteTypeCode></BulletPoint>',
@CacheDuration=@p5 output select @p5
質問:
パラメータ@ListNoteTypeCode XML
が空かどうかを確認する最良の方法は何ですか?
この手順を次のように呼び出すとどうなりますか。
declare @p5 int set @p5=86400
exec DenormV2.udpProductBulletPointSelectByTier1NoteTypeCode
@Tier1=N'WW099',
@LanguageID=3,
@SeasonItemID=N'16AUT',
@ListNoteTypeCode=N'',
@CacheDuration=@p5 output select @p5
提案されたとおり here パラメータ@ListNoteTypeCode
をテストすることで、選択を完全に回避できます。
このシナリオの主な目的は、可能な限り最高のパフォーマンスでデータを取得することです。この手順はWebサーバーにキャッシュされず、1日に100万回以上呼び出されるためです。
NULL
およびノードの不在(exist
タイプのxml
メソッド)を確認できます。
@ListNoteTypeCode is NULL OR @ListNoteTypeCode.exist('*') = 0
必要に応じて、XPathをより具体的にすることができます。
@ListNoteTypeCode is NULL OR @ListNoteTypeCode.exist('/BulletPoint/NoteTypeCode/text()') = 0
空のXMLパラメータ、変数、または列をテストする別の方法は、DATALENGTH
を確認することです。空のXMLアイテムは5バイトにする必要があります。例えば:
_DECLARE @Test TABLE (XmlParam XML NULL);
INSERT INTO @Test ([XmlParam]) VALUES (NULL), (N''), (N'g');
SELECT t.[XmlParam],
DATALENGTH(t.[XmlParam]) AS [DATALENGTH],
CASE (ISNULL(DATALENGTH(t.[XmlParam]), 5))
WHEN 5 THEN 'EMPTY'
ELSE 'Not Empty'
END AS [IsEmpty]
FROM @Test t;
_
戻り値:
_XmlParam DATALENGTH IsEmpty
-------- ---------- ---------
NULL NULL EMPTY
5 EMPTY
g 9 Not Empty
_
ISNULL(DATALENGTH(t.[XmlParam]), 5)
を使用したことに注意してください。これは、パラメーターまたは変数のチェックには問題ないはずです。列をチェックする場合は、XmlColumn IS NULL OR DATALENGTH(XmlColumn) = 5
を使用することをお勧めします。
XMLデータの内部表現がバージョン間で変更されるのは可能ですが、SQL Server 2008 R2、2012、および2014でテストし、空のXMLアイテムのサイズが一貫していることにも注意してください5。
私のXMLはスキーマを使用しています。DATALENGTH
は間違いなく機能しません。
データがなくても、ランダムな量のスペースを占めるスキーマがあります。
これは、不足している要素/ノードをテストします(スキーマなしでまたはで機能):
SELECT ISNULL(@ListNoteTypeCode.exist('*:BulletPoint/*:NoteTypeCode'), 0)[HasRows]
それが邪魔にならないうちに、あなたの質問の目的はパフォーマンスを改善することでした。
あなたは相関サブクエリを使用しています! :O
うわぁ!それをNoteTypeCode
のPKを使用してTable-Variableに移動します。
次に、テーブル変数に内部結合して、このすべてのTest-For-Missing-Xmlビジネスを忘れます。