Sql 在Firebird中插入SELECT

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

我是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(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';