【问题标题】:Mulesoft: Insert into sql server fails b/c of null constraint however payload has dataMulesoft:插入 sql server 失败 b/c 的空约束但是有效负载有数据
【发布时间】:2018-03-09 15:49:13
【问题描述】:

我对@9​​87654321@ 的Mule ESB 还是新手,我就是无法解决这个问题。

我无法理解为什么我的 Mule flow 因 sql server 插入错误而失败。

负载似乎有数据,但由于某种原因,查询参数没有填充该数据。我可以很好地从表或文件中读取数据,只是写入横向的 db 表。

我需要做什么才能将有效负载写入 sql server 数据库?

以下是我在 AnyPoint Studio 中运行 Mule 应用程序时收到的错误消息。由于隐私原因,我已从消息中删除了大部分有效负载。

我还发布了我的流 xml。

任何帮助将不胜感激。谢谢

********************************************************************************
Message               : Cannot insert the value NULL into column 'AgentId', table 'GARDB1dev.src.AgentList'; column does not allow nulls. INSERT fails. (com.microsoft.sqlserver.jdbc.SQLServerException).
Payload               : [{Agent_ID=10032, **REDACTED DATA**  [..]]
Payload Type          : java.util.ArrayList
Element               : /Load-AgentList/processors/2/1/1 @ gar-data-load:sharepoint.xml:51
Element XML           : <db:insert config-ref="GAR-DB-Connection-SSPI" doc:name="Insert AgentList Data">
                        <db:parameterized-query>insert into src.AgentList (AgentId,PartyId,PartyType,AgentIdStatus,SalesOrg,AgentIdStatusStart,AgentIdStatusEnd,AgentName,SubOrganization,[Function],NewToOrg,NewToChannel,DaysAgentIdActive,Region,AgentPhone,CertificationSummary)Values (#[payload.Agent_ID],#[payload.Party_ID],#[payload.Party_Type],#[payload.Agent_ID_Status],#[payload.Sales_Organization],#[payload.Agent_ID_Status_Start],#[payload.Agent_ID_Status_End],#[payload.Agent_Name],#[payload.Sub_Organization],#[payload.Function],#[payload.New_To_Org],#[payload.New_To_Channel],#[payload.Days_Agent_ID_Active],#[payload.Region],#[payload.Agent_Phone],#[payload.Certification_Summary])</db:parameterized-query>
                        </db:insert>
--------------------------------------------------------------------------------

我的 Mule Flow 的 XML 描述如下:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:db="http://www.mulesoft.org/schema/mule/db" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:metadata="http://www.mulesoft.org/schema/mule/metadata" xmlns:sharepoint2010="http://www.mulesoft.org/schema/mule/sharepoint2010" xmlns:sharepoint="http://www.mulesoft.org/schema/mule/sharepoint" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/sharepoint http://www.mulesoft.org/schema/mule/sharepoint/current/mule-sharepoint.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/sharepoint2010 http://www.mulesoft.org/schema/mule/sharepoint2010/current/mule-sharepoint2010.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">

    <file:connector name="input" autoDelete="false" streaming="true" validateConnections="true" doc:name="File" readFromDirectory="C:\Users\rpearso7\_gar-data\input" />

    <flow name="Load-AgentList">
        <file:inbound-endpoint path="C:\Users\rpearso7\_gar-data\input"  responseTimeout="10000" doc:name="File" moveToDirectory="C:\Users\rpearso7\_gar-data\archive" connector-ref="input" moveToPattern="#[function:datestamp]-#[message.inboundProperties['originalFilename']]">
            <file:filename-regex-filter pattern="agent_list\.csv" caseSensitive="false"/>
        </file:inbound-endpoint>
        <dw:transform-message doc:name="Transform Message" metadata:id="fdb1aea0-6e94-425f-9493-ee71983b8eb1">
            <dw:input-payload mimeType="application/csv"/>
            <dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
payload]]></dw:set-payload>
        </dw:transform-message>
        <logger message="************** Payload Loaded" level="INFO" doc:name="Log Payload"/>
        <scatter-gather doc:name="Scatter-Gather">
            <threading-profile maxThreadsActive="1" poolExhaustedAction="WAIT"/>
            <processor-chain>
                <logger message="***************************** Truncate AgentList Table" level="INFO" doc:name="Logger"/>
                <db:update config-ref="GAR-DB-Connection-SSPI" doc:name="Truncate table">
                    <db:parameterized-query><![CDATA[truncate table src.AgentList;]]></db:parameterized-query>
                </db:update>
                <logger message="************************************ AgentList table truncated" level="INFO" doc:name="Logger"/>
            </processor-chain>
            <processor-chain>
                <logger message="********************************* Start Insert" level="INFO" doc:name="Logger"/>
                <db:insert config-ref="GAR-DB-Connection-SSPI" doc:name="Insert AgentList Data">
                    <db:parameterized-query><![CDATA[insert into src.AgentList (
    AgentId,
    PartyId,
    PartyType,
    AgentIdStatus,
    SalesOrg,
    AgentIdStatusStart,
    AgentIdStatusEnd,
    AgentName,
    SubOrganization,
    [Function],
    NewToOrg,
    NewToChannel,
    DaysAgentIdActive,
    Region,
    AgentPhone,
    CertificationSummary)
Values (
    #[payload.Agent_ID],
    #[payload.Party_ID],
    #[payload.Party_Type],
    #[payload.Agent_ID_Status],
    #[payload.Sales_Organization],
    #[payload.Agent_ID_Status_Start],
    #[payload.Agent_ID_Status_End],
    #[payload.Agent_Name],
    #[payload.Sub_Organization],
    #[payload.Function],
    #[payload.New_To_Org],
    #[payload.New_To_Channel],
    #[payload.Days_Agent_ID_Active],
    #[payload.Region],
    #[payload.Agent_Phone],
    #[payload.Certification_Summary])]]></db:parameterized-query>
                </db:insert>
            </processor-chain>
        </scatter-gather>
        <logger message="**************** Complete" level="INFO" doc:name="Logger"/>
    </flow>
</mule>

【问题讨论】:

  • 能否请您也添加日志?您是否尝试过调试应用程序?通过在记录器或插入处理步骤设置断点,您可以检查值运行时。 #[payload.Agent_ID] 似乎为空或根本不存在。你检查拼写了吗? Mule 表达式语言区分大小写...
  • 您最终能否从您的输入文件中发布一个 sn-p?

标签: sql mule mule-studio mule-component mule-esb


【解决方案1】:

当我在 CSV 文件上使用您的转换时,我查看了调试器中发生的情况。

我在第一个记录器处设置了一个断点,因此我可以停止执行并查看不同的Mule Expression Language (MEL) 表达式在流程的不同步骤中的表现。

当我在转换后评估#[payload]时;我得到一个带有 CSV 文件行的ArrayList

这似乎是正确的。

但是...由于 scather-gather 只向每个人发送一个副本,因此在 scather-gather 之后,调试器中也可以看到相同的有效负载。

详情见以下博文:Scatter-Gather in Mule ESB

Scatter-Gather 是 Mule ESB 运行时中的路由消息处理器, 同时向多个目标发送请求消息。那么它 收集来自所有路由的响应并将它们聚合回 单一响应。

据此,您的流程中的 DB INSERT 处理步骤将获得 ArrayListArrayList 的元素可以使用基于空的整数索引进行索引。您不能使用 CSV 文件的列名来使用它们。

首先您必须从ArrayList 中选择一个条目,然后您可以在ArrayList 的条目上使用CSV 文件中的列标题,如下例所示:

#[payload[0].Agent_id]

此 MEL 表达式按预期返回代理 ID。但是如果你尝试执行 #[payload.Agent_id] ;你会得到null

在我看来,您在INSERT 中正是这样做的。您不是插入从 CSV 文件创建的 ArrayList 的每个条目,而是尝试访问 ArrayList 而不是其元素上的 CSV 文件的列。

可能的解决方案是添加foreach scope

使用它,您可以遍历 ArrayList 的条目并将它们中的每一个插入到您的数据库表中。

还请在简化版的流程中查看不同状态下不同 MEL 表达式的结果:

(请注意,Mule 表达式语言区分大小写。如果将“ID”子字符串替换为“Id”,则返回“null”。)

我一直在使用包含以下内容的简单 CSV 文件进行测试:

Agent_ID,Agent_Name
7,james bond
1,Mr. 47
8,Dr. X

您可以考虑类似以下的解决方案:

我刚刚添加了一个foreach scope

此流程已生成以下控制台输出:

INFO  2018-03-14 16:08:37,736 [[testproject01].connector.file.mule.default.receiver.01] org.mule.transport.file.FileMessageReceiver: Lock obtained on file: X:\SomePathToTheFile\agent_list.csv
INFO  2018-03-14 16:08:38,485 [[testproject01].Load-AgentList.stage1.02] org.mule.api.processor.LoggerMessageProcessor: ************** Payload Loaded
INFO  2018-03-14 16:08:38,488 [[testproject01].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: ***************************** Truncate AgentList Table
INFO  2018-03-14 16:08:38,506 [[testproject01].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: ********************************* Start Insert
INFO  2018-03-14 16:08:38,506 [[testproject01].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: ********************************* Start Insert
INFO  2018-03-14 16:08:38,507 [[testproject01].ScatterGatherWorkManager.01] org.mule.api.processor.LoggerMessageProcessor: ********************************* Start Insert

我希望这是你想要达到的目标。

如果您还有其他问题或我误解了您的目标,请添加评论。

非常感谢。

【讨论】:

  • 感谢@Attila 非常彻底的回复。我很抱歉之前没有看到这个。我现在不记得我是如何解决这个问题的。但是,您的解决方案肯定会解决它。我非常感谢您的努力和分享的意愿。自从我最初遇到这个问题以来,我获得了更多的 xp 甚至我的 MCD 1 级证书。也许有一天我可以回报这个人情。 --瑞克
【解决方案2】:

当另一个进程针对同一个数据库表运行INSERT 语句时,我们在类似的场景中遇到了死锁问题。

场景:

TRUNCATE当前正在一个表上执行,同时,另一个进程INSERTS数据库同一个表中的一些数据。

首先优先考虑TRUNCATE 并获取表上的锁。一旦完成,然后去INSERT

你应该在执行TRUNCATE之前请求一个表锁。

如果您这样做,您就不会出现死锁——在INSERT 完成之前不会授予表锁,一旦您获得锁,另一个INSERT 就不会发生。

评论更新:

您可以使用LOCK TABLE 命令。

【讨论】:

  • 好吧,感谢您的洞察力,但这与手头的问题无关。我可以删除截断并得到同样的问题。我创建的每个写入数据库的流在有效负载中都有数据,但没有填充任何查询参数。此外,scatter-gather 设置为仅使用单个线程,因此截断将在插入之前发生。本质上它是串行处理的。
  • 结果是一个带有详细错误的 SQL 错误:“无法将值 NULL 插入列 'AgentId'”。这听起来不像是一个死锁问题。非常感谢您分享您的经验,但在这种情况下,问题似乎是其他问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 2013-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多