在SQL中批量替换

时间:2017-10-06 09:32:19

标签: sql-server

我试图通过表格的一列删除特定单词。在表#Temp中,需要调整字段“Text1”,以便从Text1中删除表#Collections中的所有字符串。我总是得到一个错误。我是否需要为该特定情况定义一个函数?

  

子查询返回的值超过1。这是不允许的   子查询跟随=,!=,<,< =,>,> =或当子查询用作   表达。

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp
IF OBJECT_ID('tempdb..#Collections') IS NOT NULL DROP TABLE #Collections

CREATE TABLE #Temp (Text1 VARCHAR(200))
CREATE TABLE #Collections (Name VARCHAR(10))

INSERT INTO #Temp (Text1)
VALUES
('This is a text'),
('I made a mistake')


INSERT INTO #Collections (Name)
VALUES
('is'),
('a'),
('I')

UPDATE #Temp
SET Text1 = (SELECT Text2 FROM(
    SELECT
        REPLACE(T0.Text1, T1.Name, '') AS 'Text2'
    FROM #Temp T0
    INNER JOIN #Collections T1 on CHARINDEX(' ' + T1.Name + ' ', T0.Text1) > 0)Alias)

预期结果:
1. 本文
2. 犯了错误

编辑:使用以下光标解决它:

DECLARE @ReplaceValue as NVARCHAR(50);

DECLARE db_cursor CURSOR FOR
    SELECT Name
    FROM #Collections

OPEN db_cursor
FETCH NEXT FROM db_cursor into  @ReplaceValue

WHILE @@FETCH_STATUS = 0
BEGIN
    UPDATE #Temp
    SET Text1 = REPLACE(Text1, ' ' + @ReplaceValue + ' ', ' ')
    WHERE CHARINDEX(' ' + @ReplaceValue + ' ', Text1) > 0
    FETCH NEXT FROM db_cursor INTO @ReplaceValue
END

CLOSE db_cursor
DEALLOCATE db_cursor

2 个答案:

答案 0 :(得分:1)

此代码可以帮助您

IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp
IF OBJECT_ID('tempdb..#Collections') IS NOT NULL DROP TABLE #Collections

CREATE TABLE #Temp (ID INT IDENTITY,Text1 VARCHAR(200))
CREATE TABLE #Collections (ID INT IDENTITY,Name VARCHAR(10))

INSERT INTO #Temp (Text1)
VALUES
('This is a text'),
('I Made a mistake')


INSERT INTO #Collections (Name)
VALUES
('is'),
('a'),
('I')

;WITH cte 
     AS (SELECT id, 
                text1 
         FROM   (SELECT id, 
                        split.a.value('.', 'nvarchar(1000)') AS Text1 
                 FROM   (SELECT id, 
                                Cast('<S>' + Replace(text1, ' ', '</S><S>') + 
                                     '</S>' 
                                     AS 
                                     XML) AS 
                                Text1 
                         FROM   #temp)AS A 
                        CROSS apply text1.nodes('S') AS Split(a))DT 
         WHERE  dt.text1 NOT IN (SELECT DISTINCT NAME 
                                 FROM   #collections)) 
SELECT DISTINCT Id, 
                Stuff((SELECT ' ' + text1 
                       FROM   cte i 
                       WHERE  i.id = o.id 
                       FOR xml path ('')), 1, 1, '') AS ExpectedText 
FROM   cte o 

结果

Id  ExpectedText
-----------------
1   This text
2   Made mistake

答案 1 :(得分:0)

请找到符合您要求的代码示例,这里我使用的是物理表而不是#table,因为函数不支持#表。

IF OBJECT_ID('Temp') IS NOT NULL DROP TABLE Temp
IF OBJECT_ID('Collections') IS NOT NULL DROP TABLE Collections

CREATE TABLE Temp (Text1 VARCHAR(200))
CREATE TABLE Collections (Name VARCHAR(10))

INSERT INTO Temp (Text1)
VALUES
('This is a text'),
('I made a mistake'),
('I am a SuperStar')



INSERT INTO Collections (Name)
VALUES
('is'),
('a'),
('I')

GO

CREATE FUNCTION [dbo].[Split]
(
@String NVARCHAR(4000),
@Delimiter NCHAR(1)
)
RETURNS TABLE 
AS
RETURN 
(
WITH Split(stpos,endpos) 
AS(
SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
FROM Split
)

GO 

CREATE Function GetModifiedValue
(
@String Varchar(100)
)
RETURNS Varchar(100)
AS
BEGIN

Declare @Result Varchar(100)

Select @Result=COALESCE(@Result + ' ', '')+Data From dbo.Split(@String,' ') Where Data not in (Select Name from Collections)

RETURN @Result

END

Go

Select dbo.GetModifiedValue(Text1) From Temp