在 SSIS 中串联多列
Concatenation multiple columns in SSIS
我正在 SSIS 中进行简单的连接。
例如我有一个 table 这样的:
+--------+-----------+------------+--------+
| ID | COL_A | COL_B | COL_C |
+--------+-----------+------------+--------+
| 110-99 | | APPLE | Orange |
+--------+-----------+------------+--------+
| 111-01 | Mango | Palm | |
+--------+-----------+------------+--------+
| 111-02 | | Strawberry | |
+--------+-----------+------------+--------+
| 111-05 | Pineapple | Guava | Lemom |
+--------+-----------+------------+--------+
我在 SSIS 派生列中执行此操作。使用 Pipe |
连接 3 列
COL_A +"|"+COL_B+"|"+COL_C
实际结果:
|APPLE|Orange
MANGO|Palm|
|Strawberry|
Pineapple|Guava|Lemom
预期结果:
APPLE|Orange
MANGO|Palm
Strawberry
Pineapple|Guava|Lemom
我不确定如何在值为空时删除那些额外的 |
。我试过使用 CASE
但它不起作用。其实我不知道如何在派生列表达式中使用 CASE
。
在 SQL 服务器中,一个选项是 concat_ws()
,它在设计上忽略了 null
值。如果您有空字符串,您可以使用 nullif()
.
将它们转换为 null
值
concat_ws(
' | ',
nullif(col_a, ''),
nullif(col_b, ''),
nullif(col_c, '')
)
您可以使用 ?:
语法在 SSIS 表达式中执行条件逻辑。 ? : (Conditional) (SSIS Expression) 它的工作方式很像内联 IFF
。
按照这些思路:
boolean_expression ? returnIfTrue : returnIfFalse
为了获得您想要的结果,我想我会使用两个派生列转换。在第一个中,我将创建管道分隔的字符串,然后在第二个中,如果在构建字符串后有一个尾部管道,我将 trim 关闭。否则,为了避免留下尾随定界符,条件逻辑会变得非常复杂。
第一步 - 如果每列是 NULL
或空字符串,则 return 是空字符串。否则,return 与管道连接的列的内容:
((ISNULL(COL_A) || COL_A == "") ? "" : COL_A + "|"
对所有三列重复该逻辑,将此表达式放入您的派生列(此处添加换行符以提高可读性):
(((ISNULL(COL_A) || COL_A == "") ? "" : COL_A + "|" ) +
(((ISNULL(COL_B) || COL_B == "") ? "" : COL_B + "|" ) +
(((ISNULL(COL_C) || COL_C == "") ? "" : COL_C ) --No pipe here, since nothing follows.
然后,在第二个转换中,trim 来自最后一列或两列为空的实例的尾部管道:
(RIGHT(NewColumnFromAbove,1)=="|") ? LEFT(NewColumnFromAbove,LEN(NewColumnFromAbove)-1) : NewColumnFromAbove
另一方面,如果有很多列,或者性能下降,我会强烈考虑使用 CONCAT_WS
将连接写入存储过程,然后从 Execute SQL
任务代替。
我正在 SSIS 中进行简单的连接。
例如我有一个 table 这样的:
+--------+-----------+------------+--------+
| ID | COL_A | COL_B | COL_C |
+--------+-----------+------------+--------+
| 110-99 | | APPLE | Orange |
+--------+-----------+------------+--------+
| 111-01 | Mango | Palm | |
+--------+-----------+------------+--------+
| 111-02 | | Strawberry | |
+--------+-----------+------------+--------+
| 111-05 | Pineapple | Guava | Lemom |
+--------+-----------+------------+--------+
我在 SSIS 派生列中执行此操作。使用 Pipe |
COL_A +"|"+COL_B+"|"+COL_C
实际结果:
|APPLE|Orange
MANGO|Palm|
|Strawberry|
Pineapple|Guava|Lemom
预期结果:
APPLE|Orange
MANGO|Palm
Strawberry
Pineapple|Guava|Lemom
我不确定如何在值为空时删除那些额外的 |
。我试过使用 CASE
但它不起作用。其实我不知道如何在派生列表达式中使用 CASE
。
在 SQL 服务器中,一个选项是 concat_ws()
,它在设计上忽略了 null
值。如果您有空字符串,您可以使用 nullif()
.
null
值
concat_ws(
' | ',
nullif(col_a, ''),
nullif(col_b, ''),
nullif(col_c, '')
)
您可以使用 ?:
语法在 SSIS 表达式中执行条件逻辑。 ? : (Conditional) (SSIS Expression) 它的工作方式很像内联 IFF
。
按照这些思路:
boolean_expression ? returnIfTrue : returnIfFalse
为了获得您想要的结果,我想我会使用两个派生列转换。在第一个中,我将创建管道分隔的字符串,然后在第二个中,如果在构建字符串后有一个尾部管道,我将 trim 关闭。否则,为了避免留下尾随定界符,条件逻辑会变得非常复杂。
第一步 - 如果每列是 NULL
或空字符串,则 return 是空字符串。否则,return 与管道连接的列的内容:
((ISNULL(COL_A) || COL_A == "") ? "" : COL_A + "|"
对所有三列重复该逻辑,将此表达式放入您的派生列(此处添加换行符以提高可读性):
(((ISNULL(COL_A) || COL_A == "") ? "" : COL_A + "|" ) +
(((ISNULL(COL_B) || COL_B == "") ? "" : COL_B + "|" ) +
(((ISNULL(COL_C) || COL_C == "") ? "" : COL_C ) --No pipe here, since nothing follows.
然后,在第二个转换中,trim 来自最后一列或两列为空的实例的尾部管道:
(RIGHT(NewColumnFromAbove,1)=="|") ? LEFT(NewColumnFromAbove,LEN(NewColumnFromAbove)-1) : NewColumnFromAbove
另一方面,如果有很多列,或者性能下降,我会强烈考虑使用 CONCAT_WS
将连接写入存储过程,然后从 Execute SQL
任务代替。