从 mule 4 调用存储过程时只接受数字和字符串值
Only numeric and string values are accepted in call to stored procedure from mule 4
这是被发送以插入到 Oracle 存储过程中的示例请求负载:
{
"inputParameters": {
"p_h_inv_cur": "EUR",
"p_h_inv_date": "20210101",
"p_h_tax_amt": 245.57,
"p_h_po_num": "1234",
"p_lne_tbl": ""
},
"outputParameters": {
"p_out_inv_id": "NUMERIC",
"p_out_er_code": "VARCHAR"
},
"inOutParameters": {},
"query": "{call XXX_PKG.XXX_STG(:p_h_inv_cur,:p_h_inv_date,:p_h_tax_amt,:p_h_po_num,:p_lne_tbl,:p_out_inv_id,:p_out_er_code)}"
}
名为p_lne_tbl的字段属于TABLE(UDT)类型。所以它应该接受 array 个对象。
但是当我尝试在该字段中发送数组时,出现错误:
Invalid conversion requested: java.util.LinkedHashMap to java.lang.String
所以我尝试将该数组转换为 application/java,但随后出现错误:
ORA-06550: line 1, column 7:\nPLS-00306: wrong number or types of arguments in call to 'INSERT_INVOICE_STAGE'\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored
数据库配置:
<db:config name="Database_Config" doc:name="Database Config" doc:id="5eaa8218-938e-4fc0-b3e9-0e3ba7e98a89" >
<db:oracle-connection host="${db.host}" port="${db.port}" user="${db.user}" password="${db.password}" instance="${db.instance}" >
<reconnection >
<reconnect frequency="${reconnect.frequency}" count="${reconnect.attempts}" />
</reconnection>
<db:pooling-profile maxPoolSize="${db.maxPoolSize}" minPoolSize="${db.minPoolSize}" acquireIncrement="${db.acquireIncrement}" preparedStatementCacheSize="${db.cacheSize}" maxWait="${db.maxWait}" />
</db:oracle-connection>
</db:config>
数据库存储过程配置:
<db:stored-procedure doc:name="invokingStoredProcedure" doc:id="6bcd83f8-bb62-4826-9cb7-4afa5d28168c" config-ref="Database_Config" inOutParameters="#[vars.inOutParameters]" outputParameters='#[vars.outputParameters]' queryTimeout="${db.querytimeout}" fetchSize="${db.prefetch}" doc:description="calling storedprocedure and executing the query">
<ee:repeatable-file-store-stream inMemorySize="${db.inMemorySize}" />
<reconnect frequency="${reconnect.frequency}" count="${reconnect.attempts}" />
<db:sql >#[vars.query]</db:sql>
<db:input-parameters ><![CDATA[#[vars.inputParameters]]]>
</db:input-parameters>
</db:stored-procedure>
配置中使用的变量是:
- 输入输出参数:
output application/json
---
payload.inOutParameters
- 输出参数:
%dw 2.0
output application/json
---
payload.outputParameters pluck(value,key)-> {
key : key,
typeClassifier:{
"type": value
}
}
- 输入参数:
%dw 2.0
output application/json
---
payload.inputParameters
- 查询:
%dw 2.0
output application/json
---
payload.query
上面的payload
就是我上面提到的payload
注意:为了测试,我从 oracle 端禁用了字段 p_lne_tbl,我得到了成功的响应.这就是我知道问题出在这个领域的方式,p_lne_tbl .
请让我知道这是什么问题。
您正在以通用方式使用数据库连接器的存储过程操作,即动态传递参数和查询。这适用于基本类型,但对于数组和用户定义的类型,它需要使用特殊函数 Db::createArray() 和 Db::createStruct() 来构造它们。此外,您可能需要在数据库连接器配置中指定类型。
<db:config name="dbConfig" >
<db:oracle-connection host="localhost" user="SYS as SYSDBA" password="Oradoc_db1" instance="ORCLCDB">
<db:column-types>
<db:column-type id="2003" typeName="PEOPLE"/>
<db:column-type id="2003" typeName="PHONE_NUMBER"/>
<db:column-type id="2008" typeName="PERSON" />
<db:column-type id="2003" typeName="PHONE_NUMBER_ARRAY"/>
<db:column-type id="2003" typeName="PHONE_BOOK"/>
</db:column-types>
</db:oracle-connection>
</db:config>
...
<ee:transform doc:name="Transform Message - Prepare UDT">
<ee:variables>
<ee:set-variable variableName="in_people_tab"><![CDATA[%dw 2.0
output application/java
fun toPhoneNumberArray(phoneNumber) = Db::createArray("dbConfig", "PHONE_NUMBER_ARRAY",[Db::createStruct("dbConfig", "PHONE_NUMBER", [phoneNumber.areaCode, phoneNumber.phoneNumber])])
fun toPerson(person) = Db::createStruct("dbConfig", "PERSON", [person.name, person.surname, person.age, toPhoneNumberArray(person.phoneNumber)])
---
Db::createArray("dbConfig", "PEOPLE", payload map (item, index) -> ( toPerson(item) ) )
]]></ee:set-variable>
</ee:variables>
</ee:transform>
<db:stored-procedure config-ref="dbConfig">
<db:sql><![CDATA[{ call proc_insert_humans(:people, :phoneBook) }]]></db:sql>
<db:input-parameters><![CDATA[{
people: vars.in_people_tab
}]]></db:input-parameters>
<db:output-parameters >
<db:output-parameter key="phoneBook" customType="PHONE_BOOK" />
</db:output-parame
您可以在文档中找到完整的示例:https://docs.mulesoft.com/db-connector/1.10/database-connector-udt-stored-procedure
这意味着您需要在脚本中手动构建它们,或者开发可以执行通用转换的 DataWeave 脚本。您的示例输入仅显示字段的空值而不显示类型信息,因此我不确定您是否能够编写没有类型提示的通用脚本。一旦你确定上面的例子可以作为一个有用的基础。
这是被发送以插入到 Oracle 存储过程中的示例请求负载:
{
"inputParameters": {
"p_h_inv_cur": "EUR",
"p_h_inv_date": "20210101",
"p_h_tax_amt": 245.57,
"p_h_po_num": "1234",
"p_lne_tbl": ""
},
"outputParameters": {
"p_out_inv_id": "NUMERIC",
"p_out_er_code": "VARCHAR"
},
"inOutParameters": {},
"query": "{call XXX_PKG.XXX_STG(:p_h_inv_cur,:p_h_inv_date,:p_h_tax_amt,:p_h_po_num,:p_lne_tbl,:p_out_inv_id,:p_out_er_code)}"
}
名为p_lne_tbl的字段属于TABLE(UDT)类型。所以它应该接受 array 个对象。
但是当我尝试在该字段中发送数组时,出现错误:
Invalid conversion requested: java.util.LinkedHashMap to java.lang.String
所以我尝试将该数组转换为 application/java,但随后出现错误:
ORA-06550: line 1, column 7:\nPLS-00306: wrong number or types of arguments in call to 'INSERT_INVOICE_STAGE'\nORA-06550: line 1, column 7:\nPL/SQL: Statement ignored
数据库配置:
<db:config name="Database_Config" doc:name="Database Config" doc:id="5eaa8218-938e-4fc0-b3e9-0e3ba7e98a89" >
<db:oracle-connection host="${db.host}" port="${db.port}" user="${db.user}" password="${db.password}" instance="${db.instance}" >
<reconnection >
<reconnect frequency="${reconnect.frequency}" count="${reconnect.attempts}" />
</reconnection>
<db:pooling-profile maxPoolSize="${db.maxPoolSize}" minPoolSize="${db.minPoolSize}" acquireIncrement="${db.acquireIncrement}" preparedStatementCacheSize="${db.cacheSize}" maxWait="${db.maxWait}" />
</db:oracle-connection>
</db:config>
数据库存储过程配置:
<db:stored-procedure doc:name="invokingStoredProcedure" doc:id="6bcd83f8-bb62-4826-9cb7-4afa5d28168c" config-ref="Database_Config" inOutParameters="#[vars.inOutParameters]" outputParameters='#[vars.outputParameters]' queryTimeout="${db.querytimeout}" fetchSize="${db.prefetch}" doc:description="calling storedprocedure and executing the query">
<ee:repeatable-file-store-stream inMemorySize="${db.inMemorySize}" />
<reconnect frequency="${reconnect.frequency}" count="${reconnect.attempts}" />
<db:sql >#[vars.query]</db:sql>
<db:input-parameters ><![CDATA[#[vars.inputParameters]]]>
</db:input-parameters>
</db:stored-procedure>
配置中使用的变量是:
- 输入输出参数:
output application/json
---
payload.inOutParameters
- 输出参数:
%dw 2.0
output application/json
---
payload.outputParameters pluck(value,key)-> {
key : key,
typeClassifier:{
"type": value
}
}
- 输入参数:
%dw 2.0
output application/json
---
payload.inputParameters
- 查询:
%dw 2.0
output application/json
---
payload.query
上面的payload
就是我上面提到的payload
注意:为了测试,我从 oracle 端禁用了字段 p_lne_tbl,我得到了成功的响应.这就是我知道问题出在这个领域的方式,p_lne_tbl .
请让我知道这是什么问题。
您正在以通用方式使用数据库连接器的存储过程操作,即动态传递参数和查询。这适用于基本类型,但对于数组和用户定义的类型,它需要使用特殊函数 Db::createArray() 和 Db::createStruct() 来构造它们。此外,您可能需要在数据库连接器配置中指定类型。
<db:config name="dbConfig" >
<db:oracle-connection host="localhost" user="SYS as SYSDBA" password="Oradoc_db1" instance="ORCLCDB">
<db:column-types>
<db:column-type id="2003" typeName="PEOPLE"/>
<db:column-type id="2003" typeName="PHONE_NUMBER"/>
<db:column-type id="2008" typeName="PERSON" />
<db:column-type id="2003" typeName="PHONE_NUMBER_ARRAY"/>
<db:column-type id="2003" typeName="PHONE_BOOK"/>
</db:column-types>
</db:oracle-connection>
</db:config>
...
<ee:transform doc:name="Transform Message - Prepare UDT">
<ee:variables>
<ee:set-variable variableName="in_people_tab"><![CDATA[%dw 2.0
output application/java
fun toPhoneNumberArray(phoneNumber) = Db::createArray("dbConfig", "PHONE_NUMBER_ARRAY",[Db::createStruct("dbConfig", "PHONE_NUMBER", [phoneNumber.areaCode, phoneNumber.phoneNumber])])
fun toPerson(person) = Db::createStruct("dbConfig", "PERSON", [person.name, person.surname, person.age, toPhoneNumberArray(person.phoneNumber)])
---
Db::createArray("dbConfig", "PEOPLE", payload map (item, index) -> ( toPerson(item) ) )
]]></ee:set-variable>
</ee:variables>
</ee:transform>
<db:stored-procedure config-ref="dbConfig">
<db:sql><![CDATA[{ call proc_insert_humans(:people, :phoneBook) }]]></db:sql>
<db:input-parameters><![CDATA[{
people: vars.in_people_tab
}]]></db:input-parameters>
<db:output-parameters >
<db:output-parameter key="phoneBook" customType="PHONE_BOOK" />
</db:output-parame
您可以在文档中找到完整的示例:https://docs.mulesoft.com/db-connector/1.10/database-connector-udt-stored-procedure
这意味着您需要在脚本中手动构建它们,或者开发可以执行通用转换的 DataWeave 脚本。您的示例输入仅显示字段的空值而不显示类型信息,因此我不确定您是否能够编写没有类型提示的通用脚本。一旦你确定上面的例子可以作为一个有用的基础。