web-dev-qa-db-ja.com

SQLサーバーでXML = ''かどうかをテストする方法は?

私は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万回以上呼び出されるためです。

7

NULLおよびノー​​ドの不在(existタイプのxmlメソッド)を確認できます。

@ListNoteTypeCode is NULL OR @ListNoteTypeCode.exist('*') = 0

必要に応じて、XPathをより具体的にすることができます。

@ListNoteTypeCode is NULL OR @ListNoteTypeCode.exist('/BulletPoint/NoteTypeCode/text()') = 0
7
i-one

空の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。

3
Solomon Rutzky

私のXMLはスキーマを使用しています。
DATALENGTH間違いなく機能しません。
データがなくても、ランダムな量のスペースを占めるスキーマがあります。

これは、不足している要素/ノードをテストします(スキーマなしでまたはで機能):

SELECT ISNULL(@ListNoteTypeCode.exist('*:BulletPoint/*:NoteTypeCode'), 0)[HasRows]

それが邪魔にならないうちに、あなたの質問の目的はパフォーマンスを改善することでした。
あなたは相関サブクエリを使用しています! :O
うわぁ!それをNoteTypeCodeのPKを使用してTable-Variableに移動します。
次に、テーブル変数に内部結合して、このすべてのTest-For-Missing-Xmlビジネスを忘れます。

0
MikeTeeVee