【问题标题】:How do I get an int from a string that may contain dates in SQL?如何从可能包含 SQL 日期的字符串中获取 int?
【发布时间】:2016-05-10 16:39:29
【问题描述】:

我必须从第三方工具中获取一个包含整数的字符串,剥离 int,并使用它来连接本地表。我正在使用Pinal Dave's udf_GetNumeric function,它对I worked on ticket no. 123456 for a long time 非常有效,但现在用户正在输入类似5/9/2016 ticket 123456 was closed as duplicate 的内容,它返回5092016123456。我可以将搜索模式修改为仅查看 5 个或更多连续数字,因为我们的 ID 列 > 9999,但 sql 不理解 ([0-9]{5,})。不幸的是,我无法安装 CLR 来使用完整的正则表达式。

【问题讨论】:

  • 你能假设所有的数字都用空格隔开吗?如果您将文本从空格拆分为单独的行并取一行仅包含数字?
  • 您的问题不清楚。向我们展示一些数据和期望的输出。您要应用的逻辑是什么?为什么你的意思是 Sql 不理解正则表达式?请阅读How-to-Ask 这里是START 了解如何提高问题质量并获得更好答案的好地方。
  • 抱歉措辞尴尬。基本上,我有“这是一个字符串 123456 blah blah blah 5/09/2016”,我想得到 123456。是的,我想我可以假设数字会用空格分隔,所以我可以试试。 Sql 确实理解正则表达式,但它是一个有限的子集。

标签: sql-server regex validation date


【解决方案1】:

我可以将搜索模式修改为仅查看 5 个或更多 连续数字,因为我们的 ID 列 > 9999,但 sql 没有 了解 ([0-9]{5,})。我无法安装 CLR

然后您可以修改搜索模式以使用%[0-9][0-9][0-9][0-9][0-9]%。这将找到 5 个连续整数的字符串。例如如下。

WITH T(Notes)
     AS (SELECT 'I worked on ticket no 123456.  for a long time ')
SELECT *,
       SUBSTRING(Notes, PatIdx, Length)
FROM   T
       CROSS APPLY (SELECT PATINDEX('%[0-9][0-9][0-9][0-9][0-9]%', Notes)) CA(PatIdx)
       CROSS APPLY (SELECT PATINDEX('%[^0-9]%', SUBSTRING(Notes + ' ', PatIdx, 8000)) - 1) CA2(Length) 

【讨论】:

  • 谢谢,马丁。这暂时可行,但 123456 是一个标识列,最终会有超过 5 或 6 个数字,但未来足够长,我可能不必担心它。
  • 好吧,如果有 6 个连续数字,则找到 5 的模式将找到 6。但是找到起点后,您可能应该寻找从该点开始的第一个非整数。将编辑。
  • 谢谢!这也有效,而且比我的回答要少。
  • @DavidFrodin - 它也不依赖于被空格包围的数字。
【解决方案2】:

使用 JamesZ 的分割空间的建议,我重新利用了我在其他地方使用的旧函数。

CREATE FUNCTION [dbo].[tvf_CreateVarcharTableFromCsv]
    (
      @VarcharCsv VARCHAR(4000) ,
      @Seperator VARCHAR(5) = NULL
    )
RETURNS @VarcharTable TABLE
    (
      VarcharIndex VARCHAR(50) NOT NULL
    )
AS
    BEGIN
        DECLARE @localVarcharIndexList VARCHAR(4000);  
        DECLARE @localSeperator VARCHAR(5);  
        SET @localVarcharIndexList = @VarcharCsv;
        SET @localSeperator = @Seperator;
        IF @localSeperator IS NULL
            SET @localSeperator = ',';

        /*****************************************************************************************
        Parse CSVs into tables with CTE
        http://www.simple-talk.com/sql/t-sql-programming/sql-server-2005-common-table-expressions/
        *****************************************************************************************/
        IF @localVarcharIndexList IS NOT NULL
            BEGIN
                WITH    VarcharCsv ( i, j, VarcharIndex )
                          AS ( SELECT   i = 1 ,
                                        VarcharIndex = CHARINDEX(@localSeperator,
                                                              @localVarcharIndexList
                                                              + @localSeperator) ,
                                        SUBSTRING(@localVarcharIndexList, 1,
                                                  CHARINDEX(@localSeperator,
                                                            @localVarcharIndexList
                                                            + @localSeperator)
                                                  - 1)
                               UNION ALL
                               SELECT   i = j + 1 ,
                                        j = CHARINDEX(@localSeperator,
                                                      @localVarcharIndexList
                                                      + @localSeperator, j + 1) ,
                                        SUBSTRING(@localVarcharIndexList,
                                                  j + 1,
                                                  CHARINDEX(@localSeperator,
                                                            @localVarcharIndexList
                                                            + @localSeperator,
                                                            j + 1) - ( j + 1 ))
                               FROM     VarcharCsv
                               WHERE    CHARINDEX(@localSeperator,
                                                  @localVarcharIndexList
                                                  + @localSeperator, j + 1) <> 0
                             )
                    INSERT  INTO @VarcharTable
                            SELECT  VarcharIndex
                            FROM    VarcharCsv
                    OPTION  ( MAXRECURSION 500 );
            END;
        RETURN; 
    END;

它可以像这样用于我的要求:

SELECT  *
FROM    [tvf_CreateVarcharTableFromCsv]('here is a string 123456 blah blah blah 5/09/2016"',
                                        ' ')
WHERE   LEN(VarcharIndex) > 5
        AND ISNUMERIC(VarcharIndex) = 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 2020-11-12
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    • 2021-12-08
    • 2018-05-27
    相关资源
    最近更新 更多