【问题标题】:Splitting A String into Multiple Values in SQL Server 2000在 SQL Server 2000 中将字符串拆分为多个值
【发布时间】:2019-04-22 23:14:49
【问题描述】:

我代表为我的客户工作的某个人提出这个问题,该客户问我这个问题。我其实比 SQL Server 更熟悉 mySQL,但不幸的是,SQL Server 是客户端使用多年的东西。

问题基本上是这样的:SQL Server 中有没有办法将字符串拆分为多个值(例如数组?),这些值可以在 WHERE 语句中使用。

这是我所说的 PHP 示例。

<?php
    $string = "10,11,12,13";
    $explode = explode(",", $string);
?>

$explode 将等于 array(10,11,12,13)​​。我需要做的是这样的:

SELECT {long field list] FROM {tables} WHERE hour IN SPLIT(",", "10,11,12,13")

SPLIT 是我执行拆分的伪代码函数

我之所以没有在 PHP 中执行此操作,是因为查询是由报告软件构建的,我们无法在将其发送到数据库之前执行逻辑(例如我的 PHP 代码),并且软件将多个值作为由管道 (|) 分隔的单个字符串返回。

不幸的是,我无法访问报告软件(我想他说它叫做 Logi 或 LogiReports 或其他什么)或我的同事正在起草的查询,但对于这个问题,真正重要的是 WHERE 子句。

有什么想法吗?

【问题讨论】:

  • 这被标记为sql server 2000;如果实际上是 2005 年,那么有一个新的表值用户定义函数可以很好地完成这类事情
  • 哈哈,你不知道我说了多少“如果这些人使用 2005 就好了”——我已经说过很多事情,包括缺少 HashBytes() 函数.不幸的是,它是服务器 2000。

标签: sql-server tsql sql-server-2000


【解决方案1】:

可以使用动态SQL:

declare @in varchar(10)
set @in = '10,11,12,13'
exec ('SELECT {long field list] FROM {tables} WHERE hour IN (' + @in + ')')

【讨论】:

  • 这实际上似乎是最实用的解决方案。我已经在一个带有客户 ID 的简单查询中进行了尝试,并且效果很好。我已将此转发给我的同事。
  • 注意:动态 SQL 的性能不是很好。它每次都重新编译 SQL 语句并重建执行计划。但如果它不经常使用或不需要硬计划,它似乎是合理的。
【解决方案2】:

这里有几种方法:Arrays and list in SQL Server

对于短字符串,我更喜欢numbers table

我可以从这里复制/粘贴,但它真的值得一读

【讨论】:

  • 我不确定这是否适用于我的情况,因为从技术上讲,他所做的不是我的合同描述的项目,但我会将链接转发给他,并假设编写良好的指南很有用。
【解决方案3】:

你可以使用一个函数,它接收一个包含由管道分隔的“id”的字符串,并将它作为一个表返回,你可以在子查询中查询和使用,如下所示:

SELECT {long field list] FROM {tables} WHERE hour IN 
(SELECT OrderID from dbo.SplitOrderIDs('2001,2002'))


ALTER FUNCTION [dbo].[SplitOrderIDs]
(
@OrderList varchar(500)
)
RETURNS 
@ParsedList table
(
OrderID int
)
    AS
    BEGIN
    DECLARE @OrderID varchar(10), @Pos int

SET @OrderList = LTRIM(RTRIM(@OrderList))+ ','
SET @Pos = CHARINDEX(',', @OrderList, 1)

IF REPLACE(@OrderList, ',', '') <> ''
BEGIN
    WHILE @Pos > 0
    BEGIN
        SET @OrderID = LTRIM(RTRIM(LEFT(@OrderList, @Pos - 1)))
        IF @OrderID <> ''
        BEGIN
            INSERT INTO @ParsedList (OrderID) 
            VALUES (CAST(@OrderID AS int)) --Use Appropriate conversion
        END
        SET @OrderList = RIGHT(@OrderList, LEN(@OrderList) - @Pos)
        SET @Pos = CHARINDEX(',', @OrderList, 1)

    END
END 

RETURN
END

【讨论】:

    【解决方案4】:

    你可以使用这个存储过程。
    我希望这对你有用。


    CREATE PROCEDURE SP_STRING_SPLIT (@String varchar(8000),@Separator Char(10),@pos_select int=0)
    
    AS
    
    BEGIN
    
    SET NOCOUNT ON
    
    DECLARE @Caracter varchar(8000)
    
    DECLARE @Pos int
    
    Set @Pos=1
    
    Set @Caracter=''
    
    CREATE TABLE #ARRAY
        (   String  varchar(8000)   NOT NULL,
            Pos     int         NOT NULL IDENTITY (1, 1)
    
        )
    
    
    While (@Pos<=len(@String))
    Begin
    
        If substring(@String,@Pos,1)=Ltrim(Rtrim(@Separator))
            Begin
    
                INSERT INTO #ARRAY SELECT @Caracter
                SET @Caracter=''
            End
        Else
            Begin   
                --forma la palabra}
                Set @Caracter=@Caracter+substring(@String,@Pos,1)
    
            End
    
    
        If @Pos=len(@String)
            Begin
                INSERT INTO #ARRAY SELECT @Caracter
            End
    
            SET @Pos=@Pos+1
    
        End
    
         SELECT Pos,String FROM #ARRAY where (Pos=@pos_select Or @pos_select=0)
    END
    
     GO
    
     exec SP_STRING_SPLIT  'HELLO, HOW ARE YOU?',',',0
    

    【讨论】:

      猜你喜欢
      • 2017-01-16
      • 2016-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 2019-07-19
      相关资源
      最近更新 更多