首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在从mule 4调用存储过程时,只接受数值和字符串值。

在从mule 4调用存储过程时,只接受数值和字符串值。
EN

Stack Overflow用户
提问于 2021-11-05 16:09:57
回答 1查看 358关注 0票数 0

这是要发送到oracle存储过程中插入的示例请求有效负载:

代码语言:javascript
复制
{
    "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的字段属于表(UDT)类型。因此,它应该接受一个对象数组。

但是,当我试图在该字段中发送数组时,我得到的错误如下:

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

数据库配置:

代码语言:javascript
复制
<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存储过程配置:

代码语言:javascript
复制
<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>

这些配置中使用的变量是:

  • inOutParameter:

代码语言:javascript
复制
output application/json
---
payload.inOutParameters

  • outputParameters:

代码语言:javascript
复制
%dw 2.0
output application/json
--- 
payload.outputParameters pluck(value,key)-> {
     key : key,
     typeClassifier:{
        "type": value
    } 
}

  • inputParmaters:

代码语言:javascript
复制
%dw 2.0
output application/json
---
payload.inputParameters

  • query:

代码语言:javascript
复制
%dw 2.0
output application/json
---
payload.query

上面提到的payload是我在上面提到的有效载荷。

注意到:为了进行测试,我在oracle端禁用了字段p_lne_tbl,因为我得到了成功的响应。这就是我如何知道这个领域,p_lne_tbl的问题所在。

请告诉我这里有什么问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-10 11:58:58

您正在以一般方式使用数据库连接器的存储过程操作,即参数和查询是动态传递的。它适用于基本类型,但对于数组和用户定义的类型,需要使用特殊函数Db::createArray()和Db::createStruct()构造它们。此外,您可能需要在数据库连接器配置中指定类型。

代码语言:javascript
复制
    <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脚本。您的示例输入仅显示字段的空值,而不显示类型信息,因此我不确定您是否能够编写没有类型提示的泛型脚本。一旦您解决了这个问题,上面的示例就可以作为基础了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69856137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档