我有由 $$
字符分隔的字符串,如下所示:
BOB$$"DOG"$$"BROWN"$$"9"$$"4"$$"Latest"$$$$$$"small.
EVA$$"CAT"$$"BLACK"$$"1"$$"4"$$$$"Mouse"$$"Milk"$$small.
我想获得使用后的功能:更新/插入选择/SSIS映射
表格如下:
Column1 Column2 Column3 Column4 Column5 Column6 Column7 Column8 Column9
BOB "DOG" "BROWN" "9" "4" "Lat,est" NULL NULL small.
EVA "CAT" "BLACK" "1" "4" NULL "Mouse" "Milk" small.
我可以使用 Update/Insert into select 函数生成 9 行来获取结果吗? 我可以创建两个表;第一个表包含单列,第二个表包含 9 或 10 列。
我需要 100 多行的通用解决方案。上面两行只是示例。
我想继续使用这种类型的代码:
SELECT [Column0]
,LEFT([Column0], CHARINDEX('$$', [Column0]) - 1) AS [name]
FROM [dbo].[tablename]
最佳答案
您走在正确的道路上。当使用 SSIS 导入平面文件时,我们通常将所有内容导入为 varchar 数据类型列表(称为临时表),然后检查列值的数据类型一致性。 这使我们能够导入所有内容而不会丢失数据,并为清理数据提供了机会。
方法 1:对于您的情况,您可以在 SSIS 数据流任务源中使用 $$ 作为列分隔符。 SSIS 不关心标题列的顺序或名称。标题名称中可以包含任何内容,例如 Column 1、Column 2 等。 在这种方法中,您将数据从文件导入到 9 列表中。如果某些行中有较少/较多的列,则此方法将会失败。
方法 2:将所有内容作为单列导入到 varchar 临时表 (1) 中。 从这里,您拆分所有列并插入到另一个 9 列(可空)的 varchar 临时表 (2) 中,然后在将数据移动到数据类型列表之前进行数据验证。
可在方法2中使用的查询
create table staging_tbl_single_row (datarow varchar(max))
insert into staging_tbl_single_row values
('BOB$$"DOG"$$"BROWN"$$"9"$$"4"$$"Latest"$$$$$$"small.'),
('EVA$$"CAT"$$"BLACK"$$"1"$$"4"$$$$"Mouse"$$"Milk"$$small.')
; with cte as
(
select
row_number() over (order by (select NULL)) as column1,
replace(datarow,'$$','|') as column2
from staging_tbl_single_row
)
--Insert into SomeTable
select
[1],[2],[3],[4],[5],[6],[7],[8],[9]
from
(
select
t.column1,
split_values=SUBSTRING( t.column2, t1.N, ISNULL(NULLIF(CHARINDEX('|',t.column2,t1.N),0)-t1.N,8000)),
r= row_number() over( partition by column1 order by t1.N)
from cte t
join
(
select
t.column2,
1 as N
from cte t
UNION ALL
select
t.column2,
t1.N + 1 as N
from cte t
join
(
select
top 8000
row_number() over(order by (select NULL)) as N
from
sys.objects s1
cross join
sys.objects s2
) t1
on SUBSTRING(t.column2,t1.N,1) = '|'
) t1
on t1.column2=t.column2
)a
pivot
(
max(split_values) for r in ([1],[2],[3],[4],[5],[6],[7],[8],[9])
)p
关于SQL Server 将值拆分为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46680776/