Använd OPENXML för att minimera anropen
Förord
OPENXML är en ny funktion som lagts till SQL server 2000 vilket ger en Radsamling över ett XML dokument. Radsamlingen innehåller helt enkelt en uppsättning rader som innehåller kolumner med data, OPENXML är den funktionen som låter ett XML dokument att bli behandlat i den familjära relationsdatabasens format. Den tillåter ett XML dokument att skickas till en T-SQL lagrad procedur för att uppdatera data.Innehåll
Meningen med den här artikeln är att beskriva hur SQL server 2000 OPENXML funktionen kan appliceras på en flerraders insättning av data i en enda databas cell. Kod kommer att visas som accepterar en två dimensionell matris från en ASP klient, skapar en XML dokument sträng från den, och sen kallar på en SQL server 2000 lagrad procedur som sätter in nya rader till en tabell. Det här kan vara ett effektivt alternativ istället för att loopa igenom en matris och kalla på den lagrade proceduren för att sätta in en rad i taget.
Det bifogade exemplet sätter in 10 rader i en tabell, så att OPENXML frågan kapar databasanropen från 10 till 1 i det här fallet. Minimerandet av databasanropen kan översättas till en klart ökad prestanda och skalbarhets fördelar. Varje gång en databas anropas, nätverk och databas resurser är utnyttjade. Desto mera krav du lägger ner på de här resurserna desto mer kommer du att upptäcka en försämring av din applikations prestanda. OPENXML tillåter dig, att väsentligt, packa data i ett enda anrop (som XML) koppla det till en radsamlings vy och exekvera alla insättningar i samma databas anrop vilket resulterar i ett minimum av användandet av dessa resurser.
Meningen med följande kod är att spara användarens svar på en serie av en onlinekurs utvärderings frågor. Svaren på dessa frågor är samlade till en två dimensionell variant matris. Matrisen representerar undersökningens frågenummer och svaren på den givna frågan.
Lista 1 visar SurveyToXML funktionen som finns i mitten lagret på affärsobjektet kompilerat som en VB Active X dll. Matrisen skickas från en ASP sida till det här affärsobjektet. Du kan skicka matrisen till ett COM objekt med ByVal, men du måste skicka med matrisen inom parenteser. Om du inte gör så får du ett VBScript runtime error.
Microsoft har en knowledgebase artikel om att använda parenteser för att skicka ByVal som förklarar det här närmare. Det är vettigt att skicka matrisen med ByVal i det här fallet eftersom du skickar det till ett mitten lager komponent över nätverket. Här är en kod bit från ASP sidan som visar hur man skickar matrisen med ByVal.
Lista 1 - ASP kallar COM funktionen
Följande funktion kallas på från ASP sidan (Se Lista 1)
Lista 2 - VB COM Funktion
Klienten skickar in en två dimensionell variant matris med första dimensionens index 0 som Frågenummer (Qnum) och första dimensionens index 1 som Svaret. Den andra dimensionen av matrisen representerar turordningsnumren av de besvarade frågorna.
EvalID som kopplar svaren till de specifika utvärderingsfrågorna skapas och returneras från databasen. De tre värden som behövs för att sätta in ett svar till en specifik utvärderingsfråga är EvalID, Qnum och Answer.
I det här läget måste du skapa XML strängen. Den kan skapas genom att använda DOM eller genom att direkt skapa XML strängen i en sträng variabel. Exemplet ovanför använder DOM för att skapa rot element noden, och undernod elementet . Tre attribut är skapade i --> evalid, qnum, och answer. Efter att noden är skapad och bifogad, koden loopar igenom matrisen och lägger till en nod som den lägger till för varje turordningsfråga. XML representationen för noden och all dess härstammande är fångade från xml egenskapen av det XML dokument du just skapade.
Lista 3 - XML skapad
OBS! Koden i Lista 3 ska vara utan mellanslag, men för att texten ska kunna visas så är mellanslag inlagda!
Den här strängen skickas till en databas komponents funktion som sköter insättningen till databasen. Den här komponenten finns också i mitten lagret kompilerad som en VB Active X dll. Här är koden för databas funktionen.
Lista 4 – VB COM Databas Funktion (ADO)
Det här är rätt så rakt på allt det du gör instansierar ett Command objekt med en parameter, din XML sträng och exekverar den lagrade procedur anropet.
Det lagrade procedur anropet ser ut så här.
Lista 5 – SQL Server 2000 Lagrad Procedur
Du kan se att den enda parametern som skickas till proceduren är XML som skickas som varchar. Beroende på storleken på XML strängen som du arbetar med, XML strängens parameter kan vara antingen (n)char eller (n)text motsvarande (n)varchar. [Notera: Använd (n) när du jobbar med Unicode data] @hDoc variabeln krävs av sp_xml_preparedocument som en output parameter. sp_xml_preparedocument är en SQL server system lagrad procedur som skapar en intern representation av XML dokumentet som skickas till den, och den returnerar dokument handtaget i @hDoc.
OPENXML funktionen accepterar tre argument, de första två är obligatoriska.
Det första argumentet är det dokument handtag du skapade genom sp_xml_preparedocument.
Det talar om för OPENXML vilket XML dokument du jobbar med. Det andra argumentet är en XPATH (XML Path Language) mönster som används för att identifiera noderna i XML dokumentet. XPATH är en W3 (World Wide Web Consortium) navigations standard.
De definierar XPATH som ett språk för att adressera delar av ett XML dokument.
Varje nod identifieras av XPATH pekar på en enda rad i ett radset skapat av OPENXML.
I vårat exempel, finns det 10 noder som representerar en rad i ett radset.
Det tredje argumentet är valfritt och specificerar hur mappningen ska göras mellan radsetet skapat av OPENXML och XML dokumentet. Standard attributet är centric vilket menas att XML attributet på ett givet namn är lagrat i en kolumn i radsetet med samma namn. I exemplet är EvalID, Qnum och Answer lagrade i radsetet med samma namn. Därför ser radsetet ut så här:
WITH klausulen tillåter dig att specificera en Schema deklaration( att specificera ytterligare mappningar mellan en kolumn i radsetet och ett värde i XML dokumentet) eller tabellnamnet om tabellen redan finns med önskat schema.
Exemplet gör en enkel insert till Answers tabellen och eftersom XML dokumentet skapades speciellt för att sätta in flera rader till Answers tabellen, det är tillräckligt att specificera tabellnamnet Answers i vår WITH klausul.
Du kan specificera en schema deklaration för att uppnå samma mappning som i exemplet som följer.
Den sista raden i Lista 5, EXEC sp_xml_removedocument @hDoc, kallas på för att ta bort XML dokumentet från lagringen i SQL serverns interna chach minne.
Som summering, den nya OPENXML funktionen i SQL server 2000 kan vara användbar för att processa fler tabell insättningar med ett enda databas anrop. Förmågan att kunna mappa ett XML dokument till en radsamling för en specificerad portion av XML dokumentet inom en lagrad procedur kan maximera effektiviteten med vilken repetitiva inserts är fulländade.
Det bifogade exemplet sätter in 10 rader i en tabell, så att OPENXML frågan kapar databasanropen från 10 till 1 i det här fallet. Minimerandet av databasanropen kan översättas till en klart ökad prestanda och skalbarhets fördelar. Varje gång en databas anropas, nätverk och databas resurser är utnyttjade. Desto mera krav du lägger ner på de här resurserna desto mer kommer du att upptäcka en försämring av din applikations prestanda. OPENXML tillåter dig, att väsentligt, packa data i ett enda anrop (som XML) koppla det till en radsamlings vy och exekvera alla insättningar i samma databas anrop vilket resulterar i ett minimum av användandet av dessa resurser.
Meningen med följande kod är att spara användarens svar på en serie av en onlinekurs utvärderings frågor. Svaren på dessa frågor är samlade till en två dimensionell variant matris. Matrisen representerar undersökningens frågenummer och svaren på den givna frågan.
Lista 1 visar SurveyToXML funktionen som finns i mitten lagret på affärsobjektet kompilerat som en VB Active X dll. Matrisen skickas från en ASP sida till det här affärsobjektet. Du kan skicka matrisen till ett COM objekt med ByVal, men du måste skicka med matrisen inom parenteser. Om du inte gör så får du ett VBScript runtime error.
Microsoft har en knowledgebase artikel om att använda parenteser för att skicka ByVal som förklarar det här närmare. Det är vettigt att skicka matrisen med ByVal i det här fallet eftersom du skickar det till ett mitten lager komponent över nätverket. Här är en kod bit från ASP sidan som visar hur man skickar matrisen med ByVal.
Lista 1 - ASP kallar COM funktionen
Dim objBusEval, arrSurvey
set objBusEval = server.CreateObject("SurveyXML.savesurvey")
if objBusEval.SurveyToXML((arrsurvey)) then
…
else
…
end if
Följande funktion kallas på från ASP sidan (Se Lista 1)
Lista 2 - VB COM Funktion
Public Function SurveyToXML( ByVal arrSurvey As Variant) As Boolean
Dim objXMLdoc As MSXML.DOMDocument
Dim objXMLRootElem As MSXML.IXMLDOMElement
Dim objXMLAnswers As MSXML.IXMLDOMElement
Dim objXMLAttribEvalID As IXMLDOMAttribute
Dim objXMLAttribQnum As IXMLDOMAttribute
Dim objXMLAttribAnswer As IXMLDOMAttribute
Dim x As Integer
Dim y As Integer
Dim EvalID As Integer
Dim objDBSurvey As dbSurvey.dbSaveSurvey
On Error GoTo ErrHandler
Set objDBSurvey = New dbSurvey.dbSaveSurvey
EvalID = objDBSurvey.GetEvalID("Alex", "Rodriguez", "arod@texasrangers.com", 1, vbNullString)
Set objXMLdoc = New MSXML.DOMDocument
With objXMLdoc
Set objXMLRootElem = .createElement("insert")
.appendChild objXMLRootElem
For y = LBound(arrSurvey, 2) To UBound(arrSurvey, 2)
Set objXMLAnswers = .createElement("Answers")
.documentElement.appendChild objXMLAnswers
Set objXMLAttribEvalID = .createAttribute("EvalID")
objXMLAttribEvalID.nodeValue = EvalID
objXMLAnswers.setAttributeNode objXMLAttribEvalID
Set objXMLAttribQnum = .createAttribute("QNum")
objXMLAttribQnum.nodeValue = arrSurvey(0, y)
objXMLAnswers.setAttributeNode objXMLAttribQnum
Set objXMLAttribAnswer = .createAttribute("Answer")
objXMLAttribAnswer.nodeValue = arrSurvey(1, y)
objXMLAnswers.setAttributeNode objXMLAttribAnswer
Next y
If objDBSurvey.SaveXMLResponse(.xml) Then
SurveyToXML = True
Else
SurveyToXML = False
End If
End With
SurveyToXML = True
Cleanup:
Set objDBSurvey = Nothing
Set objXMLdoc = Nothing
Exit Function
ErrHandler:
SurveyToXML = False
GoTo Cleanup
End Function
Klienten skickar in en två dimensionell variant matris med första dimensionens index 0 som Frågenummer (Qnum) och första dimensionens index 1 som Svaret. Den andra dimensionen av matrisen representerar turordningsnumren av de besvarade frågorna.
EvalID som kopplar svaren till de specifika utvärderingsfrågorna skapas och returneras från databasen. De tre värden som behövs för att sätta in ett svar till en specifik utvärderingsfråga är EvalID, Qnum och Answer.
I det här läget måste du skapa XML strängen. Den kan skapas genom att använda DOM eller genom att direkt skapa XML strängen i en sträng variabel. Exemplet ovanför använder DOM för att skapa rot element noden
Lista 3 - XML skapad
< insert >
< Answers EvalID="84" QNum="1" Answer="Good" />
< Answers EvalID="84" QNum="2" Answer="Fair" />
< Answers EvalID="84" QNum="3" Answer="Very Good" />
< Answers EvalID="84" QNum="4" Answer="Excellent" />
< Answers EvalID="84" QNum="5" Answer="Good" />
< Answers EvalID="84" QNum="6" Answer="Good" />
< Answers EvalID="84" QNum="7" Answer="Fair" />
< Answers EvalID="84" QNum="8" Answer="Very Good" />
< Answers EvalID="84" QNum="9" Answer="Excellent" />
< Answers EvalID="84" QNum="10" Answer="Good" />
< /insert >
OBS! Koden i Lista 3 ska vara utan mellanslag, men för att texten ska kunna visas så är mellanslag inlagda!
Den här strängen skickas till en databas komponents funktion som sköter insättningen till databasen. Den här komponenten finns också i mitten lagret kompilerad som en VB Active X dll. Här är koden för databas funktionen.
Lista 4 – VB COM Databas Funktion (ADO)
Public Function SaveXMLResponse(ByVal strXML As String) As Boolean
Dim prmXML As ADODB.Parameter
On Error GoTo SaveXMLResponse_Err
Set com = New ADODB.Command
Set prmXML = New ADODB.Parameter
If cn Is Nothing Then
StartConnection
End If
With com
.ActiveConnection = cn
.CommandText = "SaveXMLresponse"
.CommandType = adCmdStoredProc
Set prmXML = .CreateParameter("@evaldata", adVarChar, adParamInput, 4000, strXML)
.Parameters.Append prmXML
.Execute,,adExecuteNoRecords
End With
SaveXMLResponse = True
Cleanup:
Set prmXML = Nothing
Set com = Nothing
Set cn = Nothing
Exit Function
SaveXMLResponse_Err:
SaveXMLResponse = False
GoTo Cleanup
End Function
Det här är rätt så rakt på allt det du gör instansierar ett Command objekt med en parameter, din XML sträng och exekverar den lagrade procedur anropet.
Det lagrade procedur anropet ser ut så här.
Lista 5 – SQL Server 2000 Lagrad Procedur
CREATE PROC saveXMLresponse
@evaldata varchar(4000)
AS
DECLARE @hDoc int
exec sp_xml_preparedocument @hDoc OUTPUT,@evaldata
INSERT INTO Answers
SELECT *
FROM OPENXML (@hDoc,'/insert/Answers')
WITH Answers
EXEC sp_xml_removedocument @hDoc
GO
Du kan se att den enda parametern som skickas till proceduren är XML som skickas som varchar. Beroende på storleken på XML strängen som du arbetar med, XML strängens parameter kan vara antingen (n)char eller (n)text motsvarande (n)varchar. [Notera: Använd (n) när du jobbar med Unicode data] @hDoc variabeln krävs av sp_xml_preparedocument som en output parameter. sp_xml_preparedocument är en SQL server system lagrad procedur som skapar en intern representation av XML dokumentet som skickas till den, och den returnerar dokument handtaget i @hDoc.
OPENXML funktionen accepterar tre argument, de första två är obligatoriska.
Det första argumentet är det dokument handtag du skapade genom sp_xml_preparedocument.
Det talar om för OPENXML vilket XML dokument du jobbar med. Det andra argumentet är en XPATH (XML Path Language) mönster som används för att identifiera noderna i XML dokumentet. XPATH är en W3 (World Wide Web Consortium) navigations standard.
De definierar XPATH som ett språk för att adressera delar av ett XML dokument.
Varje nod identifieras av XPATH pekar på en enda rad i ett radset skapat av OPENXML.
I vårat exempel, finns det 10
Det tredje argumentet är valfritt och specificerar hur mappningen ska göras mellan radsetet skapat av OPENXML och XML dokumentet. Standard attributet är centric vilket menas att XML attributet på ett givet namn är lagrat i en kolumn i radsetet med samma namn. I exemplet är EvalID, Qnum och Answer lagrade i radsetet med samma namn. Därför ser radsetet ut så här:
EvalID | Qnum | Answer |
84 | 1 | Good |
84 | 2 | Fair |
84 | 3 | Very Good |
84 | 4 | Excellent |
84 | 5 | Good |
84 | 6 | Good |
84 | 7 | Fair |
84 | 8 | Very Good |
84 | 9 | Excellent |
84 | 10 | Good |
WITH klausulen tillåter dig att specificera en Schema deklaration( att specificera ytterligare mappningar mellan en kolumn i radsetet och ett värde i XML dokumentet) eller tabellnamnet om tabellen redan finns med önskat schema.
Exemplet gör en enkel insert till Answers tabellen och eftersom XML dokumentet skapades speciellt för att sätta in flera rader till Answers tabellen, det är tillräckligt att specificera tabellnamnet Answers i vår WITH klausul.
Du kan specificera en schema deklaration för att uppnå samma mappning som i exemplet som följer.
INSERT INTO Answers
SELECT *
FROM OPENXML (@hDoc,'/insert/Answers')
WITH (EvalID int,
Qnum int,
Answer varchar(20))
Den sista raden i Lista 5, EXEC sp_xml_removedocument @hDoc, kallas på för att ta bort XML dokumentet från lagringen i SQL serverns interna chach minne.
Som summering, den nya OPENXML funktionen i SQL server 2000 kan vara användbar för att processa fler tabell insättningar med ett enda databas anrop. Förmågan att kunna mappa ett XML dokument till en radsamling för en specificerad portion av XML dokumentet inom en lagrad procedur kan maximera effektiviteten med vilken repetitiva inserts är fulländade.
0 Kommentarer