13

我正在给Apache Derby,又名JavaDB一个旋转。在插入可能已经存在的记录时,我似乎无法解决重复键问题。是否有相当于 " insert if not exists" 或 " merge" 的德比?

同样,有没有办法做类似“ drop table foo if exists”的事情?

4

7 回答 7

16

我从未使用过 apache derby,但是一个完全独立于数据库的通用解决方案如下:

要将值 'a' 和 'b' 插入到表 foo 中(列名为 A,B),但仅限于值不存在的地方,请尝试类似

INSERT INTO foo (  
  SELECT 'a' as A, 'b' as B
  FROM foo  
  WHERE  
    A = 'a' AND B = 'b'  
  HAVING count(*)=0  
 )

这可能需要针对特定​​的 dbms 进行调整,但想法是插入仅在没有值时才返回值的选择结果。

这是创建幂等 sql 脚本(第二次运行时不执行任何操作)的有用技巧。但是,在生产代码中使用它时要小心,因为HAVING count(*)=0在大表上可能会非常慢。

于 2009-01-10T12:56:26.463 回答
4

支持 SQL:2003 MERGE 语句的请求在 Derby 错误跟踪器中记录为https://issues.apache.org/jira/browse/DERBY-3155

你可以为这个问题投票,或者更好的是,贡献一个实现!

否则,我所知道的唯一解决方案需要先选择行以查看它是否存在,或者插入它并捕获异常,正如其他人所指出的那样。

您可以将此逻辑打包到数据库过程中,以使其更易于执行。

于 2009-10-21T04:12:06.900 回答
3

我使用 PostgreSQL 数据库的标准方法如下:

INSERT INTO foo ( col1, col2, col3, ... )
SELECT 'col1 value', 'col2 value', 'colc value', ...
WHERE NOT EXISTS (
  SELECT 0
  FROM foo
  WHERE col1 = 'col1 value'
  ...
)

不确定它的可移植性或严格符合 ANSI 的程度。外部 SELECT 语句中缺少的 FROM 子句尤其可能是非标准的。试一试吧。

于 2009-04-01T14:13:07.553 回答
2

Derby 在 10.11 中实现了 MERGE:https
://db.apache.org/derby/docs/10.11/ref/rrefsqljmerge.html 请 注意,您需要在使用数据库之前将其升级到 10.11:https ://db.apache.org /derby/docs/10.11/devguide/cdevupgrades.html

于 2014-08-31T07:18:25.720 回答
1

我遇到了同样的问题,我得到了这个在 Derby 上只有一个值/列的插入。(我从来没有用更多的时间来测试它,但我没有理由认为它不应该):

INSERT INTO my_table (my_column)
    (SELECT 'new_value_to_insert'
    FROM my_table
    WHERE my_column = 'new_value_to_insert' 
    HAVING count(*)=0)
于 2010-03-16T22:05:28.610 回答
0

我正在使用此解决方案,但只有在您了解数据库视图中的重复项与用户视图中的重复项之间的区别时,您才必须使用它

  • 数据库视图中的重复项是具有相同主键的两条记录
  • 用户视图中的重复项是所有字段都相同的两条记录

        while (ResultSet.next()) {
        try {
        PreparedStatement insertion = myConn.prepareStatement("insert into table values (?)");
        insertion .setString(1, "test");
        insertion .executeUpdate();           
        } catch (SQLException e) {
            if(e.getSQLState().equals("23505"))//Found duplicate from database view
             {continue;}//ignore duplicate and continue with the insert statement
            else{try {                           
                  throw e;
            } catch (Exception ex) {  
                }
              }
            }
          }
    
于 2009-09-29T08:52:19.390 回答
0

对此没有本机支持,为了解决这个问题,我正在使用 eclipse-link,eclipse-link 将尝试创建表并忽略尝试创建已经存在的表时出现的任何错误。

如果您进行架构更改,您可以告诉 eclipse 链接在创建表之前删除它们。

于 2009-07-27T22:10:03.983 回答