【问题标题】:Convert CASE expression in SQL to derived column in SSIS [closed]将 SQL 中的 CASE 表达式转换为 SSIS 中的派生列 [关闭]
【发布时间】:2012-03-07 16:38:27
【问题描述】:
CASE 
        WHEN CHARINDEX('%', '{FixedARMRateReductionLimit}') > 0 THEN
            CAST(SUBSTRING('{FixedARMRateReductionLimit}', 0, 
               CHARINDEX('%', '{FixedARMRateReductionLimit}')) as decimal)/100
        WHEN '{FixedARMRateReductionLimit}' = 'Weekly PMMS Rate' THEN
            PARAM_VAL_TXT
        ELSE
            .02
    END

【问题讨论】:

  • 欢迎使用 StackOverflow:如果您发布代码、XML 或数据示例,在文本编辑器中突出显示这些行并单击“代码示例”按钮 ({ } ) 在编辑器工具栏上以很好地格式化和语法突出显示它!
  • 提供的代码似乎不准确。它是从某个数据访问层复制而来的吗? CHARINDEX('%', '{FixedARMRateReductionLimit}') 将始终计算为 0,因为第二个参数的值永远不会改变。
  • 以前的帐户是user1169594

标签: sql sql-server-2008 ssis


【解决方案1】:

以下故事的寓意是,仅仅因为您可以在 SSIS 中做某事,这并不总是一个好主意。

例如,这个查询。使用现有的 sql 逻辑生成最终值要比使用派生列或 SSIS 中的脚本任务效率高得多(更不用说浪费管道内存、CPU 等)

来源查询

我使用以下作为源查询。

SELECT '50%' AS FixedARMRateReductionLimit, .1 AS PARAM_VAL_TXT
UNION ALL  SELECT 'Weekly PMMS Rate' AS FixedARMRateReductionLimit, .3 AS PARAM_VAL_TXT
UNION ALL  SELECT 'Frack',  .5

查找百分比位置

判断列中是否存在百分比符号。这将创建一个名为 PercentPosition

的列
FINDSTRING(FixedARMRateReductionLimit, "%",1)

检查费率文本

如第一个表达式所示,做一个简单的比较就足够了,但我遇到了问题。我认为这是string conversion/comparison 问题(见第一个注释)。我没有骗取布尔值,而是使用 findstring 来生成序数位置。

FixedARMRateReductionLimit == "'Weekly PMMS Rate"
FINDSTRING(FixedARMRateReductionLimit,"Weekly PMMS Rate",1)

导出输出

享受Ternary operator的双重使用。

(RateTextPosition > 0) ? (PARAM_VAL_TXT) : (PercentPosition == 0) ? .2 : ((DT_NUMERIC, 18,2) SUBSTRING(FixedARMRateReductionLimit,1,PercentPosition - 1))/100

您可以在脚本任务中简化其中的一些内容,但我只需在源代码中执行逻辑即可。

【讨论】:

    【解决方案2】:

    这只是为了说明在派生转换中应该如何构造表达式。我不建议这样做,因为它很难维护。

    参考@billinkc这个问题的答案Convert CASE expression in SQL to derived column in SSIS

    下面是表达式在派生转换中的写法。

    (FINDSTRING(FixedARMRateReductionLimit,"%",1) > 1) ? ((DT_NUMERIC,5,2)SUBSTRING(FixedARMRateReductionLimit,1,FINDSTRING(FixedARMRateReductionLimit,"%",1) - 1)) : (FixedARMRateReductionLimit == "Weekly PMMS Rate" ? (0.35) : (0.02))
    

    表达式的格式化版本。

    (FINDSTRING(FixedARMRateReductionLimit,"%",1) > 1) 
        ?   (
                (DT_NUMERIC,5,2) 
                    SUBSTRING(  FixedARMRateReductionLimit, 
                                1, 
                                FINDSTRING(FixedARMRateReductionLimit, "%", 1) - 1
                              )
            ) 
        :   FixedARMRateReductionLimit == "Weekly PMMS Rate" 
                ? (0.35) 
                : (0.02))
    

    使用的样本数据:

    SELECT c1 AS FixedARMRateReductionLimit
    FROM
    (
                SELECT '2.00%'              AS c1 
        UNION   SELECT '13.95%'             AS c1 
        UNION   SELECT '%52.00%'            AS c1 
        UNION   SELECT '%%'                 AS c1 
        UNION   SELECT '85.%42%'            AS c1 
        UNION   SELECT 'Weekly PMMS Rate'   AS c1 
        UNION   SELECT 'Monthly PMMS Rate' 
    ) T1
    

    在数据查看器中查看派生转换的输出:

    【讨论】:

    • 好答案。但是,将此类“复杂”转换移动到脚本转换可能更方便且对开发人员友好。
    猜你喜欢
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多