【问题标题】:Dynamic expressions implementation动态表达式实现
【发布时间】:2014-07-17 15:44:59
【问题描述】:

我有一个源表:
S1 S2 S3 S4 Hi There SSN1 SSN2
其中 S1、S2、S3 和 S4 是列名。

同样有一个目标表,它具有三个字段:
T1 T2 T3

我有另一个表如下:
Function Target_Column concat(S1,S2) T1 substr(S3,1,3) T2 substr(S3,3,1) T3

我想要这样一个映射,它可以根据表中存在的函数获取函数名称并映射到指定的目标列。运行映射后,我现在的目标表将是:

T1 T2 T3 HiThere SSN 1

我怎样才能做到这一点? 我尝试在 FUNCTION 列上使用查找,该列将在输出中包含 1 列,其中包含所有函数和目标表名称的串联字符串。所以我的查找输出如下所示:
concat(S1,S2),T1::substr(S3,1,3),T2::substr(S3,3,1),T3

然后我将它与源端口 S1 S2 S3 S4 一起传递给 java 转换以进行处理。现在不知道如何进行。
我尝试使用invokeJExpression。 我用 :: 作为分隔符分割了我的字符串,并将其存储在数组 arr1 中。 所以我有
arr1[0]=concat(S1,S2),T1 arr1[1]=substr(S3,1,3),T2 arr1[2]=substr(S3,3,1),T3
现在我运行了这个 trhough 循环并再次使用 , 作为我的分隔符将其拆分并存储到 arr2 中。 所以我的 arr1[0] 的 arr2 是这样的:
arr2[0]=concat(S1,S2) arr2[1]=T1

现在,如果我使用 InvokeJExpression,我会将其结果分配给什么? 我希望我的表达式 concat(S1,S2) 被处理并映射到现在位于 arr2[1] 中的 T1。这就是我卡住的地方。

【问题讨论】:

  • 假设与表的连接没有问题,您应该对 Function 列进行一些字符串操作。函数名称和参数是否已知?如果是这样,查找表可能是解决方案。到目前为止,您尝试过什么?
  • 我认为您也可以摆脱查找表...只需正确排列数据并操作一点函数字符串即可获取函数和参数。
  • 要求澄清:这些表在数据库中吗?
  • 是的。我正在使用 Oracle 11g 数据库。
  • 我尝试在FUNCTION 列上使用查找,该列将在输出中包含 1 列,其中包含所有函数和目标表名称的串联字符串。因此,我的查找输出将如下所示:concat(S1,S2),T1::substr(S3,1,3),T2::concat(S3,3,1),T3 然后我将其与源端口S1 S2 S3 S4 一起传递给 Java 转换以进行处理。现在不知道如何进行。

标签: java informatica informatica-powercenter


【解决方案1】:

看起来您可以在 Java 转换中使用 Java API 函数 invokeJExpression() 来派生目标列。

(datatype)invokeJExpression(
                  String expression, 
                  Object[] paramMetadataArray);

我想最困难的部分是从您的查找中解析连接的字符串以获取两个参数 expressionparamMeradataArray

expression 和 paramMeradataArray 应如下所示:

"concat(X1,X2)", [S1, S2]
"substr(X1,X2,X3)", [S1, 1, 3]

请注意,参数必须以 X 开头并连续编号。

更新:

假设您从查找中获得端口lkp='concat(S1,S2)~T1::substr(S3,1,3)~T2::substr(S3,3,1)~T3',您可以在Java 转换中尝试以下代码。但是,此代码可能不适用于所有功能。例如,传递十进制值将不起作用。

导入包:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

在输入行上:

String[] arr1 = lkp.split("::");

