Sql server 在SQL Server中使用另一个表的内容替换字符串(例如更新table1 set value=replace(table1.value、table2.val1、table2.val2))

Sql server 在SQL Server中使用另一个表的内容替换字符串(例如更新table1 set value=replace(table1.value、table2.val1、table2.val2)),sql-server,tsql,Sql Server,Tsql,我有一个包含邮政地址的SQL Server表。在准备邮寄时,我需要做大量的字符串替换以符合USPS偏好(“Avenue”变为“Ave”,例如) 为了省去枚举所有替换项的麻烦,我将标签/缩写对保存在一个两列表中。是否有一种优雅的方法可以在update语句中的Replace函数中将这些参数作为参数传递 查找表如下所示: CREATE TABLE addressLookup (label varchar(50),abbreviation varchar(20)) INSERT INTO address

我有一个包含邮政地址的SQL Server表。在准备邮寄时,我需要做大量的字符串替换以符合USPS偏好(“Avenue”变为“Ave”,例如)

为了省去枚举所有替换项的麻烦,我将标签/缩写对保存在一个两列表中。是否有一种优雅的方法可以在update语句中的Replace函数中将这些参数作为参数传递

查找表如下所示:

CREATE TABLE addressLookup (label varchar(50),abbreviation varchar(20))
INSERT INTO addressLookup (label,abbreviation)
SELECT 'Avenue','Ave' UNION
SELECT 'Boulevard','Blvd' UNION
SELECT 'Drive','Dr' UNION
SELECT 'Lane','Ln' UNION
SELECT 'Street','St' UNION
SELECT 'First','1st' UNION
SELECT 'Second','2nd' UNION
SELECT 'Third','3rd' UNION
SELECT 'Fourth','4th' UNION
SELECT 'Fifth','5th' UNION
SELECT 'Sixth','6th' UNION
SELECT 'Seventh','7th' UNION
SELECT 'Eighth','8th' UNION
SELECT 'Ninth','9th' UNION
SELECT 'Tenth','10th' UNION
SELECT 'Eleventh','11th' UNION
SELECT 'Twelfth','12th' UNION
SELECT 'Apartment','Apt' UNION
SELECT 'Apartments','Apts' UNION
SELECT 'Floor','Fl' UNION
SELECT 'Room','Rm' UNION
SELECT 'Suite','Ste' UNION
SELECT 'Po Box','PO Box' UNION
SELECT 'P O Box','PO Box' UNION
SELECT 'P o Box','PO Box' UNION
SELECT 'Rural Route','RR' UNION
SELECT 'R Rte','RR' UNION
SELECT 'Rr','RR'
这将是一个操作数据的示例(我知道这很草率,但这只是一个示例):

更新的问题是addressLookup表中任意数量的记录可能与address表的内容匹配。我想我可以实现一个递归存储过程来完成这项工作,但我希望有人会有一个更好、更优雅的解决方案

编辑
只是为了澄清一下,Addresses表已经被填充(有几百万条记录)。我只是想预测那些可能会抱怨需要真实数据来测试解决方案的人。

您可能可以使用光标来实现这一点。但是,使用SQLServer2005CTE,您可以尝试这样做

这是一个完整的工作示例:


我知道这篇文章已经有5年的历史了,但是如果它能帮助别人的话,这里是最简单的解决方案,不用光标

--REPLACE LABEL WITH ABBREVIATION
SELECT  @Address1 = REPLACE(@SearchString,[Label],[Abbreviation]),
        @Address2 = REPLACE(@SearchString2,[Label],[Abbreviation]),
        @Address3 = REPLACE(@SearchString2,[Label],[Abbreviation])
FROM    [dbo].[addressLookup]


--DEMO OUTPUT
SELECT  @Address1,
        @Address2,
        @Address3

