我将以下格式字符串存储在文本中(可以是任意数量的列):
col1_source|col1_target;col2_source|col2_target;col3_source|col3_target;...
我试图想出一种优雅的方法来提取和隔离所有 xxx_source 列名和所有 xxx_target 列名,以便我可以将它们存储在变量中并获得以下最终结果:
@Source_Columns = 'col1_source,col2_source,col3_source' @Target_Columns = 'col1_target,col2_target,col3_target'
在一天结束时,我想对我的源列和目标列执行 SELECT 以执行数据比较。
这是我到目前为止所取得的成就,但我发现它太复杂了(使用表值函数):
CREATE FUNCTION [dbo].[UF_miscParseStringToTable]
(
@list nvarchar(MAX)
, @sep varchar(8)
)
RETURNS @ts table
(
[ID] int identity
, [value] nvarchar(MAX)
)
AS
BEGIN
-- Parameters check
if ((@sep is null) or (datalength(@sep) < 1)) return
if ((@list is null) or (@list = '') or (@list = @sep)) return
-- Add path wildcards directly with sep
-- ?worth it?
if (left(@sep, 1) <> '%') set @sep = '%' + @sep
if (right(@sep, 1) <> '%') set @sep = @sep + '%'
-- First first sep
declare @i int
set @i = patindex(@sep, @list)
-- Acc values
while (@i > 0) begin
insert into @ts ([value]) values (rtrim(left(@list, @i - 1)))
set @list = ltrim(right(RTRIM(@list), len(@list) + 3 - (@i + len(@sep) )))
set @i = patindex(@sep, @list)
end
set @list = rtrim(@list)
-- Insert last value, if any
if (@list <> '') insert into @ts (value) values (@list)
return
END
上面的函数基本上采用我的映射字符串并将其转换为表中的列名列表(请参见下面的查询逻辑):
DECLARE @Delim varchar(1) = '|'
DECLARE @Mapping varchar(max) = 'col1_source|col1_target;col2_source|col2_target;col3_source|col3_target'
DECLARE @String varchar(max) = REPLACE(@Mapping,';', @Delim)
SELECT * FROM dbo.UF_miscParseStringToTable(@String, @Delim)
以上结果查询产生下表:
ID| value
1 | col1_source
2 | col1_target
3 | col2_source
4 | col2_target
5 | col3_source
6 | col3_target
我也许可以对列索引进行联接,但是我发现很难隔离源字段和目标字段以便我可以在它们之间执行数据比较。此外,如果不需要的话,我想避免对表执行额外的连接。
以下是所需的结果(以便能够执行以下操作):
SELECT col1_source, col2_source, col3_source FROM mytable;
SELECT col1_target, col2_target, col3_target FROM mytable;
任何帮助或想法都会很棒!
肖恩
您没有指定 RDBMS - 我的解决方案使用 SQL Server。
您的问题表明您有一个存储在文本中的格式化字符串
你进一步说明
我的解决方案使用 SQL Server 2016 STRING_SPLIT。如果您未达到该版本,还有其他方法可以拆分字符串。
选择@SourceColumns
选择@TargetColumns