如何在存储过程的执行语句中使用生成器?
How to use a generator in my execute statement in a stored procedure?
我正在尝试在 IBExpert 中为 Firebird 2.5 数据库创建一个简单的存储过程。不过,我在使用发电机时遇到了麻烦。我想我已经创建了一个有效的生成器和触发器。但我不知道如何在我的执行语句中应用它们。
Table:
ID BIGINT NOT NULL,
DATUM INTEGER,
KOSTENST INTEGER,
KUNDENNUMMER INTEGER,
DISPONENT CHAR(5),
KONTAKTART CHAR(2)
触发器:
CREATE OR ALTER trigger kontakte_erw_id_bi for kontakte_erw_id
active before insert position 0
AS
BEGIN
if (NEW.ID is NULL) then NEW.ID = GEN_ID(ID_KONTAKTE, 1);
END
发电机:
CREATE SEQUENCE ID_KONTAKTE;
ALTER SEQUENCE ID_KONTAKTE RESTART WITH 0;
程序语句(我想问题就出在这里?我如何处理触发器来填充ID列?):
for execute statement('
SELECT
KONTAKTE.DATUM,
KUNDEN.KOSTENST,
KUNDEN.KUNDENNR,
KONTAKTE.DISPONENT,
KONTAKTE.KONTAKTART
FROM KONTAKTE
INNER JOIN KUNDEN ON KONTAKTE.KUNDENNR = KUNDEN.KUNDENNR
')
on external 'db'
as user 'xxx' password xxx
into :XDATUM, :XKOSTENST, :XKUNDENNUMMER, :XDISPONENT, :XKONTAKTART
do
begin
execute statement
('update or insert into KONTAKTE_ERW_ID (DATUM, KOSTENST, KUNDENNUMMER, DISPONENT, KONTAKTART)
values
(:DATUM, :KOSTENST, :KUNDENNUMMER, :DISPONENT, :KONTAKTART)')
(DATUM:= XDATUM, KOSTENST := XKOSTENST, KUNDENNUMMER := XKUNDENNUMMER, DISPONENT := XDISPONENT, KONTAKTART := XKONTAKTART)
on external 'db'
as user 'xxx' password xxx;
end
这是我在尝试填充图表时遇到的错误:
336003099 : UPDATE OR INSERT field list does not match primary key of table KONTAKTE_ERW_ID
Statement : update or insert into KONTAKTE_ERW_ID (DATUM, KOSTENST, KUNDENNUMMER, DISPONENT, KONTAKTART)
values
(?, ?, ?, ?, ?)
你的问题是为了能够使用 UPDATE OR INSERT
,Firebird 需要知道行何时已经存在。为此,它要么使用主键,要么 - 如果提供 - MATCHING
子句。
在您的声明中,您没有提供主键,也没有提供 MATCHING
子句,因此 Firebird 无法决定是否有行要更新或是否应该插入。
在你的情况下,在语句中包含主键似乎不是一个选项(或者你需要应用一个方案来生成在不同数据库中唯一的标识符),所以你唯一的选择是使用MATCHING
子句。但是,查看您的专栏,我并没有立即看到可以被认为是独一无二的东西。
我正在尝试在 IBExpert 中为 Firebird 2.5 数据库创建一个简单的存储过程。不过,我在使用发电机时遇到了麻烦。我想我已经创建了一个有效的生成器和触发器。但我不知道如何在我的执行语句中应用它们。
Table:
ID BIGINT NOT NULL,
DATUM INTEGER,
KOSTENST INTEGER,
KUNDENNUMMER INTEGER,
DISPONENT CHAR(5),
KONTAKTART CHAR(2)
触发器:
CREATE OR ALTER trigger kontakte_erw_id_bi for kontakte_erw_id
active before insert position 0
AS
BEGIN
if (NEW.ID is NULL) then NEW.ID = GEN_ID(ID_KONTAKTE, 1);
END
发电机:
CREATE SEQUENCE ID_KONTAKTE;
ALTER SEQUENCE ID_KONTAKTE RESTART WITH 0;
程序语句(我想问题就出在这里?我如何处理触发器来填充ID列?):
for execute statement('
SELECT
KONTAKTE.DATUM,
KUNDEN.KOSTENST,
KUNDEN.KUNDENNR,
KONTAKTE.DISPONENT,
KONTAKTE.KONTAKTART
FROM KONTAKTE
INNER JOIN KUNDEN ON KONTAKTE.KUNDENNR = KUNDEN.KUNDENNR
')
on external 'db'
as user 'xxx' password xxx
into :XDATUM, :XKOSTENST, :XKUNDENNUMMER, :XDISPONENT, :XKONTAKTART
do
begin
execute statement
('update or insert into KONTAKTE_ERW_ID (DATUM, KOSTENST, KUNDENNUMMER, DISPONENT, KONTAKTART)
values
(:DATUM, :KOSTENST, :KUNDENNUMMER, :DISPONENT, :KONTAKTART)')
(DATUM:= XDATUM, KOSTENST := XKOSTENST, KUNDENNUMMER := XKUNDENNUMMER, DISPONENT := XDISPONENT, KONTAKTART := XKONTAKTART)
on external 'db'
as user 'xxx' password xxx;
end
这是我在尝试填充图表时遇到的错误:
336003099 : UPDATE OR INSERT field list does not match primary key of table KONTAKTE_ERW_ID
Statement : update or insert into KONTAKTE_ERW_ID (DATUM, KOSTENST, KUNDENNUMMER, DISPONENT, KONTAKTART)
values
(?, ?, ?, ?, ?)
你的问题是为了能够使用 UPDATE OR INSERT
,Firebird 需要知道行何时已经存在。为此,它要么使用主键,要么 - 如果提供 - MATCHING
子句。
在您的声明中,您没有提供主键,也没有提供 MATCHING
子句,因此 Firebird 无法决定是否有行要更新或是否应该插入。
在你的情况下,在语句中包含主键似乎不是一个选项(或者你需要应用一个方案来生成在不同数据库中唯一的标识符),所以你唯一的选择是使用MATCHING
子句。但是,查看您的专栏,我并没有立即看到可以被认为是独一无二的东西。