我试图在较旧版本的pentaho 4.4中使用javascript操纵一行并得到一些我无法解释/不明白Pentaho正在做什么的奇怪结果
var test = 'field';
Alert (this[test]); //--> Undefined
Alert (this['field']); // --> Expected result
Alert (this[test]); //--> Expected Result
出于某种原因,this[test]
的初始请求是未定义的,直到我使用文字字符串引用使得无法动态驱动进程(即我无法通过引用访问行信息)。
为什么有任何想法?这简直就是Pentaho如何处理变量?实际上,我希望我的最终结果允许我更改任何给定位置的行值。之一:
row[test] = 'New value
或
this[test] = 'New Value
或
this[test].setValue('New Value');
但是,上述工作都没有,没有替换值使其成为一个非常静态的过程。
答案 0 :(得分:2)
据我所知,Kettle不会在脚本的范围中添加字段,除非该字段作为脚本源代码中的子字符串包含(即使注释中提到的字段,它也应该添加) )。请参阅determineUsedFields()
和addValues()
方法(https://github.com/pentaho/pentaho-kettle/blob/4.4.0/src/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java#L106)。
因此,您提供的确切脚本实际上会产生三个定义的值,或三个未定义的值,具体取决于字段是否存在。只有在我完全从代码中删除了包含字段名称的字符串并在另一个字段中传递了字段名称后,我才能重现您的问题。
因此,操作行值的一种方法可能是提及脚本中的所有字段名称(例如在注释中),然后尝试使用setValue,因为您尝试过(似乎仅在兼容模式下工作)。
另一种可能的方法是使用row
数组变量来获取值,使用getInputRowMeta().indexOfValue(fieldName)
来获取字段的索引,例如:
var idx = getInputRowMeta().indexOfValue(fieldName)
// WARNING: you may assign value of any type this way
// and the value will not be converted to a type defined
// in the field's ValueMeta:
row[idx] = 'New value'
但是,这种方法会绕过类型转换,这种转换通常是在getValueFromJScript()
方法中将JS值传递到JS步骤之外时执行的。
例如,以下代码会在输出中放入无效值,您可能甚至不会注意到它,直到某个后续步骤以某种不正确的方式处理该值:
// Let's assume that fieldName is name of the 0th input field.
// I'd expect, that the value would remain the same
// but in fact the `fieldName` references some wrapper oject
// which looks similar to its value
// but has a different type
row[0] = fieldName;
在随后的JS步骤中:
for(var i = 0; i < row.length; i++) {
Alert(row[i]) // alerts same value as the input, e.g. 'test'
Alert(row[i].class) // alerts undefined. While expected is 'java.lang.String'
// Some other subsequent steps may crash once this value encountered
}