Вместо PL / SQL я бы предложил MERGE , который также известен как 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);