Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何从作为另一个字符串的子字符串的括号中删除尾随空格_Sql Server_Tsql_Data Cleaning - Fatal编程技术网

Sql server 如何从作为另一个字符串的子字符串的括号中删除尾随空格

Sql server 如何从作为另一个字符串的子字符串的括号中删除尾随空格,sql-server,tsql,data-cleaning,Sql Server,Tsql,Data Cleaning,我使用的是SQL,一些列值表示为{3P Test}*1+0.45% 这里我在Test之后有尾随空格,我想将其更新为{3P Test}*1+0.45%。如何更新该列,以便删除括号中的尾随空格?您可以在WHILE循环中使用REPLACE函数,例如使用以下函数: SELECT LTRIM(RTRIM('{3P Test } * 1 + 0.45%')) update table set COL1 = LTRIM(RTRIM(COL1)) SELECT '{3P Test } * 1 + 0.4

我使用的是SQL,一些列值表示为
{3P Test}*1+0.45%


这里我在Test之后有尾随空格,我想将其更新为
{3P Test}*1+0.45%
。如何更新该列,以便删除括号中的尾随空格?

您可以在WHILE循环中使用REPLACE函数,例如使用以下函数:

SELECT LTRIM(RTRIM('{3P Test } * 1 + 0.45%'))

update table set COL1 = LTRIM(RTRIM(COL1))
SELECT '{3P Test   } * 1 + 0.45%' AS TestCol INTO #temp 
UNION 
SELECT '{3P Test } * 1 + 0.45%' 

SELECT * FROM #temp

