【问题标题】:FireDAC Array DML and Returning clausesFireDAC 数组 DML 和返回子句
【发布时间】:2021-03-19 07:54:28
【问题描述】:

使用FireDACArray DML 功能,似乎无法使用RETURNING 子句(在我的例子中是PostgeSQL)。

如果我运行一个简单的插入查询,例如:

    With FDQuery Do
     begin        
      SQL.Text := 'INSERT INTO temptab(email, name) '
       +'VALUES (''email1'', ''name1''), '
       +'(''email2'', ''name2'') '
       +'RETURNING id';
      Open;
     end;

查询返回两条记录,其中包含新插入记录的 id。

对于较大的插入,我更喜欢使用Array DML,但在某些情况下,我还需要能够获取返回的数据。

Open 函数没有ATimes 参数。虽然您可以使用Array DML 调用Open,但它只会插入和返回第一条记录。

我找不到任何其他似乎有助于实现这一点的属性和方法。我已经在 Praxis 上发帖,看看是否有人有任何想法,但我没有任何回应。我还在 Quality Central 上将此作为新功能请求发布。

如果有人知道使用Array DML 实现此目的的方法,我将不胜感激,但我的主要问题是如果我坚持从数据库中检索插入的数据(主要是 ID)的最有效途径是什么Array DML?

我想到了几个想法,但似乎都不是很吸引人:

  1. StartTransactionCommit 内并在插入之后检索最后插入的记录的ID,然后向后抓取所需的编号。这似乎有点冒险,虽然在交易中,应该没问题。
  2. 向相关表中添加一个整数字段,并使用唯一标识符填充每个插入的记录,然后插入检索具有该标识符的记录。虽然这将确保返回插入的记录,但除非我索引用于存储标识符的字段,否则效率会相对较低。

以上两者都取决于将记录插入到数据库中的顺序,这些记录按照它们提供给Array DML 的顺序,但我假设/希望这是给定的。

我希望对上述选项中的最佳(即最有效和最可靠)的意见以及关于替代甚至更好选项的任何建议,即使这些需要放弃 Array DML 需要 Returning 子句。

【问题讨论】:

    标签: firedac


    【解决方案1】:

    您实际上可以获得所有返回的 ID。您可以使用 {INTO } 告诉 Firedac 将结果值存储在参数中。例如看下面的代码:

    FDQuery.SQL.Text := 'INSERT into tablename (fieldname) values (:p1) returning id {into :p2}';
    FDQuery.Params.ArraySize := 2;
    FDQuery.Params[0].AsStrings[0] := 'one';
    FDQuery.Params[0].AsStrings[1] := 'two';
    
    FDQuery.Params[1].ParamType := ptInputOutput;
    FDQuery.Params[1].DataType  := ftLargeInt;
    
    FDQuery.Execute(2,0);
    
    ID1 := FDQuery.Params[1].AsLargeInts[0];
    ID2 := FDQuery.Params[1].AsLargeInts[1];
    

    这在每个 arraydml 元素返回 1 行时有效。我认为它不适用于 >1 行,但我没有测试过。如果是这样,您必须知道哪个结果与您的 arraydml 元素相对应。

    请注意,当 arraydml 中的一个或多个元素返回 0 行时,Firedac 会引发 AV。例如,当您更新同时被删除的行时。 AV 与数组 DML 本身无关。当FDQuery.Execute;被调用,你也会得到一个 AV。

    我之前在 delphipraxis 论坛上提出了另一个选项,但这是一个次优的解决方案,因为它使用临时表来存储 ID: https://en.delphipraxis.net/topic/4693-firedac-array-dml-returning-values-from-inserted-records/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-07
      • 2015-10-09
      • 2022-10-21
      • 1970-01-01
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多