IBExpert 插入变量给定的列值

Posted

技术标签:

【中文标题】IBExpert 插入变量给定的列值【英文标题】:IBExpert insert into with column value given by variable 【发布时间】:2019-09-26 06:52:19 【问题描述】:

在 IBExpert 中,我在“主程序”中循环访问日期,并尝试将当前循环的日期设置为要插入的表的“日期”列中的值。

我要插入的表格非常简单:

Table Name: FTE_TABLE
|---------------------|------------------|------------------|
|         GESCHST     |        DATUM     |       FTE        |
|---------------------|------------------|------------------|
|         Integer     |        Date      |      Integer     |
|---------------------|------------------|------------------|

我尝试了很多方法。不过我的理解是它应该看起来像这样:

FOR EXECUTE STATEMENT
('
SELECT
    geschst,
    :XDATUM_FILTER as DATUM,
    count(personalnr)

FROM personal

WHERE
    eintritt1 is not null
    and (austritt1 is null or austritt1 >=  :XDATUM_FILTER)

GROUP BY geschst, DATUM
')
(XDATUM_FILTER := XDATUM_FILTER)

          on external 'xxx'
          as user 'xxx' password 'xxx'

          into :XGESCHST, :XDATUM, :XFTE

 do
  begin

    execute statement

    ('insert into FTE (GESCHST, DATUM, FTE_TABLE)

  values

(:GESCHST, :DATUM, :FTE)
')

   (GESCHST:= XGESCHST, DATUM := XDATUM, FTE:=XFTE)

        on external 'xxx'
        as user 'xxx' password 'xxx';

  end

我收到此错误消息:

Error Message:
----------------------------------------
Unsuccessful execution caused by system error that does not preclude 
successful execution of subsequent statements.
Execute statement error at isc_dsql_prepare :
335544569 : Dynamic SQL Error
335544436 : SQL error code = -804
335544573 : Data type unknown

预期的结果是 GESCHST 和 FTE 列填充了 SELECT 语句的返回值,而 DATUM 列填充了变量 XDATUM_FILTER

提前感谢您的任何提示!

【问题讨论】:

AFAIK IBExpert/Firebird 不使用 PL/SQL。我稍微更改了您的标签,希望其他人现在能接受。 在“插入到 FTE”语句中,您将整数插入 FTE_TABLE 而不是 FTE。是不是打错字了? 只需进行第一个查询order by austritt1 descending nulls first 并继续迭代。一旦值低于阈值参数 - 取消循环。这当然会排除避免迭代和使用insert-select 的机会。但是,如果源数据库和目标数据库相同 - 您可以在该数据库上将其设为 Stored Procedure,以便为您的主数据库调用,或者甚至向该数据库发出 execute block 【参考方案1】:

如果您在 select 子句中使用参数(就像使用 :XDATUM_FILTER 一样),则 Firebird 不知道该参数的数据类型。这会导致 Data type unknown 错误。

要解决此问题,您需要将参数显式转换为所需的类型,因此请使用:

SELECT
    geschst,
    cast(:XDATUM_FILTER as DATE) as DATUM,
    count(personalnr)

这仅适用于最近的 Firebird 3.0 及更高版本,在早期版本中无法投射参数。

原因是Firebird在prepare时需要知道参数的类型,而不能通过变量来判断。

但是,您也可以忽略此列:您无需在远程数据库中选择此列即可获得所需的结果。

另外,如果您从中选择的远程数据库和您要插入到的远程数据库是同一个数据库,那么使用INSERT ... SELECT 而不是选择、迭代结果可能会更好(更快更简单)并为每一行插入。

【讨论】:

我明天会测试这个并给你反馈!不过看起来不错 :) 谢谢! 不,这在 Firebird 2.5 中是不可能的。我为你测试过:)

以上是关于IBExpert 插入变量给定的列值的主要内容,如果未能解决你的问题,请参考以下文章

SQLite3代码动态插入要删除的行数据的列值

TSQL设置表变量的列值

SQL求助,我要想在一张表新增多行,只有第一列值不同,后面的列值相同,该怎么插入?

更新熊猫 groupby().last() 的列值

如何将数据库中的列值获取到jLabel

重置前根据增加的列值选择最后一行?