如果购买的桌子上已经有砖块,我需要更新砖块的价格,否则我必须插入它。我写了这段代码:
DECLARE
colour VARCHAR2(10) :='brown';
shape VARCHAR2(10) :='rectangle';
price NUMBER(10,2) :=21;
BEGIN
UPDATE purchased_bricks pb
SET pb.price = price
WHERE pb.colour = colour
AND pb.shape = shape;
IF sql%rowcount = 0
THEN
INSERT INTO purchased_bricks
VALUES(colour,shape,price);
END IF;
END;
我第一次运行它,插入了记录。然后,当我尝试更新砖的价格时,更改未反映在表中。
答案 0 :(得分:4)
我建议使用 MERGE 代替PL / SQL,也称为 UPSERT (UPdate和/或inSERT)。
这是一个例子:
SQL> CREATE TABLE purchased_bricks
2 (
3 colour VARCHAR2 (10),
4 shape VARCHAR2 (20),
5 price NUMBER
6 );
Table created.
SQL> MERGE INTO purchased_bricks p
2 USING (SELECT 1 FROM DUAL) x
3 ON ( p.colour = '&&par_colour'
4 AND p.shape = '&&par_shape')
5 WHEN MATCHED
6 THEN
7 UPDATE SET p.price = &&par_price
8 WHEN NOT MATCHED
9 THEN
10 INSERT (colour, shape, price)
11 VALUES ( '&&par_colour', '&&par_shape', &&par_price);
Enter value for par_colour: brown
Enter value for par_shape: rectangular
Enter value for par_price: 21
1 row merged.
SQL> select * From purchased_bricks;
COLOUR SHAPE PRICE
---------- -------------------- ----------
brown rectangular 21
让我们尝试其他价格:
SQL> undefine par_price
SQL> MERGE INTO purchased_bricks p
2 USING (SELECT 1 FROM DUAL) x
3 ON ( p.colour = '&&par_colour'
4 AND p.shape = '&&par_shape')
5 WHEN MATCHED
6 THEN
7 UPDATE SET p.price = &&par_price
8 WHEN NOT MATCHED
9 THEN
10 INSERT (colour, shape, price)
11 VALUES ( '&&par_colour', '&&par_shape', &&par_price);
Enter value for par_price: 50
1 row merged.
SQL> select * from purchased_bricks;
COLOUR SHAPE PRICE
---------- -------------------- ----------
brown rectangular 50
SQL>
调整了上面的示例,使其可以在SQL * Plus中使用。根据您使用的工具,参数的值可能会被不同地引用,例如
MERGE INTO purchased_bricks p
USING (SELECT 1 FROM DUAL) x
ON ( p.colour = :par_colour
AND p.shape = :par_shape)
WHEN MATCHED
THEN
UPDATE SET p.price = :par_price
WHEN NOT MATCHED
THEN
INSERT (colour, shape, price)
VALUES ( :par_colour, :par_shape, :par_price);
答案 1 :(得分:2)
我找到了。问题在于变量名与列名相同。因此set pb.price = price
用现有表值而不是变量值更新了表。解决方案是通过使用前缀来使名称不同。
DECLARE
l_colour VARCHAR2(10) :='brown';
l_shape VARCHAR2(10) :='rectangle';
l_price NUMBER(10,2) :=21;
BEGIN
UPDATE purchased_bricks pb
SET pb.price = l_price
WHERE pb.colour = l_colour
AND pb.shape = l_shape;
IF sql%rowcount = 0
THEN
INSERT INTO purchased_bricks
VALUES(colour,shape,price);
END IF;
END;
答案 2 :(得分:1)
您可以对所需的过滤条件进行计数,如果大于0则不更新,否则插入新行;如下所示:
DECLARE
colour VARCHAR2(10) :='brown';
shape VARCHAR2(10) :='rectangle';
price NUMBER(10,2) :=21;
count_row Number;
BEGIN
Select count(*) into count_row from purchased_bricks pb
WHERE pb.colour = colour
AND pb.shape = shape;
IF count_row > 0
THEN
UPDATE purchased_bricks pb
SET pb.price = price
WHERE pb.colour = colour
AND pb.shape = shape;
ELSE
INSERT INTO purchased_bricks
VALUES(colour,shape,price);
END IF;
END;