使用 xml 将 csv 值转换为表行。谁能解释一下下面提到的查询将如何工作

Posted

技术标签:

【中文标题】使用 xml 将 csv 值转换为表行。谁能解释一下下面提到的查询将如何工作【英文标题】:Convert csv values into table rows using xml. Can anyone please explain how below mentioned queries will work 【发布时间】:2016-07-21 01:14:02 【问题描述】:

请解释一下这段代码。

CREATE TABLE tbl 
(Name VARCHAR(100),DependsOnCSV VARCHAR(100))

INSERT INTO tbl
VALUES
    ('a','b,c'),
    ('b','d'),
    ('c',''),
    ('d',''),
    ('e','g'),
    ('f','b,e,a,g'),
    ('g',''),
    ('h','a')

CREATE FUNCTION Split
(
  @delimited nvarchar(max),
  @delimiter nvarchar(100)
) RETURNS @t TABLE
(
  id int identity(1,1),
  val nvarchar(max)
)
AS
BEGIN
  declare @xml xml
  set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'

  insert into @t(val)
  select 
    r.value('.','varchar(5)') as item
  from @xml.nodes('//root/r') as records(r)

  RETURN
END
GO

SELECT
  tbl.Name,
  split.val AS [DependsOn-Rows]
FROM tbl AS tbl
CROSS APPLY dbo.Split(tbl.DependsOnCSV,',') split

【问题讨论】:

不要标记多个 DBMS。你曾经为所有这些写过相同的查询吗? 您的评论如何为我的问题提供任何解决方案。@nikhil 这不是一个解决方案,而是一个建议,让这里的人们更认真地对待您的帖子。当 SO 上的某人正在阅读您的帖子时,诸如问题清晰度、正确标签、代码格式等之类的事情很重要,否则他们中的大多数人甚至都不会费心去完成它。无意冒犯,我希望您了解一些事情,因为您是 SO 新手。 @StutiNautiyal 它没有;这就是为什么它被发布为评论,而不是作为答案。但这是一个很好的评论:你使用的是什么数据库?询问有关 SQL Server 的问题并将其标记为“mysql”是没有意义的,因为阅读 MySQL 标签的人不太可能是 SQL Server 专家;你在浪费他们和你的时间。 您已经了解了哪些部分?哪些部分让您感到困惑? 【参考方案1】:

这是我对这个脚本的解释

以下创建一个示例数据库表,其中包含一个对象(名称)及其对另一个字段 (DependsOnCSV) 的依赖项,以逗号分隔

CREATE TABLE tbl (Name VARCHAR(100),DependsOnCSV VARCHAR(100))

以下代码使用示例数据填充上表。对于许多开发人员来说,这是一种新语法。如果您使用的是 SQL2012 的先前版本,则可能必须将其转换为 INSERT INTO .. SELECT ... 每一行

INSERT INTO tbl
VALUES
    ('a','b,c'),
    ('b','d'),
    ('c',''),
    ('d',''),
    ('e','g'),
    ('f','b,e,a,g'),
    ('g',''),
    ('h','a')

以下函数用于split string values in SQL。您可以找到许多类似的功能。 SQL Server 2016 附带内置拆分功能

CREATE FUNCTION Split
(
  @delimited nvarchar(max),
  @delimiter nvarchar(100)
) RETURNS @t TABLE
(
  id int identity(1,1),
  val nvarchar(max)
)
AS
BEGIN
  declare @xml xml
  set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'

  insert into @t(val)
  select 
    r.value('.','varchar(5)') as item
  from @xml.nodes('//root/r') as records(r)

  RETURN
END
GO

此 SELECT 语句通过用“,”逗号分隔 DependendOnCVS 列来返回对象及其每个依赖项

SELECT
  tbl.Name,
  split.val AS [DependsOn-Rows]
FROM tbl AS tbl
CROSS APPLY dbo.Split(tbl.DependsOnCSV,',') split

我希望上面的代码现在可以阅读

【讨论】:

值得一提的是,Split 函数作为可内联 TVF(没有 BEGIN ... END)会更好。此外,文字字​​符串之前的N 应该无处不在。此外,&lt;root&gt; 级别可以省略,.nodes('//root/r') 应该是 .nodes('/root/r') 或 - 没有 &lt;root&gt; 只是 .nodes('/r')。此外,varchar(5) 对于“通用”功能确实不建议使用,最后但并非最不重要的是tbl AS tbl 至少令人困惑:)

以上是关于使用 xml 将 csv 值转换为表行。谁能解释一下下面提到的查询将如何工作的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法使用 KnockoutJS 将 XML 文件转换为 CSV?

AWS Athena 无法将 .csv 整数转换为表值

使用SSIS包将csv列转换为表列的日期格式?

如何使用 Javascript/jquery 将字符串中的数组显示为表行

将 XML 记录转换为表

如何解析 CSV 文件,以便可以被 Mahout 分类