for (int i = 0; i < arr1.length; i++) {
    String[] arr2 = arr1[i].split("~");
    Pattern pattern = Pattern.compile("\\((.*?)\\)");
    Matcher matcher = pattern.matcher(arr2[0]);
    String params = "";
    if (matcher.find()) {
        params = matcher.group(1);
    }
    String[] param = params.split(",");
    Object[] args1 = new Object[param.length];
    String params1 = "";
    for (int j = 0; j < param.length; j++) {
        int index = j + 1;
        Object arg = new Object();
        params1 = params1 + (!params1.equals("") ? "," : "") + "X"
                + index;
        if (param[j].equals("S1"))
            arg = S1;
        else if (param[j].equals("S2"))
            arg = S2;
        else if (param[j].equals("S3"))
            arg = S3;
        else if (param[j].equals("S4"))
            arg = S4;
        else if (!param[j].startsWith("\'"))
            arg = Integer.parseInt(param[j]);
        else
            arg = param[j];
        args1[j] = arg;
    }

    String exp = matcher.replaceAll("(" + params1 + ")");
    if (arr2[1].equals("T1"))
        T1 = (String) invokeJExpression(exp, args1);
    else if (arr2[1].equals("T2"))
        T2 = (String) invokeJExpression(exp, args1);
    else if (arr2[1].equals("T3"))
        T3 = (String) invokeJExpression(exp, args1);

}

【讨论】:

  • 感谢 Samik 的回复。我尝试使用invokeJExpression。我用 :: 作为分隔符分割了我的字符串,并将其存储在数组 arr1 中。所以我有 arr1[0]=concat(S1,S2),T1 arr1[1]=substr(S3,1,3),T2 arr1[2]=substr(S3,3,1),T3 现在我运行了这个 trhough 循环并再次使用 , 作为我的分隔符并将其拆分并存储到 arr2 中。所以我的 arr1[0] 的 arr2 是这样的:arr2[0]=concat(S1,S2) arr2[1]=T1 现在如果我使用 InvokeJExpression,我应该将结果分配给什么?我希望我的表达式 concat(S1,S2) 被处理并映射到现在位于 arr2[1] 中的 T1。这就是我卡住的地方。
  • 如果用逗号分割是不行的,因为参数也是用逗号分隔的。我已经用示例代码更新了答案。让我知道它是否有效
【解决方案2】:

我不确定我是否正确理解了这个问题。但是,如果您的源列和目标列将保持不变,但您的表达式可能会因每次运行而改变,那么您可以尝试使用选中“Is Expression”的参数。参数值将是您的实际函数,无论您在哪里使用它都会在表达式转换中进行评估。

【讨论】:

    【解决方案3】:

    请在下面找到最简单的方法,如果您还有其他问题,请告诉我,

    1.Create 3 mapping parameters as $$Map1 , $$Map2 & $$Map3 with any default value.
    
    2.Better to create a Job_Parameter table to store parameter and its corresponding value like :
    
    Workflow Name | Parameter Name | Parameter value
    wf_abc | $$Map1 | default
    wf_abc | $$Map2 | default
    wf_abc | $$Map3 | default
    
    3. Create a mapping / unix script / SQL procedure to read your functions and keep those in to this Job_Parameter table, your table should look like this.
    (Job_Parameter is always truncate and load).
    
    Workflow Name | Parameter Name | Parameter value
    wf_abc | $$Map1 | concat(S1,S2) 
    wf_abc | $$Map1 | substr(S3,1,3)
    wf_abc | $$Map1 | substr(S3,3,1)
    
    4. Create a parameter file using this Job_Parameter table and it should look like this:
    
    [Global]
    wf_abc
     $$Map1=concat(S1,S2) 
     $$Map1=substr(S3,1,3)
     $$Map1=substr(S3,3,1)
    
    4. Go to you Actual mapping and read the source with 4 columns, 
     create 3 variable ports next to SQ 
    V1= $$Map1
    V2= $$Map2
    V3= $$Map3 ..Create 3 output ports and assign these variable ports accordingly.
    Source-SQualifier-Expression-Target
    

    将输出端口链接到目标。

    我希望您在函数 source 中收到的所有文件名和 Informatica 中的 NAMED 都打开并且相同,如果没有相应地进行更改。

    【讨论】:

      猜你喜欢
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      相关资源
      最近更新 更多