Stored procedures 如何在merge语句中使用过程参数

Stored procedures 如何在merge语句中使用过程参数,stored-procedures,plsql,parameters,upsert,Stored Procedures,Plsql,Parameters,Upsert,我正在创建一个使用merge语句更新/插入表的过程upsert。现在我遇到了一个问题:使用过程参数我必须执行此upsert 程序xyz a在表.a%类型中,b在表.b%类型中,。。。。 是 局部变量; 开始 合并到目标_表中 使用source_table-我必须在这里使用过程参数,而不是source table 关于表中主键的条件 当匹配时 更新表 当不匹配时 插入表格; 结束xyz; 那么如何在merge语句中使用过程参数而不是源表呢??或 建议我使用查询获取过程参数并将其用作源表值 请帮帮我

我正在创建一个使用merge语句更新/插入表的过程upsert。现在我遇到了一个问题:使用过程参数我必须执行此upsert

程序xyz a在表.a%类型中,b在表.b%类型中,。。。。 是 局部变量; 开始 合并到目标_表中 使用source_table-我必须在这里使用过程参数,而不是source table 关于表中主键的条件 当匹配时 更新表 当不匹配时 插入表格; 结束xyz; 那么如何在merge语句中使用过程参数而不是源表呢??或 建议我使用查询获取过程参数并将其用作源表值

请帮帮我。 提前谢谢。

可能是这样的

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;
此外,您还可以尝试使用所谓的“tempotary table select from DUAL”

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;
请参见

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;
此外,您还可以尝试使用所谓的“tempotary table select from DUAL”

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;

请看

很难从您的问题中分辨出确切的内容,但我想您希望合并到或合并到的表是动态的。在这种情况下,您应该使用的是创建动态SQL的软件包,很难从您的问题中准确地说出您要做什么,但我想您希望合并到或合并到的表是动态的。在这种情况下,您应该使用的是创建动态SQL的包

我知道我参加聚会晚了八年,但我想我正在尝试做一些类似于您所做的事情,但是尝试基于传入存储过程的参数进行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; 

我知道我参加聚会晚了八年,但我想我是在尝试做一些与您所做的类似的事情,但是尝试根据传递到存储过程中的参数进行升级,成功时返回空字符串,失败时返回错误返回到我的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; 

嗨coldice谢谢你的回复。。我正在寻找一个直接使用过程参数的查询,而不是merge stmt中的source_table/view。这个查询应该在merge语句中的Using关键字之后提供valuesi.e参数。嗨,coldice,我尝试使用临时表方法,但是它显示错误,说ora:00969:missing ON keyword。嗨,coldice,谢谢你的回复。。我正在寻找一个直接使用过程参数的查询,而不是merge stmt中的source_table/view。此查询应在merge语句中的Using关键字后提供valuesi.e参数。嗨,coldice,我尝试使用临时表方法,但显示错误,说ora:00969:关键字上缺少。嗨,raskart,签出新版本,这应该可以。嗨,raskart,签出新版本,这应该可以。