如何在sql server中测试XML = ''?

Mar*_*lli 8 performance sql-server-2005 xml sql-server optimization query-performance

我正在使用 sql server 2005,我遇到了可以在参数中传递许多值的情况。

基于此:为一个 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
Run Code Online (Sandbox Code Playgroud)

关于这个程序的更多信息在这里

这是如何调用它的示例:

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
Run Code Online (Sandbox Code Playgroud)

题:

找出参数@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
Run Code Online (Sandbox Code Playgroud)

正如这里建议的那样我可以通过测试参数来完全避免选择@ListNoteTypeCode

在这种情况下,我的主要目标是以最佳性能检索数据,因为此过程未缓​​存在 Web 服务器中,并且每天调用超过一百万次。

i-o*_*one 8

您可以检查NULL和节点缺失(类型exist方法xml):

@ListNoteTypeCode is NULL OR @ListNoteTypeCode.exist('*') = 0
Run Code Online (Sandbox Code Playgroud)

如有必要,您的 XPath 可以更具体:

@ListNoteTypeCode is NULL OR @ListNoteTypeCode.exist('/BulletPoint/NoteTypeCode/text()') = 0
Run Code Online (Sandbox Code Playgroud)


Sol*_*zky 5

另一种测试空 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;
Run Code Online (Sandbox Code Playgroud)

返回:

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;
Run Code Online (Sandbox Code Playgroud)

请注意,我使用ISNULL(DATALENGTH(t.[XmlParam]), 5)它来检查参数或变量应该没问题。如果检查一列,最好使用XmlColumn IS NULL OR DATALENGTH(XmlColumn) = 5.

另请注意,虽然XML 数据的内部表示可能会在不同版本之间发生变化,但我已经在 SQL Server 2008 R2、2012 和 2014 上进行了测试,并且空 XML 项的大小始终为 5。