XML列の出力
Sep 17 2020
SQLServerデータベースと.NETを使用してXMLファイルを生成するコンソールプログラムに取り組んでいます。
現在、適切なXMLファイルを生成するためのコードに固執しています。Categoriesメモ帳でファイルを開いたときにノードがXML形式として正しく識別されず、その結果、ノードを適切に使用できません。
必要なのはこれです:
Categories以下のように適切なXMLタグを生成し、メモ帳で開くときに特殊文字を含めないでください。複数のサイトID(場所)がある場合、SQLテーブルからコードに対してforループを実行するにはどうすればよいですか。
Dim dsXmlDoc As XmlDocument = New XmlDocument() ds.Tables(0).TableName = "Inv" dsXmlDoc.LoadXml(ds.GetXml()) Dim xmlInner As XmlElement = CType(xmlDoc.SelectSingleNode("/Root/"), XmlElement)xmlInner.AppendChild(xmlDoc.ImportNode(dsXmlDoc.DocumentElement, True))
回答
1 CaiusJard Sep 17 2020 at 14:51
私はそれがこれになると思います:
WITH x AS (
SELECT
A.[ORDER ID],
RIGHT(A.[POS ID], 2) AS [LesseePOSNumber],
REPLACE(A.[BUSINESS DATE],'-','') + '-' + A.[RECEIPT NUMBER] AS [InvoiceNumber],
'1' AS [DocumentType],
CAST(A.[BUSINESS DATE] AS datetime) + CAST(A.[START SALE TIME] AS DATETIME) AS [TransactionDateTime],
SUM(A.ITEM) AS [TotalNumberOfItems],
SUM(A.[TOTAL AMOUNT] - A.[TOTAL TAX]) AS [TransactionTotalWithoutVAT],
SUM(A.[TOTAL TAX]) AS [VATTotalAmount],
'1' AS [PaymentType],
'4' AS [Currency]
FROM
(
SELECT
T1.[storeId] AS [STORE NO]
,CONVERT(date,CONVERT(varchar(15),T1.businessDate,101)) AS [BUSINESS DATE]
,FORMAT(CONVERT(datetime,SUBSTRING(T1.startSaleTime,1,2) + ':' + SUBSTRING(T1.startSaleTime,3,2) + ':' + SUBSTRING(T1.startSaleTime,5,2), 121), 'h:mm:ss') AS [START SALE TIME]
,CASE WHEN (T1.Type) = 'TRX_Refund' OR (T1.Type) = 'TRX_Overring' THEN CAST(T1.[totalAmount] AS decimal(16,2)) * -1 ELSE CAST(T1.[totalAmount] AS decimal(16,2)) END AS [TOTAL AMOUNT]
,CASE WHEN (T1.Type) = 'TRX_Refund' OR (T1.Type) = 'TRX_Overring' THEN 0 ELSE 1 END AS [GC]
,CASE WHEN (T1.Type) = 'TRX_Refund' OR (T1.Type) = 'TRX_Overring' THEN CAST(T1.[totalTax] AS decimal(16,2)) * -1 ELSE CAST(T1.[totalTax] AS decimal(16,2)) END AS [TOTAL TAX]
,T1.NodeId AS [POS ID]
,T1.[receiptNumber] AS [RECEIPT NUMBER]
,T1.orderId AS [ORDER ID]
,
(
SELECT SUM(CASE WHEN CAST(T2.totalPrice AS float) > 0.00 THEN 1 ELSE 0 END)
FROM [McDonalds_STG].[dbo].[ITEMLEVEL] T2
WHERE T2.orderId = T1.orderId
) AS [ITEM]
FROM [McDonalds_STG].[dbo].[Orders] T1
) A
GROUP BY
A.[STORE NO],
A.[BUSINESS DATE],
A.[POS ID],
A.[RECEIPT NUMBER],
A.[START SALE TIME],
A.[ORDER ID]
)
SELECT
x.[LesseePOSNumber],
x.[InvoiceNumber],
x.[DocumentType],
x.[TransactionDateTime],
x.[TotalNumberOfItems],
x.[TransactionTotalWithoutVAT],
x.[VATTotalAmount],
x.[PaymentType],
x.[Currency],
(
SELECT
49 AS [ID],
(CAST(T1.[totalAmount] AS decimal(16,2)) - CAST(T1.[totalTax] AS decimal(16,2)) ) AS [Total]
FROM [Order] T2
WHERE T2.orderId = x.[ORDER ID]
FOR XML PATH('Category'), TYPE
) As Categories
FROM x
FOR XML PATH ('Invoice'), root ('Invoices')
ここには、重要で賢明なリファクタリングの機会がまだいくつかあり(日付/文字列/日付の処理は破棄して、可能な場合は文字列を使用せずにやり直す必要があります)、タイプミスの修正が必要になる場合があります。読むのは簡単なSQLではなく、SSMSに直接貼り付けて、調整なしで機能するとは思いません。
GROUP BY STORE NOですが、使用していないように見えることに注意してください
jdweng Sep 17 2020 at 04:23
xml linqを試してください:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, XElement> dict = doc.Descendants("Invoice")
.GroupBy(x => (string)x.Element("LesseePOSNumber"), y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
string lesseePOSNumber = "1";
string id = "29";
int total = 3000;
if (dict.ContainsKey(lesseePOSNumber))
{
XElement categories = new XElement("Categories", new XElement("Category", new object[] {
new XElement("ID", id),
new XElement("Total", total)
}));
dict[lesseePOSNumber].Add(categories);
}
}
}
}