我目前正在与Firebird合作并尝试利用UPDATE OR INSERT功能来解决我们软件中的特定新案例。基本上,我们需要从源中提取数据并将其放入现有表中,然后定期更新该数据并添加任何新引用。源不是数据库,所以不是使用MERGE来链接两个表(除非我们创建一个单独的表然后合并它,但这似乎是不必要的)。
问题在于我们无法使用现有表的主键进行匹配,因为我们需要根据从源获取的ID进行匹配。我们可以使用MATCHING子句没有问题,但问题是现有表的主键每次都会更新到下一个键,因为插入机会必须在查询中。以下是用于演示问题的查询(以及c#参数添加)。
UPDATE OR INSERT INTO existingtable (PrimaryKey, UniqueSourceID, Data) VALUES (?,?,?) MATCHING (UniqueSourceID);
this.AddInParameter("PrimaryKey", FbDbType.Integer, itemID);
this.AddInParameter("UniqueSourceID", FbDbType.Integer, source.id);
this.AddInParameter("Data", FbDbType.SmallInt, source.data);
问题表明,每次UPDATE触发时,主键也会更改为下一个递增的键我需要一种方法在更新时单独保留主键,但如果插入则需要插入它。
答案 0 :(得分:3)
不要手动生成主键,让触发器在nessesary时生成:
CREATE SEQUENCE seq_existingtable;
SET TERM ^ ;
CREATE TRIGGER Gen_PK FOR existingtable
ACTIVE BEFORE INSERT
AS
BEGIN
IF(NEW.PrimaryKey IS NULL)THEN NEW.PrimaryKey = NEXT VALUE FOR seq_existingtable;
END^
SET TERM ; ^
现在您可以从语句中省略PK字段:
UPDATE OR INSERT INTO existingtable (UniqueSourceID, Data) VALUES (?,?) MATCHING (UniqueSourceID);
当语句触发insert
时,触发器将负责创建PK。如果您需要知道生成的PK,请使用RETURNING
语句的UPDATE OR INSERT
子句。