动态表达式实现

时间:2014-07-17 15:45:00

标签: java informatica informatica-powercenter

我有一个源表:
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。  我用:: as delimiter分割我的字符串并将其存储在数组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。这就是我被困住的地方。

3 个答案:

答案 0 :(得分:0)

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

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

我想难以解决查询中的连接字符串以获取两个参数expressionparamMeradataArray

表达式和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);

}

答案 1 :(得分:0)

我不确定我是否理解这个问题。但是,如果您的源列和目标列保持相同,但是每次运行时表达式都可能会更改,那么您可以尝试使用带有&#39; Is Expression&#39;检查。参数值将是您的实际函数,无论您在何处使用它,都将在表达式转换中进行评估。

答案 2 :(得分:0)

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

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

将输出端口链接到目标。

我希望您在函数源中收到的所有归档名称和Informatica中的NAMED都是相同的,如果没有相应的更改。