SQL Server替换,删除某些字符后的所有字符
我的数据看起来像SQL Server替换,删除某些字符后的所有字符,sql,sql-server,tsql,replace,Sql,Sql Server,Tsql,Replace,我的数据看起来像 ID MyText 1 some text; some more text 2 text again; even more text 如何更新MyText以删除分号之后的所有内容,包括分号,因此我只剩下以下内容: ID MyText 1 some text 2 text again 我已经看过了,但想不出一种可行的方法来检查“;”使用CHARINDEX查找“;”。然后使用子字符串仅返回“;”之前的零件使用LEFT和CHARINDE
ID MyText
1 some text; some more text
2 text again; even more text
如何更新MyText以删除分号之后的所有内容,包括分号,因此我只剩下以下内容:
ID MyText
1 some text
2 text again
我已经看过了,但想不出一种可行的方法来检查“;”使用
CHARINDEX
查找“;”。然后使用子字符串
仅返回“;”之前的零件使用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)
对于某些字段有“;”而某些字段没有“;”的情况,您也可以在字段中添加分号,并使用所述的相同方法
SET MyText = LEFT(MyText+';', CHARINDEX(';',MyText+';')-1)
可以在时使用大小写来保留没有“;”的内容独自一人
SELECT
CASE WHEN CHARINDEX(';', MyText) > 0 THEN
LEFT(MyText, CHARINDEX(';', MyText)-1) ELSE
MyText END
FROM MyTable
对于需要替换或匹配(查找)字符串的情况,我更喜欢使用正则表达式 由于在
T-SQL
中不完全支持正则表达式,因此可以使用CLR
函数实现它们。此外,您根本不需要任何C#
或CLR
知识,因为您所需要的一切都已在MSDN中提供
在您的情况下,使用正则表达式的解决方案是:
SELECT [dbo].[RegexReplace] ([MyColumn], '(;.*)', '')
FROM [dbo].[MyTable]
但是在数据库中实现这样的功能将帮助您解决更复杂的问题
下面的示例显示了如何仅部署
[dbo].[RegexReplace]
函数,但我建议您部署整个字符串实用程序
类
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO
.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
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); } }
- 替换以下
语句中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
如果MyText不包含“;”怎么办性格在这种情况下,在left()中不使用负1作为第二个参数吗。在这种情况下,在我的框中,我得到了一个错误“传递给子字符串函数的长度参数无效”。@Mike这正是我的问题atm-请参阅@najmeddine的下一个答案@Mike Rashlien下面的回答解决了这个问题:LEFT(MyText+';',CHARINDEX(';',MyText+';')-1)注意上面的WHERE子句跳过了没有分号的行。OP希望删除分号及其后的任何文本。如果没有分号,则没有要删除的内容,因此UPDATE语句将跳过该行。使用一些测试用例更新了此答案,以显示它如何处理缺少的分号、null、空字符串和其他分号。