Sql 将包含类XML数据的varchar列解析为行

Sql 将包含类XML数据的varchar列解析为行,sql,sql-server,tsql,Sql,Sql Server,Tsql,我在表中有一列包含XML之类的数据,我希望以行的形式获取数据 我的表数据为- select printDataColumn from Mytable 它返回值- <PrintData> <Line1>.MERCHANT ID: *****4005</Line1> <Line2>.CLERK ID: ADMIN</Line2> <Line3>.</Line3> <Lin

我在表中有一列包含XML之类的数据,我希望以行的形式获取数据

我的表数据为-

select printDataColumn from Mytable 
它返回值-

  <PrintData>
    <Line1>.MERCHANT ID: *****4005</Line1>
    <Line2>.CLERK ID: ADMIN</Line2>
    <Line3>.</Line3>
    <Line4>.                VOID SALE</Line4>
    <Line5>.</Line5>
    <Line6>.VISA                   ************0006</Line6>
    <Line7>.ENTRY METHOD: SWIPED</Line7>
    <Line8>.DATE: 03/05/2019  TIME: 16:57:20</Line8>
    <Line9>.</Line9>
    <Line10>.INVOICE: 1551785225020</Line10>
    <Line11>.REFERENCE: 1008</Line11>
    <Line12>.AUTH CODE: 08354A</Line12>
    <Line13>.</Line13>
    <Line14>.AMOUNT                       USD$ 1.14</Line14>
    <Line15>.                            ==========</Line15>
    <Line16>.TOTAL                        USD$ 1.14</Line16>
    <Line17>.</Line17>
    <Line18>.          APPROVED - THANK YOU</Line18>
    <Line19>.</Line19>
    <Line20>.I AGREE TO PAY THE ABOVE TOTAL AMOUNT</Line20>
    <Line21>.ACCORDING TO CARD ISSUER AGREEMENT</Line21>
    <Line22>.(MERCHANT AGREEMENT IF CREDIT VOUCHER)</Line22>
    <Line23>.</Line23>
    <Line24>.</Line24>
    <Line25>.</Line25>
    <Line26>.x_______________________________________</Line26>
    <Line27>.           Merchant Signature</Line27>
    <Line28>.</Line28>
  </PrintData>

任何帮助都是值得赞赏的。

除了使用适当的类型存储数据总是一个好主意之外,您还可以使用动态转换将类似xml的数据与xml方法结合使用:

DECLARE @tbl TABLE(ID INT IDENTITY,PrintData VARCHAR(4000));
INSERT INTO @tbl VALUES
('<PrintData>
    <Line1>.MERCHANT ID: *****4005</Line1>
    <Line2>.CLERK ID: ADMIN</Line2>
    <Line3>.</Line3>
    <Line4>.                VOID SALE</Line4>
    <!-- more lines -->
  </PrintData>');

  SELECT t.ID
        ,A.Casted.value(N'(/PrintData/Line1/text())[1]','nvarchar(max)') AS Line1
  FROM @tbl t
  CROSS APPLY(SELECT CAST(t.PrintData AS XML)) A(Casted);
DECLARE@tbl表(ID INT-IDENTITY,printdatavarchar(4000));
插入@tbl值
('
.商户ID:****4005
.职员编号:ADMIN
.
1.无效销售
');
选择t.ID
,A.Casted.value(N'(/PrintData/Line1/text())[1],'nvarchar(max')作为第1行
来自@tbl t
交叉应用(选择CAST(t.printdataasxml))A(Casted);
在本例中,我使用
CROSS-APPLY
将列
a.Casted
添加到结果集中,这是一个按行浇筑的XML

当然,在XML无效的情况下,这会中断。您可以试试
试试\u CAST
。这将返回
NULL
,但将隐藏数据错误

更多背景资料
转换为XML是一项相当昂贵的操作。每当您想要读取数据时,执行此操作对您的服务器来说是一个沉重的负担。此外,使用
VARCHAR
容易出现两个主要错误:

  • 如果有外来字符,您可能会得到问号
  • 如果XML无效,在使用它之前,您将无法看到它
如果可能,尝试将表的设计更改为使用原生XML

还有一个提示

命名数字元素是一种不好的方法(列也是如此)。与其使用
不如使用

到目前为止,您尝试了什么?
DECLARE @tbl TABLE(ID INT IDENTITY,PrintData VARCHAR(4000));
INSERT INTO @tbl VALUES
('<PrintData>
    <Line1>.MERCHANT ID: *****4005</Line1>
    <Line2>.CLERK ID: ADMIN</Line2>
    <Line3>.</Line3>
    <Line4>.                VOID SALE</Line4>
    <!-- more lines -->
  </PrintData>');

  SELECT t.ID
        ,A.Casted.value(N'(/PrintData/Line1/text())[1]','nvarchar(max)') AS Line1
  FROM @tbl t
  CROSS APPLY(SELECT CAST(t.PrintData AS XML)) A(Casted);