【问题标题】:SQL Server replace, remove all after certain characterSQL Server替换,删除特定字符后的所有内容
【发布时间】:2010-12-12 16:27:59
【问题描述】:

我的数据看起来像

ID    MyText
1     some text; some more text
2     text again; even more text

如何更新 MyText 以删除分号之后的所有内容,包括分号,所以我只剩下以下内容:

ID    MyText
1     some text
2     text again

我查看了SQL Server Replace,但想不出检查“;”的可行方法

【问题讨论】:

    标签: sql sql-server tsql replace


    【解决方案1】:

    将 LEFT 与 CHARINDEX 结合使用:

    UPDATE MyTable
    SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1)
    WHERE CHARINDEX(';', MyText) > 0
    

    请注意,WHERE 子句会跳过更新没有分号的行。

    这里有一些代码来验证上面的 SQL 是否有效:

    declare @MyTable table ([id] int primary key clustered, MyText varchar(100))
    insert into @MyTable ([id], MyText)
    select 1, 'some text; some more text'
    union all select 2, 'text again; even more text'
    union all select 3, 'text without a semicolon'
    union all select 4, null -- test NULLs
    union all select 5, '' -- test empty string
    union all select 6, 'test 3 semicolons; second part; third part;'
    union all select 7, ';' -- test semicolon by itself    
    
    UPDATE @MyTable
    SET MyText = LEFT(MyText, CHARINDEX(';', MyText) - 1)
    WHERE CHARINDEX(';', MyText) > 0
    
    select * from @MyTable
    

    我得到以下结果:

    id MyText
    -- -------------------------
    1  some text
    2  text again
    3  text without a semicolon
    4  NULL
    5        (empty string)
    6  test 3 semicolons
    7        (empty string)
    

    【讨论】:

    • 如果 MyText 不包含 ';' 怎么办?特点?在这种情况下,您不会使用负 1 作为 left() 中的第二个参数吗?在这种情况下,在我的盒子上,我收到“传递给子字符串函数的长度参数无效”的错误。
    • @Mike 这正是我的问题 atm - 请参阅@najmeddine 的下一个答案!
    • @Mike Rashlien 下面的回复解决了这个问题:LEFT(MyText+';', CHARINDEX(';',MyText+';')-1)
    • 请注意,上面的 WHERE 子句会跳过没有分号的行。 OP 想删除分号和它后面的任何文本。如果没有分号,则没有要删除的内容,因此 UPDATE 语句将跳过该行。
    • 用一些测试用例更新了这个答案,以展示它如何处理缺少的分号、NULL、空字符串和额外的分号。
    【解决方案2】:

    对于某些字段有“;”的时候有些没有,您也可以在字段中添加分号并使用描述的相同方法。

    SET MyText = LEFT(MyText+';', CHARINDEX(';',MyText+';')-1)
    

    【讨论】:

      【解决方案3】:

      可以使用CASE WHEN 让那些没有';'的人离开独自的。

          SELECT
          CASE WHEN CHARINDEX(';', MyText) > 0 THEN
          LEFT(MyText, CHARINDEX(';', MyText)-1) ELSE
          MyText END
          FROM MyTable
      

      【讨论】:

        【解决方案4】:
        UPDATE MyTable
           SET MyText = SUBSTRING(MyText, 1, CHARINDEX(';', MyText) - 1)
         WHERE CHARINDEX(';', MyText) > 0 
        

        【讨论】:

          【解决方案5】:

          使用CHARINDEX 查找“;”。然后使用SUBSTRING 只返回“;”之前的部分。

          【讨论】:

            【解决方案6】:

            对于需要替换或匹配(查找)字符串的情况,我更喜欢使用正则表达式。

            由于T-SQL 不完全支持正则表达式,您可以使用CLR 函数来实现它们。此外,您根本不需要任何 C#CLR 知识,因为您需要的所有知识都已在 MSDN String Utility Functions Sample 中提供。

            在您的情况下,使用正则表达式的解决方案是:

            SELECT [dbo].[RegexReplace] ([MyColumn], '(;.*)', '')
            FROM [dbo].[MyTable]
            

            但是在你的数据库中实现这样的功能将帮助你解决更复杂的问题。


            下面的例子展示了如何只部署[dbo].[RegexReplace]函数,但我会建议你部署整个String Utility类。

            1. 启用 CLR 集成。执行以下 Transact-SQL 命令:

              sp_configure 'clr enabled', 1
              GO
              RECONFIGURE
              GO  
              
            2. 构建代码(或创建.dll)。通常,您可以使用 Visual Studio 或 .NET Framework 命令提示符执行此操作(如文章中所示),但我更喜欢使用 Visual Studio。

              • 新建类库项目:

              • 将以下代码复制并粘贴到Class1.cs 文件中:

                using System;
                using System.IO;
                using System.Data.SqlTypes;
                using System.Text.RegularExpressions;
                using Microsoft.SqlServer.Server;
                
                public sealed class RegularExpression
                {
                    public static string Replace(SqlString sqlInput, SqlString sqlPattern, SqlString sqlReplacement)
                    {
                        string input = (sqlInput.IsNull) ? string.Empty : sqlInput.Value;
                        string pattern = (sqlPattern.IsNull) ? string.Empty : sqlPattern.Value;
                        string replacement = (sqlReplacement.IsNull) ? string.Empty : sqlReplacement.Value;
                        return Regex.Replace(input, pattern, replacement);
                    }
                }
                
              • 构建解决方案并获取创建的.dll 文件的路径:

              • 在以下T-SQL语句中替换.dll文件的路径并执行它们:

                IF OBJECT_ID(N'RegexReplace', N'FS') is not null
                DROP Function RegexReplace;
                GO
                
                IF EXISTS (SELECT * FROM sys.assemblies WHERE [name] = 'StringUtils')
                DROP ASSEMBLY StringUtils;
                GO
                
                DECLARE @SamplePath nvarchar(1024)
                -- You will need to modify the value of the this variable if you have installed the sample someplace other than the default location.
                Set @SamplePath = 'C:\Users\gotqn\Desktop\StringUtils\StringUtils\StringUtils\bin\Debug\'
                CREATE ASSEMBLY [StringUtils] 
                FROM @SamplePath + 'StringUtils.dll'
                WITH permission_set = Safe;
                GO
                
                
                CREATE FUNCTION [RegexReplace] (@input nvarchar(max), @pattern nvarchar(max), @replacement nvarchar(max))
                RETURNS nvarchar(max)
                AS EXTERNAL NAME [StringUtils].[RegularExpression].[Replace]
                GO
                
              • 就是这样。测试你的功能:

                declare @MyTable table ([id] int primary key clustered, MyText varchar(100))
                insert into @MyTable ([id], MyText)
                select 1, 'some text; some more text'
                union all select 2, 'text again; even more text'
                union all select 3, 'text without a semicolon'
                union all select 4, null -- test NULLs
                union all select 5, '' -- test empty string
                union all select 6, 'test 3 semicolons; second part; third part'
                union all select 7, ';' -- test semicolon by itself    
                
                SELECT [dbo].[RegexReplace] ([MyText], '(;.*)', '')
                FROM @MyTable
                
                select * from @MyTable
                

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-03
              • 2016-01-14
              相关资源
              最近更新 更多