【问题标题】:SQL statement which returns id and splits comma separated values返回 id 并拆分逗号分隔值的 SQL 语句
【发布时间】:2011-09-08 03:34:57
【问题描述】:

我有一个包含以下数据的表格:

节点 ID 外部 ID 50 601 56 700,701

如何编写分割 ExternalIds 列并返回的 SQL 语句:

节点 ID 外部 ID 50 601 56 700 56 701

我发现了很多用户定义的函数和过程,它们将字符串拆分成一个表,但我无法让它们中的任何一个工作

编辑

创建表 #tmpTable (NodeId int, ExternalIds varchar(50)) 插入 #tmpTable (NodeId,ExternalIds) 值 (50, '600') 插入 #tmpTable (NodeId,ExternalIds) 值 (56, '700,701') 选择节点ID, (SELECT * FROM [dbo].[SplitString](select * from #tmpTable,',') where NodeId=56)from #tmpTable) 其中节点 ID=56 删除表#tmpTable

其中 SplitString 基于以下内容:

设置 ANSI_NULLS ON 走 设置 QUOTED_IDENTIFIER ON 走 创建函数 [dbo].[SplitString] ( -- 在此处添加函数的参数 @myString varchar(500), @deliminator varchar(10) ) 回报 @ReturnTable 表 ( -- 在此处添加 TABLE 变量的列定义 [id] [int] IDENTITY(1,1) 非空, [部分] [varchar](50) NULL ) 作为 开始 声明@iSpaces int 声明@part varchar(50) --初始化空格 选择@iSpaces = charindex(@deliminator,@myString,0) 而@iSpaces > 0 开始 选择@part = substring(@myString,0,charindex(@deliminator,@myString,0)) 插入@ReturnTable(part) 选择@part 选择@myString = substring(@mystring,charindex(@deliminator,@myString,0)+ len(@deliminator),len(@myString) - charindex(' ',@myString,0)) 选择@iSpaces = charindex(@deliminator,@myString,0) 结尾 如果 len(@myString) > 0 插入@ReturnTable 选择@myString 返回 结尾

我正在尝试从 Umbraco(cms)的数据库中获取一些数据,该数据库是用逗号分隔的值设计的。

谢谢 托马斯

【问题讨论】:

  • 请说明当您尝试让这些功能发挥作用时发生了什么。
  • “我发现了很多用户定义的函数和过程,它们将字符串拆分成一个表,但我无法让它们中的任何一个工作”你试过什么?
  • 也许您应该正确设计您的数据库。数据几乎不应该存储在分隔列表中。
  • @HLGEM。也许这是为了将数据迁移到 1NF 中的表?
  • 嗨。我用我当前的 sql 更新了问题

标签: sql-server


【解决方案1】:
select NodeId, 
       S.part
from #tmpTable
  cross apply [dbo].[SplitString](ExternalIds, ',') as S

【讨论】:

  • 嗨,Mikael,我尝试了您的解决方案,但令我惊讶的是,我的一些值在最后一个字母处被截断。我的问题与 Thomas 发布的完全相同,除了我的列表是 ;和空格分隔。例如,我有 product_Name 作为 PS CAS; SECURITY SOURCEONE,当应用 fxn 时,一列显示为 SECURITY SOURCEON,末尾缺少“E”。任何想法? TIA。
  • @Nemo 我猜拆分字符串函数不会将空格作为分隔符处理。你使用的和这里的问题一样吗?它不是很有效。看看here 的替代品。
  • @Mikael- Ty 获取信息。我去了你发布的链接。我想通过使用 SQLCLR 函数删除分号后的空格。所以我的列 product_Name 看起来像 PS CAS;SECURITY SOURCEONE 现在我关心的是如何使用上面的 SplitString fxn 为具有 product_Name 的每个 ID 获取新行,例如 PS CAS;SECURITY SOURCEONE w/o?我是 SQLCLR 的新手,但它似乎擅长处理这些问题。不知道如何。 :( 有什么帮助吗?
  • @Nemo 您应该将其作为一个新问题提出,以便其他人有机会回答或将您指向其他资源或其他有您需要的答案的问题。
  • 提建议。会的。
【解决方案2】:

下面是一个快速示例,说明如何将数据光标移至所需格式。请注意,这更像是一个当前不使用拆分功能的快速演示。我会做两个cmets: - 应该避免使用 imo 光标 - 作为 以上评论者建议尝试 避免存储分隔数据

DECLARE @Table TABLE
(
    NodeId int,
    ExternalID int
)
DECLARE @NodeId int
DECLARE @ExternalIds nvarchar(2000)

DECLARE db_cursor CURSOR FOR  
SELECT NodeId, ExternalIDs
from dbo.test

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @NodeId, @ExternalIds   

WHILE @@FETCH_STATUS = 0   
BEGIN   
    WHILE (Charindex(',',@ExternalIds)>0)
    Begin
        INSERT INTO @Table (NodeId, ExternalId)
        SELECT @NodeId, 
            Data = ltrim(rtrim(Substring(@ExternalIds,1,Charindex(',',@ExternalIds)-1)))

        SET @externalids = Substring(@ExternalIds,Charindex(',',@ExternalIds)+1,len(@ExternalIds))
    End

    INSERT INTO @Table (NodeId, ExternalId)
    Select @NodeId, Data = ltrim(rtrim(@ExternalIds))

    FETCH NEXT FROM db_cursor INTO @NodeId, @ExternalIds  
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

SELECT * FROM @Table

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多