我正在尝试从我的表中删除多个空格,其中包含40多个包含字符串值且大约150K行的列。
使用CURSOR,我提出了以下解决方案(作为填充我的表的存储过程的一部分),但是这不会在单次运行中删除空格。如果我多次手动单独运行update语句,则会完全删除空格。关于如何在单次运行中清理数据的任何想法?
Declare @col nvarchar(128)
Declare StringCol CUSRSOR for
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName'
AND DATA_TYPE = 'varchar'
OPEN StringCol
FETCH NEXT FROM StringCol into @col;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE TableName
SET @col = LTRIM(RTRIM(REPLACE(@col, ' ', ' ')))
WHERE @col LIKE '% %'
FETCH NEXT FROM StringCol into @col
END
CLOSE StringCol
Deallocate StringCol
END
答案 0 :(得分:0)
如果您有SQL Server 2016,则可以将STRING_Split
或类似的UDF函数用于其他版本。诀窍是将单词转换为列,取非空格并将它们带回一个值
Declare @col nvarchar(128)
Declare StringCol CUSRSOR for
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName'
AND DATA_TYPE = 'varchar'
OPEN StringCol
FETCH NEXT FROM StringCol into @col;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE TableName
SET @col = CONVERT(VARCHAR(MAX),
(
select Value + ' '
from STRING_SPLIT (@col, ' ')
where value <>'' for xml path('')
)
)
WHERE @col LIKE '% %'
FETCH NEXT FROM StringCol into @col
END
CLOSE StringCol
Deallocate StringCol
END
如果您使用pre-SQL Server 2016,那么这是一个UDF STRING_SPLIT
函数:
CREATE FUNCTION [dbo].[STRING_SPLIT]
(
@String nvarchar(max), -- String to be parsed
@Delm nchar(1)=','
)
returns @Table TABLE (/*ID int identity(1,1), */ value nvarchar(max))
Begin
INSERT @Table(value)
SELECT ltrim(t.val.value('.', 'VARCHAR(100)')) AS value
FROM(
SELECT Convert(XML, '<M>' + REPLACE(@String, @Delm, '</M><M>') + '</M>') AS x
) AS A CROSS APPLY x.nodes ('/M') AS t(val)
Return
End
答案 1 :(得分:0)
尝试
-- code #1
CREATE FUNCTION [dbo].[AllTrim] (@Texto varchar(8000))
returns table as
return
with xTrim as (
SELECT Rep= 1,
Trimmed= Replace(Ltrim(Rtrim(@Texto)), space(2), space(1))
union all
SELECT Charindex(space(2), Trimmed),
Replace(Trimmed, space(2), space(1))
from xTrim
where Rep > 0
)
SELECT Trimmed
from xTrim
where Rep = 0;
go
使用演示:
-- code #2
declare @TableName table (col1 varchar(200), col2 varchar(800));
INSERT into @TableName values
(' aa aaa aaaa a ', 'b b ');
SELECT T1.col1, T2.Trimmed as [col1 trimmed],
T1.col2, T3.Trimmed as [col2 trimmed]
from @TableName as T1
outer apply dbo.AllTrim(T1.col1) as T2
outer apply dbo.AllTrim(T1.col2) as T3;
演示更新:
-- code #3
declare @TableName table (ID int identity,
col1 varchar(200), col2 varchar(800));
INSERT into @TableName (col1, col2) values
(' aa aaa aaaa a ', 'b b '),
('xxx xx xx xxxxx', NULL);
with tbTrimmed as (
SELECT T1.ID,
T2.Trimmed as [col1 trimmed],
T3.Trimmed as [col2 trimmed]
from @TableName as T1
outer apply dbo.AllTrim(T1.col1) as T2
outer apply dbo.AllTrim(T1.col2) as T3
)
UPDATE TN
set col1= [col1 trimmed],
col2= [col2 trimmed]
from @TableName as TN
inner join tbTrimmed as Tr on TN.ID = Tr.ID;
答案 2 :(得分:0)
使用CLR函数可以使用正则表达式执行此操作:
Declare cnvarchar(max)
Declare @col nvarchar(128)
Declare StringCol CUSRSOR for
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'TableName'
AND DATA_TYPE = 'varchar'
OPEN StringCol
FETCH NEXT FROM StringCol into @col;
WHILE @@FETCH_STATUS = 0
BEGIN
--{ this is the key bit
set @sql ='
UPDATE TableName
SET ' + quotename(@col) + ' = dbo.RegexReplace(ltrim(rtrim(' + quotename(@col) + ')), ''\s\s+'', ' '
WHERE ' + quotename(@col) + ' LIKE ''% %''
or ' + quotename(@col) + ' LIKE '' %''
or ' + quotename(@col) + ' LIKE ''% ''
'
--} this is the key bit
--print @sql --for debugging
exec @sql
FETCH NEXT FROM StringCol into @col
END
CLOSE StringCol
Deallocate StringCol
END
有关相关的CLR代码,请参阅https://msdn.microsoft.com/en-us/library/ff878119.aspx。