这真是太糟糕了...我强烈建议,如果您想单独处理每个地址行,请在第一时间正确存储它。而不是继续做你正在做的事情,添加额外的列,修复现有数据一次(而不是每次运行查询时“修复”),然后调整执行插入/更新的存储过程,使其知道使用其他列。
DECLARE @Address TABLE(id INT IDENTITY(1,1), ad VARCHAR(MAX));
INSERT @Address(ad) SELECT 'line 1
line 2
line 3
line 4'
UNION ALL SELECT 'row 1
row 2
row 3'
UNION ALL SELECT 'address 1
address 2'
UNION ALL SELECT 'only 1 entry here'
UNION ALL SELECT 'let us try 5 lines
line 2
line 3
line 4
line 5';
SELECT
id,
Line1 = REPLACE(REPLACE(COALESCE(Line1, ''), CHAR(10), ''), CHAR(13), ''),
Line2 = REPLACE(REPLACE(COALESCE(Line2, ''), CHAR(10), ''), CHAR(13), ''),
Line3 = REPLACE(REPLACE(COALESCE(SUBSTRING(Rest, 1, COALESCE(NULLIF(CHARINDEX(CHAR(10), Rest), 0), LEN(Rest))), ''), CHAR(10), ''), CHAR(13), ''),
Line4 = REPLACE(REPLACE(COALESCE(SUBSTRING(Rest, NULLIF(CHARINDEX(CHAR(10), Rest) + 1, 1), LEN(Rest)), ''), CHAR(10), ''), CHAR(13), '')
FROM
(
SELECT
id,
ad,
Line1,
Line2 = SUBSTRING(Rest, 1, COALESCE(NULLIF(CHARINDEX(CHAR(10), Rest), 0), LEN(Rest))),
Rest = SUBSTRING(Rest, NULLIF(CHARINDEX(CHAR(10), Rest) + 1, 1), LEN(Rest))
FROM
(
SELECT
id,
ad,
Line1 = SUBSTRING(ad, 1, COALESCE(NULLIF(CHARINDEX(CHAR(10), ad), 0), LEN(ad))),
Rest = SUBSTRING(ad, NULLIF(CHARINDEX(CHAR(10), ad) + 1, 1), LEN(ad))
FROM
@address
) AS x
) AS y
ORDER BY id;
Denis的PARSENAME()技巧当然更整洁,但是你必须非常小心地使用一个在数据中自然出现绝对不可能的替换字符。插入符号(^)可能是一个不错的选择,但就像我说的,你需要小心谨慎。
还有一些软件包可以清理地址和其他人口统计数据,但是清理数据输入是我要继续强调的最重要的事情……如果每个地址行需要分别处理,请将它们存储在这样的方式。