Ich arbeite mit SQL Server 2005 und hatte eine Situation, in der viele Werte in einem Parameter übergeben werden können.
Basierend darauf: Bei der Übergabe mehrerer Werte für einen SQL-Parameter wird bei dieser Prozedur XML als Parameter verwendet.
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 finden Sie 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>',
@CacheDuration=@p5 output select @p5
Frage:
Was ist der beste Weg, um herauszufinden, 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'',
@CacheDuration=@p5 output select @p5
Wie hier vorgeschlagen , konnte ich die Auswahl durch Testen des Parameters insgesamt vermeiden @ListNoteTypeCode
.
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.
quelle
'*'
vs'/BulletPoint/NoteTypeCode/text()'
?xml
Instanz leer ist. In diesem Fall wird SqlServer keine Ressourcen für die nachfolgendeselect
Kompilierung von Anweisungen (oder eine mögliche Neukompilierung) und Ausführung ausgeben. Stattdessen kann eine "leere" select-Anweisung ausgeführt werden (was viel einfacher ist), wie in Beantwortung einer der vorherigen Fragen vorgeschlagen.'*'
vs'/BulletPoint/NoteTypeCode/text()'
. Es geht in erster Linie um Semantik. Wenn eine bestimmtexml
Instanz keine anderen als die angegebenen Knoten enthalten kann,'*'
kann eine Überprüfung ausreichend sein. Wenn die bereitgestelltexml
Instanz jedoch andere als die angegebenen Knoten enthalten kann und Sie nur einen Teil dieserxml
Instanz verwenden, sollten Sie in Ihrem XPath genauer angeben, ob die angegebene Instanz für den Zweck dieses gespeicherten Prozesses leerxml
ist .Eine andere Möglichkeit, auf einen leeren XML-Parameter, eine leere Variable oder eine leere XML-Spalte zu testen, besteht darin, die zu überprüfen
DATALENGTH
. Jedes leere XML-Element sollte 5 Byte groß sein. Zum Beispiel:Kehrt zurück:
Bitte beachten Sie, dass ich dies verwendet habe
ISNULL(DATALENGTH(t.[XmlParam]), 5)
, um einen Parameter oder eine Variable zu überprüfen. Wenn Sie eine Spalte überprüfen, ist es möglicherweise besser, sie zu verwendenXmlColumn IS NULL OR DATALENGTH(XmlColumn) = 5
.Bitte beachten Sie auch , dass , während es ist möglich für die interne Darstellung von XML - Daten auf Wechsel zwischen Versionen, ich auf SQL Server 2008 R2 getestet habe, 2012 und 2014 und die Größe eines leeren XML - Elements ist konsequent 5.
quelle
DATALENGTH
schneller ist als das Aufrufen des XML-Parsers, ABER ich habe es nicht getestet. Es sollte jedoch einfach zu testen sein, indem eine Ergebnismenge von 1 Million Zeilen (CROSS JOIN sys.all_columns) generiert und meine Version eingeschlossen wird. Entfernen Sie diese und führen Sie sie erneut mit der i-one-Version aus. Bitte posten Sie die Ergebnisse.Mein XML verwendet Schema.
DATALENGTH
wird definitiv nicht funktionieren.Selbst ohne Daten nimmt das Schema immer noch zufällig Speicherplatz ein.
Dies wird auf fehlende Elemente / Knoten testen (funktioniert mit oder ohne Schema):
Damit war der Zweck Ihrer Frage, die Leistung zu verbessern.
Sie verwenden eine Correlated-SubQuery! : O
Huch! Verschieben Sie das in eine Tabellenvariable mit aktiviertem PK
NoteTypeCode
.Dann Inner-Join zu Ihrer Tabellenvariablen und vergessen Sie all dieses Test-For-Missing-Xml- Geschäft.
quelle