Apache Derby:如何执行“如果不存在则插入”?

发布于 2024-07-11 20:23:59 字数 325 浏览 6 评论 0原文

我正在提供 Apache Derby,又名 JavaDB 一个旋转。 插入可能已经存在的记录时,我似乎无法解决重复的关键问题。 是否有一个 Derby 相当于“如果不存在则插入”或“merge”?

同样,有没有办法执行“drop table foo if isn't”之类的操作?

I'm giving Apache Derby, aka JavaDB a spin. I can't seem to get around duplicate key issues when inserting records that may already exist. Is there a Derby equivalent to "insert if not exists", or "merge" ?

Similarly, is there a way to do something like "drop table foo if exists"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

眼角的笑意。 2024-07-18 20:23:59

我从未使用过 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 可能会非常慢。

I've never used apache derby, but a general solution that is fairly database independent is as follows:

To insert the values 'a' and 'b' into table foo (with columns named A, B), but only where the values are not already there, try something like

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

This may need tweaking for a particular dbms, but the idea is to insert the result of a select that only returns values when there are non.

This is a useful trick for creating an idempotent sql script (one that does nothing the second time it is run). However, be careful when using this in production code as the HAVING count(*)=0 may be very slow on large tables.

菩提树下叶撕阳。 2024-07-18 20:23:59

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

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

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

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

The request to support the SQL:2003 MERGE statement is logged in the Derby bug tracker as https://issues.apache.org/jira/browse/DERBY-3155

You could vote for that issue, or, even better, contribute an implementation!

Otherwise, the only solutions I know of require either selecting the row first to see if it exists, or inserting it and catching the exception, as others have noted.

You can package this logic up in a database procedure to make it somewhat easier to execute.

ι不睡觉的鱼゛ 2024-07-18 20:23:59

我使用 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 子句尤其可能是非标准的。 不过,试一试吧。

A standard way I've used with PostgreSQL DBs is something like the following:

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

Not sure how portable or strictly ANSI compliant it is though. The missing FROM clause in the outer SELECT statement particularly may be non-standard. Give it a go though.

鲜血染红嫁衣 2024-07-18 20:23:59

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

Derby implemented MERGE in 10.11: https://db.apache.org/derby/docs/10.11/ref/rrefsqljmerge.html
Note that you need to upgrade your DB to 10.11 before using it: https://db.apache.org/derby/docs/10.11/devguide/cdevupgrades.html

记忆之渊 2024-07-18 20:23:59

我遇到了同样的问题,并且我在 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)

I had the same problem, and I got this working for an insert with just one value / column on Derby. (I never got around to testing it with more, but I have no reason to assume it should not though):

INSERT INTO my_table (my_column)
    (SELECT 'new_value_to_insert'
    FROM my_table
    WHERE my_column = 'new_value_to_insert' 
    HAVING count(*)=0)
想你的星星会说话 2024-07-18 20:23:59

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

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

There is no native support for this, to get round it I'm using eclipse-link, eclipse-link will try to create the tables and ignore any errors that arise from attempting to create tables that already exists.

If you make schema changes, you can tell eclipse link to drop the tables before creating them.

日裸衫吸 2024-07-18 20:23:59

中的重复项之间的区别时,您才必须使用它。

  • 我正在使用此解决方案,但只有当您了解数据库视图中的重复项用户视图 是具有相同主键的两条记录
  • 从用户视图来看,重复项是所有字段都相同的两条记录

     while (ResultSet.next()) { 
          尝试 { 
          ReadyStatement insert = myConn.prepareStatement("插入表值(?)"); 
          插入.setString(1, "测试"); 
          插入.executeUpdate();            
          } catch (SQLException e) { 
              if(e.getSQLState().equals("23505"))//从数据库视图中发现重复 
               {continue;}//忽略重复并继续插入语句 
              否则{尝试{                            
                    扔 e; 
              } catch (异常前) {   
                  } 
                } 
              } 
            } 
      

I'am using this solution but you must use it only if you understanding the difference between the duplicate from the database view and the duplicate from the user view

  • Duplicates from the database view are two records with the same primary key
  • Duplicates from the user view are two records with all the fiels identical

        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) {  
                }
              }
            }
          }
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文