Sql 在Firebird中插入SELECT
我是firebird的新手,我有很多问题。我想在从另一个表中选择的表中插入不同的行 代码如下:Sql 在Firebird中插入SELECT,sql,select,insert,firebird,firebird2.5,Sql,Select,Insert,Firebird,Firebird2.5,我是firebird的新手,我有很多问题。我想在从另一个表中选择的表中插入不同的行 代码如下: /*CREATE GENERATOR POS; */ SET GENERATOR POS TO 1; SET TERM ^; create trigger BAS_pkassign for MATERIAL active before insert position 66 EXECUTE BLOCK AS declare posid bigint; select gen_id(P
/*CREATE GENERATOR POS; */
SET GENERATOR POS TO 1;
SET TERM ^;
create trigger BAS_pkassign
for MATERIAL
active before insert position 66
EXECUTE BLOCK
AS
declare posid bigint;
select gen_id(POS, 1)
from RDB$DATABASE
into :posid;
BEGIN
END
SET TERM ; ^
INSERT INTO MATERIAL ( /*ID */ LOCATION, POSID, ARTID, ARTIDCONT, QUANTITY )
SELECT 1000, ':posid', 309, BAS_ART.ID, 1
FROM BAS_ART
WHERE BAS_ART.ARTCATEGORY LIKE '%MyWord%'
ID应从66开始自动递增。posid应该从1开始自动递增
实际上它没有插入任何内容
我使用的是Firebird Maestro,刚刚打开了SQL脚本编辑器(在执行脚本时不会抛出任何错误消息)
有人能帮我吗
谢谢
其他信息:
触发器应该自动递增列“ID”-但我不知道如何确切地更改它以使其工作。。“:posid”使用它抛出一个错误:posid,但是像这样没有错误(我猜它被解释为一个字符串)。但我如何正确使用它呢
我执行它时不会出错。桌子的结构很简单。我有两张桌子: 一, 和2。其他表格
BAS_ART (ID (INTEGER), ARTCATEGORY (VARCHAR255))
->我想将表格BAS_ART中的所有条目(ARTCATEGORY列中包含“MyWord”)插入到MATERIAL表格中。对于我的大部分答案,我将假设一个非常简单的表格:
CREATE TABLE MyTable (
ID BIGINT PRIMARY KEY,
SomeValue VARCHAR(255),
posid INTEGER
)
自动增量标识符
Firebird(版本2.5之前)没有标识列类型(这将添加到Firebird 3中),相反,您需要使用序列(又名生成器)和触发器来获取该类型
序列
首先,您需要使用以下命令创建序列:
序列是原子的,这意味着交错的事务/连接不会得到重复的值,它也在事务控制之外,这意味着回滚
不会恢复到以前的值。在大多数情况下,序列应该始终增加,因此在问题开始时重置的值几乎在所有情况下都是错误的;例如,另一个连接可能会在执行的中途重置序列,从而导致出现POSID
的意外副本
触发
要生成自动增量标识符的值,需要在插入触发器之前使用,该触发器将生成的值分配给-在本例中-ID
列
CREATE TRIGGER trgMyTableAutoIncrement FOR MyTable
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
NEW.ID = NEXT VALUE FOR seqMyTable;
END
在本例中,I始终分配生成的值,仅当ID
为NULL
时分配生成的值
获取价值
要获取生成的值,可以使用INSERT
-语句的:
INSERT INTO MyTable (SomeValue) VALUES ('abc') RETURNING ID
插入到。。。挑选
使用插入到。。。选择
您可以从一个表中选择行并将其插入其他表中。它不适用于您的原因是,您试图将字符串值':pos'
分配给INTEGER
类型的列,这是不允许的
假设我有另一个表MyOtherTable
,其结构与MyTable
类似,我可以使用以下方法传输值:
INSERT INTO MyTable (SomeValue)
SELECT SomeOtherValue
FROM MyOtherTable
使用插入到。。。选择
除非仅插入一行,否则无法获取生成的值
关于POSID
我不清楚POSID应该是什么,应该有什么值。看起来您希望将单个插入到…中的值从1开始递增。。。选择
。在Firebird 2.5之前的版本中,以这种方式是不可能的(在Firebird 3中,您可以使用ROW\u NUMBER()
)
如果我的猜测是正确的,那么您将需要使用(或存储过程)为要插入的每一行赋值并增加值
执行块类似于:
EXECUTE BLOCK
AS
DECLARE posid INTEGER = 1;
DECLARE someothervalue VARCHAR(255);
BEGIN
FOR SELECT SomeOtherValue FROM MyOtherTable INTO :someothervalue DO
BEGIN
INSERT INTO MyTable (SomeValue, posid) VALUES (:someothervalue, :posid);
posid = posid + 1;
END
END
如果没有orderby
和SELECT
命令,posid的值基本上是没有意义的,因为没有保证的顺序。我不明白为什么需要触发器
这个问题:
我想将表BAS_ART中包含“MyWord”的所有条目插入到MATERIAL表中
可以通过单个插入解决。。。选择
语句
insert into material (id, location, posid, artid, quantity)
select next value for seq_mat_id, 1000, next value for seq_pos, id, 1
from bas_art
where artcategory = 'My Word';
这假设有第二个序列(也称为“生成器”),名为seq\u mat\u id
,它为列material.id提供新的id。您的触发器没有任何效果:它有语法错误,如果正确,则不会更新任何内容。我还非常确定':posid'
不是posid
列的有效值。您可能还希望包括执行此操作时出现的任何错误,请描述表结构以及您实际想要实现的目标触发器应自动递增列“ID”-但我不知道如何确切地更改它以使其工作。。“:posid”使用它抛出一个错误:posid,但是像这样没有错误(我猜它被解释为一个字符串)。但是我如何正确使用它呢?当我执行它时,我不会出错。桌子的结构很简单。我有两张桌子:一张。物料(ID、位置、POSID、ARTID、ARTIDCONT、数量、其他列)和2。other table BAS_ART(ID,ARTCATEGORY)->我想将表BAS_ART中包含“MyWord”的所有条目插入到MATERIAL表中@MarkRotterVeelPlease请在您的问题中包含此类信息,并包含数据类型,这比注释中更具可读性!我不清楚什么是POSID
,以及为什么应该生成它。我在这里能想到的触发的唯一原因是为id
列生成一个自动递增值。请注意,答案中的insert总是将1000
分配给此列,而不是问题中的位置
列。@MarkrotVeel:是的,我知道material.id
的常量值,但示例insert。。。在问题中选择
,因此我假设这就是目的所在。但是从序列中填充该列也很容易。在这个问题中,ID
列被注释掉了,但现在我只是吹毛求疵;)@马克:啊!我不知怎的
EXECUTE BLOCK
AS
DECLARE posid INTEGER = 1;
DECLARE someothervalue VARCHAR(255);
BEGIN
FOR SELECT SomeOtherValue FROM MyOtherTable INTO :someothervalue DO
BEGIN
INSERT INTO MyTable (SomeValue, posid) VALUES (:someothervalue, :posid);
posid = posid + 1;
END
END
insert into material (id, location, posid, artid, quantity)
select next value for seq_mat_id, 1000, next value for seq_pos, id, 1
from bas_art
where artcategory = 'My Word';