从 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 脚本。您的示例输入仅显示字段的空值而不显示类型信息,因此我不确定您是否能够编写没有类型提示的通用脚本。一旦你确定上面的例子可以作为一个有用的基础。