谢谢这闻起来确实像是游标/CTE问题,不是吗。我会看看我是否能适应我的具体情况。
DECLARE @addressLookup TABLE (label varchar(50),abbreviation varchar(20))
INSERT INTO @addressLookup (label,abbreviation)
SELECT 'Avenue','Ave' UNION
SELECT 'Boulevard','Blvd' UNION
SELECT 'Drive','Dr' UNION
SELECT 'Lane','Ln' UNION
SELECT 'Street','St' UNION
SELECT 'First','1st' UNION
SELECT 'Second','2nd' UNION
SELECT 'Third','3rd' UNION
SELECT 'Fourth','4th' UNION
SELECT 'Fifth','5th' UNION
SELECT 'Sixth','6th' UNION
SELECT 'Seventh','7th' UNION
SELECT 'Eighth','8th' UNION
SELECT 'Ninth','9th' UNION
SELECT 'Tenth','10th' UNION
SELECT 'Eleventh','11th' UNION
SELECT 'Twelfth','12th' UNION
SELECT 'Apartment','Apt' UNION
SELECT 'Apartments','Apts' UNION
SELECT 'Floor','Fl' UNION
SELECT 'Room','Rm' UNION
SELECT 'Suite','Ste' UNION
SELECT 'Po Box','PO Box' UNION
SELECT 'P O Box','PO Box' UNION
SELECT 'P o Box','PO Box' UNION
SELECT 'Rural Route','RR' UNION
SELECT 'R Rte','RR' UNION
SELECT 'Rr','RR'


DECLARE @addresses TABLE (userid int PRIMARY KEY, address1 varchar(50), address2 varchar(50), address3 varchar(50), city varchar(50), state varchar(50), zip varchar(50))
INSERT INTO @addresses (userid,address1,address2,address3,city,state,zip)
SELECT 10,'Indiana University','123 University Lane Suite','Campus Box 123','Bloomington','IN','47405'

;WITH CTE AS(
        SELECT  *,
                ROW_NUMBER() OVER (ORDER BY label) RowID
        FROM    @addressLookup
),
CTERep AS(
        SELECT  CTE.*,
                userid,
                REPLACE(address1, CTE.label,CTE.abbreviation) address1,
                REPLACE(address2, CTE.label,CTE.abbreviation) address2,
                REPLACE(address3, CTE.label,CTE.abbreviation) address3,
                REPLACE(city, CTE.label,CTE.abbreviation) city,
                REPLACE(state, CTE.label,CTE.abbreviation) state,
                REPLACE(zip, CTE.label,CTE.abbreviation) zip,
                1 AS Depth
        FROM    CTE, @addresses a
        WHERE   RowID = 1
        UNION ALL
        SELECT  CTE.*,
                CTERep.userid,
                REPLACE(CTERep.address1, CTE.label,CTE.abbreviation) address1,
                REPLACE(CTERep.address2, CTE.label,CTE.abbreviation) address2,
                REPLACE(CTERep.address3, CTE.label,CTE.abbreviation) address3,
                REPLACE(CTERep.city, CTE.label,CTE.abbreviation) city,
                REPLACE(CTERep.state, CTE.label,CTE.abbreviation) state,
                REPLACE(CTERep.zip, CTE.label,CTE.abbreviation) zip,
                CTERep.Depth + 1
        FROM    CTE INNER JOIN
                CTERep ON CTE.RowID = CTERep.RowID + 1
)
SELECT  userid,
        address1,
        address2,
        address3,
        city,
        state,
        zip
FROM    CTERep
WHERE   Depth = (SELECT COUNT(*) FROM @addressLookup)
--REPLACE LABEL WITH ABBREVIATION
SELECT  @Address1 = REPLACE(@SearchString,[Label],[Abbreviation]),
        @Address2 = REPLACE(@SearchString2,[Label],[Abbreviation]),
        @Address3 = REPLACE(@SearchString2,[Label],[Abbreviation])
FROM    [dbo].[addressLookup]


--DEMO OUTPUT
SELECT  @Address1,
        @Address2,
        @Address3