Sql 使用update或insert语句添加到整数值
我试图在Firebird 2.5中创建一个SQL语句,以便通过添加到整数数量(如果记录存在)或简单地插入新行来更新整数数量。我似乎找不到一个真正的答案来回答我关于增加一定数量的问题,如果它已经存在的话 我能想到的SQL如下所示:Sql 使用update或insert语句添加到整数值,sql,firebird,firebird2.5,Sql,Firebird,Firebird2.5,我试图在Firebird 2.5中创建一个SQL语句,以便通过添加到整数数量(如果记录存在)或简单地插入新行来更新整数数量。我似乎找不到一个真正的答案来回答我关于增加一定数量的问题,如果它已经存在的话 我能想到的SQL如下所示: UPDATE OR INSERT INTO Pencils(Number, Location, Quantity) VALUES('12345678/90', 'TOP', 20) MATCHING(Number, Location); 因此,如果有一个匹配的记录,我
UPDATE OR INSERT INTO Pencils(Number, Location, Quantity)
VALUES('12345678/90', 'TOP', 20)
MATCHING(Number, Location);
因此,如果有一个匹配的记录,我想在实际的20个数量上加上一定的数量
就像我对UPDATE
语句所做的那样:
UPDATE Pencils SET Quantity = Quantity + 20 WHERE Number = '12345678/90'
使用UPDATE或INSERT
语句是否可以获得这样的结果,或者是否有其他方法?
.
编辑:
用IBExpert/Delphi解决参数查询
MERGE INTO Pencils AS Dest
USING (SELECT CAST(:myNumb as varchar(30)) AS Number,
CAST(:myLoca as varchar(10)) AS Location,
CAST(:myQuan as integer) AS Quantity
FROM RDB$DATABASE) Src
ON (Dest.Number = Src.Number AND Dest.Location = Src.Location)
WHEN MATCHED THEN
UPDATE SET Dest.Quantity = Dest.Quantity + Src.Quantity
WHEN NOT MATCHED THEN
INSERT (Number, Location, Quantity) VALUES (Src.Number, Src.Location, Src.Quantity);
将Firebird's用于复杂的上部结构:
MERGE INTO Pencils AS Dest
USING (SELECT '12345678/90' AS Number,
'TOP' AS Location,
20 As Quantity
FROM RDB$DATABASE) Src
ON (Dest.Number = Src.Number AND Dest.Location = Src.Location)
WHEN MATCHED THEN
UPDATE SET Dest.Quantity = Dest.Quantity + 10
WHEN NOT MATCHED THEN
INSERT (Number, Location, Quantity) VALUES (Src.Number, Src.Location, Src.Quantity);
这里唯一的复杂性是更新时动态计算的数量。如果只是用静态值覆盖现有记录,则可以更简洁地使用
示例:
SQL> SELECT * FROM Pencils;
NUMBER QUANTITY LOCATION
================ ============ ================
123 5 TOP
123 10 MID
SQL> MERGE INTO Pencils AS Dest
CON> USING (SELECT '123' AS Number, 'TOP' AS Location, 20 As Quantity
CON> FROM RDB$DATABASE) Src ON (Dest.Number = Src.Number AND Dest.Location = Src.Location)
CON> WHEN MATCHED THEN
CON> UPDATE SET Dest.Quantity = Dest.Quantity + 10
CON> WHEN NOT MATCHED THEN
CON> INSERT (Number, Location, Quantity) VALUES (Src.Number, Src.Location, Src.Quantity);
SQL> SELECT * FROM Pencils;
NUMBER QUANTITY LOCATION
================ ============ ================
123 15 TOP
123 10 MID
SQL> SELECT * FROM Pencils;
NUMBER QUANTITY LOCATION
================ ============ ================
123 5 TOP
123 10 MID
SQL> MERGE INTO Pencils AS Dest
CON> USING (SELECT '123' AS Number, 'TOP' AS Location, 20 As Quantity
CON> FROM RDB$DATABASE) Src ON (Dest.Number = Src.Number AND Dest.Location = Src.Location)
CON> WHEN MATCHED THEN
CON> UPDATE SET Dest.Quantity = Dest.Quantity + 10
CON> WHEN NOT MATCHED THEN
CON> INSERT (Number, Location, Quantity) VALUES (Src.Number, Src.Location, Src.Quantity);
SQL> SELECT * FROM Pencils;
NUMBER QUANTITY LOCATION
================ ============ ================
123 15 TOP
123 10 MID
123 20 BOT
确保可以使用“更新”或“插入”。
但您必须重复您的键值,这会使您的查询变得脆弱(只更改两个值中的一个-并且您得到了行为不端的查询)
在Delphi中,大多数库都不支持同名的多个SQL参数,因此您可能需要实际创建两个参数(名称相似但清晰),才能使这种方法起作用
所以,总而言之,MERGE
将是更好、更安全的方法。但为了完整性,这也应该起作用
如果我正确理解你的陈述,如果记录不存在,它将插入20作为数量,但它应该插入10(10是一个dnymic值,我将从Delphi程序获得,它将是要插入的数量)@VirusInside然后将语句更改为使用10而不是20。但是我认为Firebird不允许在使用中使用SELECT WITH FROMstatement@virussinside坦率地说,这是一个不同的问题,一个人可能回答了数百万次。这是在准备查询时的母鸡和鸡蛋问题,FB在知道数据类型并完成输出行集的二进制缓冲区布局之前无法开始准备,并且在开始准备之前无法推断未知数据类型。因此,您应该在之前硬编码参数数据类型<代码>选择?从RDB$DATABASE
通常会失败,但从RDB$DATABASE选择强制转换(?as integer)将起作用。打它的荣誉。我在埋伏中等待,想知道你是否在没有参数的情况下偷懒。此外,Firebird中没有像varchar
这样的数据类型!您必须指定长度为了完整性,您是否可以显示更新或插入,其中新插入的数量不是简单的“零+增量”?根据澄清意见,我认为OP确实希望新记录默认为“零+增量”,但书面问题是“20表示新记录”和“数量+=10表示更新”。这将是一个不同的UP或IN,可能对某些人也有用。@pilcrow确切地说,我只有一个数量,例如20,如果找不到数量和位置,我希望有一个新的记录,或者简单地将这些相同的20添加到现有数量中。所以它是'zero+newQuantity'或'oldQuantity+=newQuantity'哦,我明白了,我没有想到COALESCE,但你是对的,对于同一个值有不同的参数是非常脆弱的。谢谢你的帮助。@pilcrow完成了,但我不在个人电脑自动取款机上,所以实际上没有试过。可能有次要语法errors@Arioch与我上一次对答案的评论相同的问题是,是否有可能用参数(如:myNumber、:MyLocation)来替换我们在SELECT中输入的静态值。对于total freaks,还有另一种古老的方法可以做到这一点,它早于MERGE、U-O-I甚至Firebird本身。它需要创建可更新视图,其中U/I/D操作由触发器中的PSQL代码实现,然后在插入之前触发器将检查基础表中是否已经有行或没有行。但这将是一台鲁布·戈德伯格的机器。。。像Delphi XE2:-D一样可爱迷人
UPDATE OR INSERT
INTO Pencils(Number, Location, Quantity)
VALUES( '12345678/90', 'TOP',
20 + coalesce(
( Select Quantity
From Pencils
where Number = '12345678/90'
and Location = 'TOP' )
,0 )
)
MATCHING(Number, Location);
select rdb$get_context('SYSTEM', 'ENGINE_VERSION') as version
, rdb$character_set_name
from rdb$database;
VERSION | RDB$CHARACTER_SET_NAME
:------ | :---------------------------------------------------------------------------------------------------------------------------
3.0.5 | UTF8
create table Pencils( Number varchar(20), Location varchar(10), Quantity int,
constraint pk_pens primary key (number, location) )
✓
INSERT INTO Pencils(Number, Location, Quantity)
VALUES('12345678/90', 'TOP', 13)
1 rows affected
INSERT INTO Pencils(Number, Location, Quantity)
VALUES('12345678/90', 'MID', 7)
1 rows affected
select * from pencils
NUMBER | LOCATION | QUANTITY
:---------- | :------- | -------:
12345678/90 | TOP | 13
12345678/90 | MID | 7
UPDATE OR INSERT
INTO Pencils(Number, Location, Quantity)
VALUES( '12345678/90', 'TOP',
20 + coalesce(
(Select Quantity
From Pencils
where Number = '12345678/90'
and Location = 'TOP')
,0 )
)
MATCHING(Number, Location);
1 rows affected
UPDATE OR INSERT
INTO Pencils(Number, Location, Quantity)
VALUES( '12345678/90', 'BOTTOM',
20 + coalesce(
(Select Quantity
From Pencils
where Number = '12345678/90'
and Location = 'BOTTOM')
,0 )
)
MATCHING(Number, Location);
1 rows affected
select * from pencils
NUMBER | LOCATION | QUANTITY
:---------- | :------- | -------:
12345678/90 | TOP | 33
12345678/90 | MID | 7
12345678/90 | BOTTOM | 20
.........
VALUES( '12345678/90', 'TOP',
coalesce( 20 + -- increment when found
( Select Quantity
From Pencils
where Number = '12345678/90'
and Location = 'TOP' )
, -15 /* new value when not found */ )
)
.......