Нужно обновить, если есть, или вставить значения - PullRequest
0 голосов
/ 24 декабря 2018

Мне нужно обновить цену кирпича, если в купленной таблице уже есть кирпич, иначе я должен вставить его.Я написал этот код:

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;

При первом запуске я вставил запись.Затем, когда я попытался обновить цену кирпича, изменение не было отражено в таблице.

Ответы [ 3 ]

0 голосов
/ 24 декабря 2018

Вместо 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);
0 голосов
/ 24 декабря 2018

Вы можете подсчитать требуемый критерий фильтрации и, если он больше 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;
0 голосов
/ 24 декабря 2018

Я нашел это.Проблема заключалась в том, что имена переменных были такими же, как имена столбцов.Таким образом, 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...