Как использовать параметры процедуры в операторе слияния - PullRequest
1 голос
/ 28 февраля 2009

Я создаю процедуру для обновления / вставки таблицы, используя оператор слияния (upsert). Теперь у меня есть проблема: используя параметры процедуры, я должен сделать это upsert.

процедура xyz (тип a в таблице.%, B в типе table.b%, ....) является некоторые локальные переменные; начать объединить в target_table используя исходную таблицу - вместо исходной таблицы, здесь я должен использовать параметры процедуры вкл (условие по первичному ключу в таблице) когда соответствует обновить таблицу когда не совпадают, то вставить таблицу; конец XYZ; так как использовать параметры процедуры вместо исходной таблицы в операторе слияния ?? или же Предложите мне запрос для извлечения параметров процедуры и использования его в качестве значений исходной таблицы.

помогите мне, пожалуйста. Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 20 апреля 2017

Я знаю, что я опоздал на вечеринку на восемь лет, но я думаю, что пытался сделать что-то похожее на то, что вы делали, но пытался выполнить Upsert на основе параметров, переданных в хранимую процедуру, которая возвращает пустую строку в случае успеха и ошибка в случае возврата к моему VB-коду. Ниже приведен весь мой код вместе с комментариями, объясняющими, что я сделал и почему я это сделал. Дайте мне знать, если это поможет вам или кому-либо еще. Я впервые отвечаю на пост.

PROCEDURE UpsertTSJobData(ActivitySeq_in IN NUMBER,
  Owner_in In VARCHAR2,
  NumTrailers_in IN NUMBER,
  ReleaseFormReceived_in IN NUMBER,
  Response_out OUT VARCHAR2) AS

  err_num NUMBER;
  err_msg VARCHAR2(4000);

  BEGIN
    --This top line essentially does a "SELECT *" from the named table
    --and looks for a match based on the "ON" statement below
    MERGE INTO glob1app.GFS_TS_JOBDATA_TAB tsj
    --This select statement is used for the INSERT when no match
    --is found and the UPDATE when a match is found.
    --It creates a "pseudo-table"
    USING (
      SELECT ActivitySeq_in AS ActSeq,
        Owner_in As Owner,
        NumTrailers_in As NumTrailers,
        ReleaseFormReceived_in As ReleaseFormReceived
        FROM DUAL) input
    --This ON statement is what we're doing the match on to find
    --matching records. This decides whether it will be an
    --INSERT or an UPDATE
    ON (tsj.Activity_seq = ActivitySeq_in)
    WHEN MATCHED THEN
      --Here we UPDATE based on the passed in input table
      UPDATE
        SET OWNER = input.owner,
          NUMTRAILERS = input.NumTrailers,
          RELEASEFORMRECEIVED = input.releaseformreceived
    WHEN NOT MATCHED THEN
      --Here we INSERT based on the passed in input table
      INSERT (
        ACTIVITY_SEQ,
        OWNER,
        NUMTRAILERS,
        RELEASEFORMRECEIVED
        )
      VALUES (
        input.actseq,
        input.owner,
        input.numtrailers,
        input.releaseformreceived
    );

    Response_out := '';

    EXCEPTION
      WHEN OTHERS THEN
        err_num := SQLCODE;
        err_msg := SUBSTR(SQLERRM, 1, 3900);
        Response_out := TO_CHAR (err_num) || ': ' || err_msg;
  END; 
0 голосов
/ 28 февраля 2009

Очень сложно ответить на ваш вопрос, что именно вы, но я понимаю, вы хотите, чтобы таблица, в которую вы объединяетесь (или включена), была динамичной. В этом случае вам следует использовать пакет DBMS_SQL для создания динамического SQL

0 голосов
/ 28 февраля 2009

Маби что-то вроде

DECLARE V_EXISTS NUMBER;
BEGIN SELECT COUNT(*) INTO V_EXISTS FROM TARGET_TABLE WHERE PK_ID = :ID;

    IF V_EXISTS  > 0 THEN
        -- UPDATE
    ELSE
        -- INSERT
    END IF;
END;

Также вы можете попробовать использовать так называемую временную таблицу (выберите из ДВОЙНОГО)

CREATE TABLE TEST (N NUMBER(2), NAME VARCHAR2(20), ADRESS VARCHAR2(100));
INSERT INTO TEST VALUES(1, 'Name1', 'Adress1');
INSERT INTO TEST VALUES(2, 'Name2', 'Adress2');
INSERT INTO TEST VALUES(3, 'Name3', 'Adress3');
SELECT * FROM TEST;
-- test update
MERGE INTO TEST trg
USING (SELECT 1 AS N, 'NameUpdated' AS NAME, 
  'AdressUpdated' AS ADRESS FROM Dual )  src                
ON ( src.N = trg.N )
WHEN MATCHED THEN
    UPDATE 
    SET trg.NAME = src.NAME,
        trg.ADRESS = src.ADRESS
WHEN NOT MATCHED THEN
    INSERT VALUES (src.N, src.NAME, src.ADRESS);
SELECT * FROM TEST;
-- test insert
MERGE INTO TEST trg
USING (SELECT 34 AS N, 'NameInserted' AS NAME, 
  'AdressInserted' AS ADRESS FROM Dual )  src                
ON ( src.N = trg.N )
WHEN MATCHED THEN
    UPDATE 
    SET trg.NAME = src.NAME,
        trg.ADRESS = src.ADRESS
WHEN NOT MATCHED THEN
    INSERT VALUES (src.N, src.NAME, src.ADRESS);
SELECT * FROM TEST;
DROP TABLE TEST;

см. здесь

...