WHILE (SELECT COUNT(*) FROM #temp WHERE TestCol LIKE '% }%') > 0
  BEGIN
    UPDATE #temp
    SET TestCol = REPLACE(TestCol, ' }', '}')
  END

SELECT * FROM #temp 

DROP TABLE #temp 

如果这是一次更新,或者如果没有那么多行,那么迭代方法(正如在对问题的评论中所建议的)可以工作,但是如果有大量数据,那么这不是您想要做的事情,因为
update
的每次迭代都是一个事务(除非在
WHILE
循环之前显式执行
BEGIN TRANSACTION
,但如果该操作需要一段时间,它将阻止表执行其他操作)

例如:

DECLARE @TestTable TABLE (String NVARCHAR(4000));
INSERT INTO @TestTable (String) VALUES (N'{3P Test   } * 1 + 0.45%');

SELECT * FROM @TestTable;

WHILE (EXISTS(
          SELECT *
          FROM @TestTable tmp
          WHERE tmp.String LIKE N'% }%'
          )
      )
BEGIN
   UPDATE TOP (100) tmp -- do this in batches to reduce transaction size
   SET tmp.String = REPLACE(tmp.String, N' }', N'}')
   FROM @TestTable tmp
   WHERE tmp.String LIKE N'% }%';
END;

SELECT * FROM @TestTable;
DECLARE @Test NVARCHAR(4000);
SET @Test = N'{3P Test   } * 1 + 0.45%';

SELECT SQL#.RegEx_Replace(@Test, N'\s+}', N'}', -1, 1, N'IgnoreCase');
,这里是@Jodrell提出的
CHARINDEX
思想的简化版本,它使用一个CTE而不是多个子查询(不需要
连接到基表),并将字符串分成2段而不是3段:

DECLARE @TestTable TABLE (String NVARCHAR(4000));
INSERT INTO @TestTable (String) VALUES (N'{3P Test               } * 1 + 0.45%');
INSERT INTO @TestTable (String) VALUES (N'{3P Test     4       } * 1 + 0.45%');

SELECT * FROM @TestTable;

WHILE (EXISTS(
          SELECT *
          FROM @TestTable tmp
          WHERE tmp.String LIKE N'% }%'
          )
      )
BEGIN

   ;WITH cte AS
   (
      SELECT TOP (100)
             tmp.String,
             CHARINDEX(N'}', tmp.String) AS [RightBracketLocation]
      FROM @TestTable tmp
      WHERE tmp.String LIKE N'% }%'
   )
   UPDATE cte
   SET cte.String =
             RTRIM(SUBSTRING(cte.String, 1, (cte.[RightBracketLocation] - 1)))
             + SUBSTRING(cte.String, [RightBracketLocation], 4000)
   FROM cte;

END;

SELECT * FROM @TestTable;
但是,如果这是一个常见的操作,那么更直接、更直接的操作更好,例如正则表达式。没有内置正则表达式函数,因此需要使用SQLCLR来获取该功能。例如:

DECLARE @TestTable TABLE (String NVARCHAR(4000));
INSERT INTO @TestTable (String) VALUES (N'{3P Test   } * 1 + 0.45%');

SELECT * FROM @TestTable;

WHILE (EXISTS(
          SELECT *
          FROM @TestTable tmp
          WHERE tmp.String LIKE N'% }%'
          )
      )
BEGIN
   UPDATE TOP (100) tmp -- do this in batches to reduce transaction size
   SET tmp.String = REPLACE(tmp.String, N' }', N'}')
   FROM @TestTable tmp
   WHERE tmp.String LIKE N'% }%';
END;

SELECT * FROM @TestTable;
DECLARE @Test NVARCHAR(4000);
SET @Test = N'{3P Test   } * 1 + 0.45%';

SELECT SQL#.RegEx_Replace(@Test, N'\s+}', N'}', -1, 1, N'IgnoreCase');

在本例中,我使用的是库(我是该库的作者,但正则表达式函数在免费版本中可用)。

关于


正如您所注意到的,前面的语句只选择了正确的数据。您可以像这样更新它,


如果
[Table]
的主键已知,则可以改进此语句。

我的列值是{3P Test spaces}*1+0.45%…测试后的描述空间中的空格由stackOveflow修剪。这是否有效?REPLACE(columnName,'}','}')@KiranHegde:u的意思是类似于SELECT REPLACE('columnName','}','}','}','}');?我更新了问题,将字符串作为内联代码放置,以便不删除尾随空格。答案由@ultraCommit给出,然后他删除了他的答案,因为他认为他的ans是面向oracle的。我接受了他的答案,并尝试将其转换为sql格式,幸运的是它成功了。这只会删除整个过程前后的空格字符串,而不是OP试图去除的字符串中的空格。我认为这将删除整个字符串上的尾随空格和前导空格,而不仅仅是括号内的空格。例如,
{3P Test}*1+0.45%
变成
{3P Test}*1+0.45%
使用
EXISTS
而不是
COUNT(*)
效率更高。非常感谢您的快速响应。我使用了更新我的\u表设置我的\u列=替换(我的\u列,'}','}'))我的_列类似于“%}%”;并且它起作用了perfectly@sach:不客气。你可能应该投票给我和阿希根斯的答案,并选择一个作为答案。我希望我能投票:)我刚开始积极使用stackoverflow,我没有15个声誉要求投票:D@sach:很公平。我忘了那个限制。嘿,我又在做那个修复,发现脚本只删除了一个空格,而不是多个空格。例如,{3P Test}*1+0.45%(使用单个空格可以正常工作),但如果列值为{3P Test}*1+0.45%,则脚本不起作用,只是删除了所有空格。有什么建议吗?我也厌倦了你的脚本(正如你所说,这需要很长时间),因为你只删除尾随空格,只要在
}
@AndriyM处拆分字符串就足够了,是的,这对这种情况更方便。@Jodrell:谢谢你的解决方案。你能告诉我在上面的问题中r是什么吗。我是sql新手,试图理解您的查询。@Jodrell:我使用了您的更新脚本,如果我更新特定列,它工作得很好。当我试图在整个表上运行查询时,我得到以下错误:Msg 537,16级,状态3,第10行传递给LEFT或SUBSTRING函数的长度参数无效。声明已终止。对此有何想法?@sach我怀疑某些值不包含
'{'
'}'
或为空或空字符串。