Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql UPSERT功能的存储过程_Sql_Database_Stored Procedures_Plsql - Fatal编程技术网

Sql UPSERT功能的存储过程

Sql UPSERT功能的存储过程,sql,database,stored-procedures,plsql,Sql,Database,Stored Procedures,Plsql,下面是我的表,ID列是主键。另外两列是字符串 我正在使用一个名为XpressMP的新数据库 Column Name ------- ID PrimaryKey SEARCHES String ACCOUNT String 我试图在这里实现UPSERT的功能- If ID doesn't exists here then insert a new record. And ID ex

下面是我的表,
ID列是主键。另外两列是字符串

我正在使用一个名为
XpressMP
的新数据库

Column Name                
-------
ID             PrimaryKey                 
SEARCHES       String
ACCOUNT        String
我试图在这里实现
UPSERT
的功能-

If ID doesn't exists here then insert a new record.
And ID exists then update the record.
我知道如果我正在与Oracle合作,那么我可以使用
MERGE
sql命令,但该数据库不支持
MERGE
,目前还没有其他用于该命令的命令。但是我相信我可以用
存储过程做同样的事情

有人能提供一些建议吗?我如何对存储过程做同样的事情?因为存储过程将在那里工作

更新:-

public final static String INSERT = "BEGIN"
+" INSERT INTO TABLE (ID, SEARCHES, ACCOUNT) VALUES (?, ?, ?)"
+" EXCEPTION"
+" WHEN DUP_VAL_ON_INDEX THEN"
+" UPDATE TABLE"
+" SET SEARCHES = ?, ACCOUNT = ?"
+" WHERE ID = ?"
+" END";
每当我尝试像这样执行上述存储过程时

preparedStatement = dbConnection.prepareStatement(INSERT);

preparedStatement.setString(1, String.valueOf(userId));
preparedStatement.setString(2, Constants.getaAccount(userId));
preparedStatement.setString(3, Constants.getaAdvertising(userId));
preparedStatement.executeUpdate();

我有例外吗?这是正确的执行方式吗?

我想你必须用传统的方式来执行

如果行不存在 插入 其他的
更新

您可以使用
DUP\u VAL\u ON\u索引
异常来处理它。
您可以在您的过程中添加以下代码,这些代码应该满足您的要求

CREATE OR REPLACE PROCEDURE TABLE_UPSERT (v_id IN NUMBER,
                                          v_searches IN VARCHAR2(20),
                                          v_account IN VARCHAR2(20)) AS
BEGIN
  INSERT INTO table (id, searches, account) VALUES (v_id, v_searches, v_account) ;
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    UPDATE TABLE
    SET searches = v_searches, account = v_account
    WHERE id = v_id;
END;
/
您可以阅读有关DUP\u VAL\u ON\u索引异常和异常的更多信息


另一种选择是在检查计数后插入或更新数据

DECLARE
  l_count number;
BEGIN
  SELECT count(*) 
  INTO l_count
  FROM table 
  WHERE id = (value);

  IF l_count = 0 THEN
    INSERT into table VALUES ....;
  ELSE
    UPDATE table SET searches = .., account = ..;
  END IF;
END;

我同意这里的@tabish。你必须用传统的方法来做。 我认为您建议的方法会造成更大的危害—您对源表中的每一行执行一次插入(插入到目标表或ERR表),然后执行额外的更新。 在最坏的情况下,当您必须更新所有行时,您将执行两倍的dml操作。 在我的书中,这不是一个好主意。
祝你好运。

是的,我已经知道了:)。但这是什么传统方式?存储过程对吗?这是你的设计决定。我会推荐存储过程。是的,我也是这么想的。你能给我提供一些关于存储过程的例子吗?谢谢Orangecrush的帮助。将查看索引上的
DUP\u VAL\u
。因为我将使用java来调用这个存储过程。所以我把你的SP改造成了这样<代码>开始插入表(ID、搜索、帐户)值(?、、?);索引上的DUP_VAL_然后更新表集搜索=?,帐户=?,时出现异常?其中ID=?;结束。它应该正常工作?当我填充。。。具有标记。@FarhanJamal Yes,如果您在调用此过程时在java中正确处理变量,它应该可以工作。试试看。如果您想尝试,我们还提供了一个更易于理解的代码。但是我建议在索引上使用
DUP\u VAL\u
@FarhanJamal我想您可以使用
SP(?,?)
从java调用这个SP。您不能在PL/SQL过程中使用变量值
。我更新了问题的更多细节。我想,我做错了,这就是我得到例外的原因。如果我做错了什么,请告诉我?啊。。现在有意义了,这意味着,我需要首先执行这个存储过程,以便在数据库中创建它,然后我需要从Java程序调用它。对吗?那么如何在数据库中创建这个存储过程呢?