我需要创建一个SQL解决方案来对字符串列执行多个搜索和替换操作。搜索/替换术语的数量是动态的,以及搜索和替换术语本身。
出于这个原因,我计划使用包含所有搜索和替换所需术语的表。因此基础设置涉及两个表,一个包含具有以下模式的字符串列的通用表:
CREATE TABLE GENERAL_TABLE (
ID INTEGER NOT NULL
, SOURCE_TEXT VARCHAR(1024) NOT NULL
, CONSTRAINT PRIMARY KEY (ID)
);
以及使用以下架构搜索和替换术语表:
CREATE TABLE SEARCH_REPLACE (
SEARCH_TERM VARCHAR(256) NOT NULL
, REPLACE_TERM VARCHAR(256) NOT NULL
);
是否有办法将每个SEARCH_TERM
值中的所有SOURCE_TEXT
值替换为相应的REPLACE_TERM
值?
例如,如果GENERAL_TABLE
填充了以下记录:
ID SOURCE_TEXT
-- -------------------------------------------------------
1 honesty is the best policy.
2 honesty is the best policy - when there is money in it.
3 we are all worms. but i believe that i am a glow-worm.
4 believe you can and you're halfway there.
5 ambition must be made to counteract ambition.
6 run, run as fast as you can.
和SEARCH_REPLACE
填充了以下记录:
SEARCH_TERM REPLACE_TERM
----------- ------------
honesty taco tuesday
policy sale
money cheese
worm robot
believe know
ambition loans
run swim
然后在所有搜索和替换之后GENERAL_TABLE
中的所需结果是:
ID SOURCE_TEXT
-- -----------------------------------------------------------
1 taco tuesday is the best sale.
2 taco tuesday is the best sale - when there is cheese in it.
3 we are all robots. but i know that i am a glow-robot.
4 know you can and you're halfway there.
5 loans must be made to counteract loans.
6 swim, swim as fast as you can.
整个过程将由具有DBA特权的用户执行。因此,任何解决方案都可以根据需要使用DDL命令。
答案 0 :(得分:0)
将SEARCH_Replace中的所有行值获取为字符串变量+包含替换函数
声明@str nvarchar(2000)
设置@str ='替换(SOURCE_TEXT,'
从@SEARCH_REPLACE中选择前1个@str = @str +''''+ SEARCH_TERM +''','''+ REPLACE_TERM +''')' - 第一行
从@SEARCH_REPLACE选择@str ='替换('+ @str +','''+ SEARCH_TERM +''','''+ REPLACE_TERM +'''),其中SEARCH_TERM不喜欢'诚实' - 其他行
为@str
构建查询声明@sql nvarchar(4000)
设置@sql ='从GENERAL_TABLE'选择Source_Text,'+ @str +'
执行@sql
EXEC(@sql)
表格结果
NEW_TEXT
-------------------------------------------------- -------
塔科周二是最好的销售
taco周二是最好的销售 - 当它有奶酪时。
我们都是机器人。但我知道我是一个发光机器人
知道你可以而且你已经到了一半。
必须提供贷款以抵消贷款
游泳,尽可能快地游泳。
答案 1 :(得分:0)
您可以尝试使用选择
进行更新UPDATE GENERAL_TABLE dest,
(SELECT
SEARCH_TERM, REPLACE_TERM
FROM
SEARCH_REPLACE) src
SET
dest.SOURCE_TEXT = REPLACE(dest.SOURCE_TEXT,
src.SEARCH_TERM,
src.REPLACE_TERM)
干杯
答案 2 :(得分:0)
这是一个利用工作表存储连续搜索/替换结果的解决方案。该解决方案涉及三个SQL步骤。首先创建一个表来执行所有中间工作,其中SOURCE_TEXT
是原始GENERAL_TABLE
值,TARGET_TEXT
是搜索/替换结果:
-- workspace table
-- all search/replace work is done in this table
DROP TABLE IF EXISTS GENERAL_TABLE_WORK;
CREATE TABLE GENERAL_TABLE_WORK (
ID INTEGER NOT NULL
, SOURCE_TEXT VARCHAR(1024) NOT NULL
, TARGET_TEXT VARCHAR(1024) NULL
, LAST_ID INTEGER NULL
, REC_NUM INTEGER
, CONSTRAINT PRIMARY KEY (ID, REC_NUM)
);
接下来,将GENERAL_TABLE
与SEARCH_REPLACE
表一起使用,并将其用作表格,将所有搜索/替换结果选择到工作区表中。连接中还使用控制表来维持连续搜索/替换结果之间的状态:
-- perform search/replace on source text
-- creating one record for each search/replace value
-- using the last replace results as the next input string
-- R is used solely to intialize variables
-- the ordering in A is crucial to maintain the correct variable state
INSERT INTO GENERAL_TABLE_WORK (
SELECT
A.ID AS ID
, A.SOURCE_TEXT AS SOURCE_TEXT
, CAST(IF(@lastid = A.ID,
@text := REPLACE(@text, A.SEARCH_TERM, A.REPLACE_TERM),
@text := REPLACE(A.SOURCE_TEXT, A.SEARCH_TERM, A.REPLACE_TERM)) AS CHAR)
AS TARGET_TEXT
, @lastid := A.ID AS LAST_ID
, @record := @record + 1 AS REC_NUM
FROM
(SELECT G.ID AS ID, G.SOURCE_TEXT AS SOURCE_TEXT,
S.SEARCH_TERM AS SEARCH_TERM, S.REPLACE_TERM AS REPLACE_TERM
FROM GENERAL_TABLE G JOIN SEARCH_REPLACE S
ORDER BY G.ID, S.SEARCH_TERM) A
JOIN (SELECT @lastid := NULL, @text := NULL, @record := 0) R
);
最后,GENERAL_TABLE
值将替换为GENERAL_TABLE_WORK
中为每条原始记录找到的最后一次搜索/替换结果:
-- copy target text back to original table
-- only taking the highest rec_num record for each id.
UPDATE GENERAL_TABLE G
JOIN
(SELECT W1.* FROM GENERAL_TABLE_WORK W1
LEFT OUTER JOIN GENERAL_TABLE_WORK W2 ON (W1.ID = W2.ID AND W2.REC_NUM > W1.REC_NUM)
WHERE W2.ID IS NULL
) A ON (G.ID = A.ID)
SET G.SOURCE_TEXT = A.TARGET_TEXT
WHERE NOT A.TARGET_TEXT = A.SOURCE_TEXT
;