2012-03-24 15 views
0

zurückgegeben wird Ich bin mit der folgenden AbfrageT-SQL: Mit ROW_NUMBER() FOR XML Paginieren - Kindknoten nicht

SELECT 
    ROW_NUMBER() OVER(ORDER BY [TransactionValues].[ID]) AS idx, 
    [Transactions].[ID] AS [id], 
    [Transactions].[EncryptedAccountID] AS [encryptedAccountID], 
    [Transactions].[Uploaded] AS [uploaded], 
    [Transactions].[Visible] AS [visible], 
    [Fields].[ID] AS [fieldId], 
    [Fields].[FriendlyName] AS [friendlyName], 
    [Fields].[OfficialName] AS [officialName], 
    [Fields].[Order] AS [order], 
    [Fields].[Visible] AS [valueVisible], 
    [TransactionValues].[ID] AS [valueId], 
    [TransactionValues].[FieldID] AS [valueFieldId], 
    [TransactionValues].[FriendlyValue] AS [friendlyValue], 
    [TransactionValues].[OfficialValue] AS [officialValue], 
    [TransactionValues].[TransactionID] AS [transactionId] 
FROM 
    [Transactions] 
    INNER JOIN [TransactionValues] 
    ON [TransactionValues].[TransactionID] = [Transactions].[ID] 
    INNER JOIN [Fields] 
    ON [TransactionValues].[FieldID] = [Fields].[ID] 
WHERE 
    [Transactions].[EncryptedAccountID] = @encryptedAccountID 
FOR XML AUTO, ROOT('root') 

Welche XML in folgendem Format zurück (ich habe das zurückgegebene Attribut weggelassen Werte - diese sind nicht relevant):

<root> 
    <Transactions idx="" id="" encryptedAccountID="" uploaded="" visible=""> 
     <Fields id="" friendlyName="" officialName="" order="" visible=""> 
      <TransactionValues valueId="" valueFieldId="" friendlyValue="" officialValue="" transactionId="" /> 
     </Fields> 
     <Fields id="" friendlyName="" officialName="" order="" visible=""> 
      <TransactionValues valueId="" valueFieldId="" friendlyValue="" officialValue="" transactionId="" /> 
     </Fields> 
    </Transactions> 
    <Transactions idx="" id="" encryptedAccountID="" uploaded="" visible=""> 
     <Fields id="" friendlyName="" officialName="" order="" visible=""> 
      <TransactionValues valueId="" valueFieldId="" friendlyValue="" officialValue="" transactionId="" /> 
     </Fields> 
     <Fields id="" friendlyName="" officialName="" order="" visible=""> 
      <TransactionValues valueId="" valueFieldId="" friendlyValue="" officialValue="" transactionId="" /> 
     </Fields> 
    </Transactions> 
</root> 

So weit so gut.

Jetzt möchte ich die Ergebnisse paginieren. Ein Teil davon erfordert, dass die obige Abfrage als Unterabfrage ausgeführt wird. So jetzt habe ich die folgende Abfrage haben:

SELECT 
* 
FROM 
(
    SELECT 
     ROW_NUMBER() OVER(ORDER BY [TransactionValues].[ID]) AS idx, 
     [Transactions].[ID] AS [id], 
     [Transactions].[EncryptedAccountID] AS [encryptedAccountID], 
     [Transactions].[Uploaded] AS [uploaded], 
     [Transactions].[Visible] AS [visible], 
     [Fields].[ID] AS [fieldId], 
     [Fields].[FriendlyName] AS [friendlyName], 
     [Fields].[OfficialName] AS [officialName], 
     [Fields].[Order] AS [order], 
     [Fields].[Visible] AS [valueVisible], 
     [TransactionValues].[ID] AS [valueId], 
     [TransactionValues].[FieldID] AS [valueFieldId], 
     [TransactionValues].[FriendlyValue] AS [friendlyValue], 
     [TransactionValues].[OfficialValue] AS [officialValue], 
     [TransactionValues].[TransactionID] AS [transactionId] 
    FROM 
     [Transactions] 
     INNER JOIN [TransactionValues] 
     ON [TransactionValues].[TransactionID] = [Transactions].[ID] 
     INNER JOIN [Fields] 
     ON [TransactionValues].[FieldID] = .[Fields].[ID] 
    WHERE 
     [Transactions].[EncryptedAccountID] = @encryptedAccountID 
) AS [TransactionInfo] 
WHERE 
    idx > 5 
AND 
    idx <= 20 
ORDER BY 
    [id], [order] ASC 
FOR XML AUTO, ROOT('root') 

Doch diese gibt die folgenden XML

<root> 
    <TransactionInfo idx="" id="" encryptedAccountID="" uploaded="" visible="" fieldId="" friendlyName="" officialName="" order="" valueVisible="" valueId="" valueFieldId="" friendlyValue="" officialValue="" transactionId="" /> 
    <TransactionInfo idx="" id="" encryptedAccountID="" uploaded="" visible="" fieldId="" friendlyName="" officialName="" order="" valueVisible="" valueId="" valueFieldId="" friendlyValue="" officialValue="" transactionId="" /> 
