在 SQL Server 存储过程中拆分文本

Posted

技术标签:

【中文标题】在 SQL Server 存储过程中拆分文本【英文标题】:Splitting text in SQL Server stored procedure 【发布时间】:2012-07-12 23:22:33 【问题描述】:

我正在使用数据库,其中我提取的字段之一是:

1-117 3-134 3-133

这些数字集中的每一个都代表另一个表中的不同数据集。以1-117为例,1=设备ID,117=设备设置。

我有另一个表,我需要根据前一个字段从中提取数据。它有两列拆分设备 ID 和设置。本质上,我需要一种方法从查询的列 1-117 出发并运行查询以从另一个表中提取数据,其中 1 和 117 是两个单独的对应列。

那么,有没有办法拆分这个数字来运行这个查询?

另外,我如何将这三个数字 (1-117 3-134 3-133) 拆分为三个不同的查询集?

这里的棘手部分是此列可以在此处包含任意数量的集合(例如1-117 3-1331-117 3-134 3-133 2-131)。

我正在存储过程中创建这些查询,作为更大文档的一部分,以显示提取的数据。

感谢您的帮助。

【问题讨论】:

不同含义的数据应该在不同的列和/或不同的行中。 有一种方法可以做你想做的事,但你应该真正规范你的数据结构 我明白了。当前的系统非常尴尬。但我只是个实习生,我觉得我改变不了。 数字是否总是用空格分隔?较小的数字总是采用#-### 格式吗? 是的,格式是固定的。 #-### 如果有另一个集合,后面是一个空格。 【参考方案1】:

由于您没有提供数据库供应商,因此这里有两篇文章分别针对 SQL Server 和 Oracle 回答了这个问题...

T-SQL: Opposite to string concatenation - how to split string into multiple records

Splitting comma separated string in a PL/SQL stored proc

如果您使用的是其他 DBMS,请搜索“拆分文本”。我几乎可以保证您不是第一个提出问题的人,而且每种 DBMS 风格都有答案。

正如你所说的格式是不变的,你也可以使用 SUBSTRING 函数做一些更简单的事情。

编辑以响应 OP 评论...

由于您使用的是 SQL Server,并且您说这些值始终采用一致的格式,因此您可以执行一些简单的操作,例如使用 SUBSTRING 获取值的每个部分并将它们分配给 T-SQL 变量,其中然后你可以使用它们来做任何你想做的事情,比如在查询的谓词中使用它们。

【讨论】:

你说得对,我从错误的浏览器选项卡复制/粘贴。我已经编辑过了。【参考方案2】:

假设您所说的格式始终为 #-###(正好是 1 位数字、破折号和 3 位数字)是正确的,这相当容易。

WITH EquipmentSettings AS (
   SELECT
      S.*,
      Convert(int, Substring(S.AwfulMultivalue, V.Value * 6 - 5, 1) EquipmentID,
      Convert(int, Substring(S.AwfulMultivalue, V.Value * 6 - 3, 3) Settings
   FROM
      SourceTable S
      INNER JOIN master.dbo.spt_values V
         ON V.Value BETWEEN 1 AND Len(S.AwfulMultivalue) / 6
   WHERE
      V.type = 'P'
)
SELECT
   E.Whatever,
   D.Whatever
FROM
   EquipmentSettings E
   INNER JOIN DestinationTable D
      ON E.EquipmentID = D.EquipmentID
      AND E.Settings = D.Settings

在 SQL Server 2005+ 中,此查询将支持字符串中的 1365 个值。

如果数字的长度可以变化,那就有点难了。告诉我。

【讨论】:

【参考方案3】:

如果集合不增加超过 4,那么您可以使用 Parsename 检索结果

 Declare @Num varchar(20)
 Set @Num='1-117 3-134 3-133'

 select parsename(replace (@Num,' ','.'),3)

 Result :- 1-117

 Now again use parsename on the same resultset 

 Select parsename(replace(parsename(replace (@Num,' ','.'),3),'-','.'),1)

 Result :- 117

如果值超过 4 个,则使用拆分函数

【讨论】:

以上是关于在 SQL Server 存储过程中拆分文本的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server-在存储过程中查找文本

如何为每次执行将过程结果存储在 SQL Server 中的新(单个)文本文件中

无法从存储过程显示文本到 textview - Android SQL Server

SQL Server 存储过程参数类型转换

SQL Server存储过程文本加密与解密过程详解 2019版可用

在存储过程中通过用户的默认架构进行访问时,在SQL Server中切换用户失败