it-swarm.com.de

Wie teste ich, ob XML = '' in SQL Server?

Ich arbeite mit SQL Server 2005 und hatte eine Situation, in der viele Werte in einem Parameter übergeben werden können.

Basierend darauf: Übergeben mehrerer Werte für einen SQL-Parameter Diese Prozedur verwendet XML als Parameter.

hier ist der Code der gespeicherten Prozedur:

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

weitere Informationen zu diesem Verfahren hier

dies ist ein Beispiel dafür, wie es genannt werden kann:

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>',
@[email protected] output  select @p5

Frage:

wie kann man am besten herausfinden, ob der Parameter @ListNoteTypeCode XML leer ist oder nicht?

was ist, wenn sie diese Prozedur so nennen:

declare @p5 int  set @p5=86400 
exec DenormV2.udpProductBulletPointSelectByTier1NoteTypeCode
@Tier1=N'WW099',
@LanguageID=3,
@SeasonItemID=N'16AUT',
@ListNoteTypeCode=N'',
@[email protected] output  select @p5

wie vorgeschlagen hier Ich konnte die Auswahl insgesamt vermeiden, indem ich den Parameter @ListNoteTypeCode testete.

Mein Hauptziel in diesem Szenario ist es, die Daten mit der bestmöglichen Leistung abzurufen, da dieses Verfahren nicht auf den Webservern zwischengespeichert wird und über eine Million Mal am Tag aufgerufen wird.

7

Sie können prüfen, ob NULL und Knoten fehlen (exist Methode vom Typ xml):

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

Ihr XPath kann bei Bedarf spezifischer sein:

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

Eine andere Möglichkeit, auf einen leeren XML-Parameter, eine leere Variable oder eine leere XML-Spalte zu testen, besteht darin, DATALENGTH zu überprüfen. Jedes leere XML-Element sollte 5 Byte groß sein. Zum Beispiel:

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;

Kehrt zurück:

XmlParam     DATALENGTH    IsEmpty
--------     ----------    ---------
NULL         NULL          EMPTY
             5             EMPTY
g            9             Not Empty

Bitte beachten Sie, dass ich ISNULL(DATALENGTH(t.[XmlParam]), 5) verwendet habe, da dies zum Überprüfen eines Parameters oder einer Variablen in Ordnung sein sollte. Wenn Sie eine Spalte überprüfen, ist es möglicherweise besser, XmlColumn IS NULL OR DATALENGTH(XmlColumn) = 5 zu verwenden.

Bitte beachten Sie auch, dass die interne Darstellung von XML-Daten zwischen den Versionen möglich geändert werden kann. Ich habe sie unter SQL Server 2008 R2, 2012 und 2014 getestet und die Größe eines leeren XML-Elements ist konsistent 5.

3
Solomon Rutzky

Mein XML verwendet Schema.
DATALENGTH wird definitiv nicht funktionieren.
Auch ohne Daten nimmt das Schema immer noch zufällig Speicherplatz ein.

Dies wird auf fehlende Elemente/Knoten testen (funktioniert mit oder ohne Schema):

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

Damit war der Zweck Ihrer Frage, die Leistung zu verbessern.
Sie verwenden eine Correlated-SubQuery! : O
Huch! Verschieben Sie das in eine Tabellenvariable mit einem PK auf NoteTypeCode.
Dann Inner-Join zu Ihrer Tabellenvariablen und vergessen Sie all dieses Test-For-Missing-Xml Geschäft.

0
MikeTeeVee