</root> 

Sie können sehen, dass die Einführung der Unter Abfrage der FOR XML-Klausel nicht mehr Nest verursacht hat das Kind ergibt ... aber ich verstehe nicht warum.

Kann mir jemand sagen, wie ich Paginierung über ROW_NUMBER() implementieren kann, und die Ergebnisse wie den ersten Block von XML oben formatiert haben?

Antwort

1

Es ist nicht schön, aber, wie es dazu:

SELECT 
    [Transactions].[ID] AS [id], 
    [Transactions].[EncryptedAccountID] AS [encryptedAccountID], 
    [Transactions].[Uploaded] AS [uploaded], 
    [Transactions].[Visible] AS [visible], 
    [Fields].[ID] AS [fieldId], 
    [Fields].[FriendlyName] AS [friendlyName], 
    [Fields].[OfficialName] AS [officialName], 
    [Fields].[Order] AS [order], 
    [Fields].[Visible] AS [valueVisible], 
    [TransactionValues].[ID] AS [valueId], 
    [TransactionValues].[FieldID] AS [valueFieldId], 
    [TransactionValues].[FriendlyValue] AS [friendlyValue], 
    [TransactionValues].[OfficialValue] AS [officialValue], 
    [TransactionValues].[TransactionID] AS [transactionId], 
    [TransactionValues].idx 
FROM 
    [Transactions] 
    INNER JOIN 
    (
     SELECT *, ROW_NUMBER() OVER(ORDER BY [TransactionValues].[ID]) AS idx 
     FROM [TransactionValues] 
    ) AS [TransactionValues] 
     ON [TransactionValues].[TransactionID] = [Transactions].[ID] 
    INNER JOIN [Fields] 
     ON [TransactionValues].[FieldID] = .[Fields].[ID] 
WHERE 
    [Transactions].[EncryptedAccountID] = @encryptedAccountID 
    AND [TransactionValues].idx BETWEEN 5 AND 20 
FOR XML AUTO, ROOT('root') 
+0

Das erzeugt den Fehler: "Fensterfunktionen können nur in den SELECT- oder ORDER BY-Klauseln angezeigt werden." – awj

+0

@awj Ich habe meine Antwort aktualisiert. Ich glaube, das sollte funktionieren –

+0

Das ist _pretty much_ it, @Justin. Ihre Abfrage gab die falsche Reihenfolge der Verschachtelung zurück (der TransactionValue war am äußersten, innerhalb dessen Field und innerhalb dessen war Transaction). Ich brauchte ein paar Minuten, um das umzustellen. Die neue Unterabfrage, die Sie hinzugefügt haben, erlaubte mir nicht, die Transactions by TransactionValue.ID zu bestellen, also habe ich Transaction einen neuen automatisch zugewiesenen Int hinzugefügt (der nun Teil eines kombinierten Primärschlüssels ist). Zusammengefasst bin ich also mit ein wenig Feingefühl dorthin gekommen. Für die Nachwelt, sollte ich die komplette Abfrage Lösung unten posten? – awj

0

Dank @Justin Pihoney, hier ist meine Lösung:

SELECT 
    [Transactions].[AssignedID], 
    [Transactions].[idx], 
    [Transactions].[ID] AS [id], 
    [Transactions].[EncryptedAccountID] AS [encryptedAccountID], 
    [Transactions].[Uploaded] AS [uploaded], 
    [Transactions].[Visible] AS [visible], 
    [Fields].[ID] AS [id], 
    [Fields].[FriendlyName] AS [friendlyName], 
    [Fields].[OfficialName] AS [officialName], 
    [Fields].[Order] AS [order], 
    [Fields].[Visible] AS [visible], 
    [TransactionValues].[ID] AS [id], 
    [TransactionValues].[FieldID] AS [fieldId], 
    [TransactionValues].[FriendlyValue] AS [friendlyValue], 
    [TransactionValues].[OfficialValue] AS [officialValue], 
    [TransactionValues].[TransactionID] AS [transactionId] 
FROM 
    [TransactionValues] 
    INNER JOIN [Fields] 
    ON [TransactionValues].[FieldID] = .[Fields].[ID] 
    INNER JOIN 
    (
     SELECT *, ROW_NUMBER() OVER(ORDER BY [Transactions].[AssignedID]) AS [idx] 
     FROM [Transactions] 
    ) AS [Transactions] 
    ON [TransactionValues].[TransactionID] = [Transactions].[ID] 
WHERE 
    [Transactions].[EncryptedAccountID] = @EncryptedAccountID 
AND 
    [Transactions].[idx] BETWEEN 5 AND 20 
ORDER BY 
    [Transactions].[AssignedID] 
FOR XML AUTO, ROOT('root') 

Auch nur der Vollständigkeit halber, die "zwischen 5 und 20" wird durch Parameter ersetzt werden.