【问题标题】:Mule Sql Query - passing parameters to the IN operatorMule Sql Query - 将参数传递给 IN 运算符
【发布时间】:2014-06-16 05:45:21
【问题描述】:

我正在尝试创建一个执行大量 DB(Microsoft SQL Server 2008 DB)操作的 mule 流。

我执行的第一个数据库查询返回一个 ID 列表

select id from first_table;

我通过构建 ArrayList 的 Java 转换器运行有效负载: [1,2,3,4,5] 然后将其保存为变量indices

然后我尝试在另一个查询中使用这个数组

select * from another_table where first_table_fk in (#[flowVars.indices]);

但无论我做什么,我都会不断收到错误

不支持从 UNKNOWN 到 UNKNOWN 的转换。

在使用 IN 运算符时,Mule 无法处理 java.util.ArrayList(或常规数组 int[])。

然后我尝试将整个查询创建为字符串变量(然后在 中引用它)。

这会导致异常: java.lang.IllegalArgumentException:没有为 SQL 语句找到 SQL 策略:#[flowVars.queryString]

你能帮我解决我的问题吗(在 Mule sql 查询中使用 IN 运算符)?

我正在使用 Mule studio 3.4.0 CE。

谢谢!

【问题讨论】:

    标签: sql mule


    【解决方案1】:

    Mule 使用语句(来自 java.sql),因此不支持以这种方式使用 IN。每次出现的 MEL 表达式 (#[]) 都将替换为问号 (?),并且实际值将作为参数传递。我建议您通过动态构建查询并将其分配给 JDBC 连接器并使用通用端点执行它来解决此问题。

    1. 像这样创建一个 Java 类:

      public class CustomQueryBuilder implements Callable {
          @Override
          public Object onCall(MuleEventContext eventContext) throws Exception {
              JdbcConnector c = (JdbcConnector) eventContext.getMuleContext().getRegistry().lookupConnector("JDBC_connector");
      
              StringBuilder query = new StringBuilder();
              String queryBase = "select * from another_table where first_table_fk in (";
              query.append(queryBase);
      
              int numIndices = ((ArrayList<Integer>)eventContext.getMessage().getInvocationProperty("indices")).size();
              ArrayList<String> indices = new ArrayList<String>();
              for(int i=0; i<numIndices; i++) {
                      indices.add("#[flowVars.indices[" + i + "]");
              }
              query.append(StringUtils.join(indices, ", "));
              query.append(")");
      
              String finalQuery = query.toString();
      
              MessageDigest md = MessageDigest.getInstance("MD5");
              String queryDigest = String.format("%1$032X",new BigInteger(1, md.digest(finalQuery.getBytes("UTF-8"))));
      
              if (!c.getQueries().containsKey(queryDigest)) {
                      c.getQueries().put(queryDigest, finalQuery);
              }
      
              eventContext.getMessage().setInvocationProperty("generatedQueryKey", queryDigest);
      
              return eventContext.getMessage();
          }
      }
      
    2. 在您设置“索引”流变量后在您的流中使用它。

      <component class="CustomQueryBuilder"/>
      
    3. 然后插入一个通用的出站端点而不是您的 jdbc 出站端点并引用创建的查询。

      <outbound-endpoint exchange-pattern="request-response" address="jdbc://#[flowVars.generatedQueryKey]" />
      

    【讨论】:

    • 感谢您的解释。我发现了其他 Mule 查询弱点(一旦查询变得更加复杂,连接等)就会出现问题。通过使用自定义 Java 转换器,我得到了对 JdbcConnector 的引用,如您所示,然后从中创建了 PreparedStatement。不是很优雅,但它可以工作,你可以实际调试它。
    猜你喜欢
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多