【问题标题】:H2 SQL database - INSERT if the record does not existH2 SQL 数据库 - 如果记录不存在则插入
【发布时间】:2013-11-15 02:11:08
【问题描述】:

我想初始化一个 H2 数据库,但我不确定记录是否存在。如果它们存在我不想做任何事情,但如果它们不存在我想写默认值。

类似这样的:

IF 'number of rows in ACCESSLEVELS' = 0
INSERT INTO ACCESSLEVELS VALUES
    (0, 'admin'),
    (1, 'SEO'),
    (2, 'sales director'),
    (3, 'manager'),
    (4, 'REP')
    ;

【问题讨论】:

    标签: sql h2


    【解决方案1】:
    MERGE INTO ACCESSLEVELS 
      KEY(ID) 
    VALUES (0, 'admin'),
      (1, 'SEO'),
      (2, 'sales director'),
      (3, 'manager'),
      (4, 'REP');
    

    更新现有行,并插入不存在的行。如果未指定键列,则使用主键列查找行。

    如果您不命名列,则必须按照表中的定义提供它们的值。如果您希望将列命名为更独立于它们在表定义中的顺序,或者避免在没有必要或可能的情况下为所有列提供值:

    MERGE INTO ACCESSLEVELS 
      (ID, LEVELNAME)
      KEY(ID) 
    VALUES (0, 'admin'),
      (1, 'SEO'),
      (2, 'sales director'),
      (3, 'manager'),
      (4, 'REP');
    

    请注意,您必须在列列表和 KEY 子句中包含键列(本例中为“ID”)。

    【讨论】:

    • 我知道这个功能,但如果记录存在,我不想更新。
    • 尝试编写用户函数,使用“select count(ID) into x from ...”,然后比较结果...
    【解决方案2】:

    以下适用于 MySQL、PostgreSQL 和 H2 数据库:

    drop table ACCESSLEVELS;
    
    create table ACCESSLEVELS(id int, name varchar(255));
    
    insert into ACCESSLEVELS select * from (
    select 0, 'admin' union
    select 1, 'SEO' union
    select 2, 'sales director' union
    select 3, 'manager' union
    select 4, 'REP'
    ) x where not exists(select * from ACCESSLEVELS);
    

    【讨论】:

    • 你能解释一下这个语法吗?很难破译它
    • 这是一个“insert into ... select”语句,通常用于将查询中的多行插入到表中。现在,我使用了带有硬编码值的“联合”查询,而不是简单的“从 tableName 中选择 *”。然后“where not exists”确保只有在表“accesslevels”为空时才插入这些行。
    【解决方案3】:

    为此,您可以在 H2 数据库中使用 MySQL Compatibility Mode。从1.4.197 版本开始,它支持以下语法: INSERT IGNORE INTO table_name VALUES ...

    来自this 拉取请求:

    常规模式不支持INSERT IGNORE,您必须通过将;MODE=MySQL 附加到数据库URL 或执行SET MODE MySQL 语句来显式启用MySQL 兼容模式。

    来自官方site

    INSERT IGNORE 部分支持,如果未指定 ON DUPLICATE KEY UPDATE,可用于跳过具有重复键的行。

    【讨论】:

      【解决方案4】:

      这是另一种方式:

      CREATE TABLE target (C1 VARCHAR(255), C2 VARCHAR(255));
      
      MERGE INTO target AS T USING (SELECT 'foo' C1, 'bar') AS S ON T.C1=S.C1
      WHEN NOT MATCHED THEN
          INSERT VALUES('foo', 'bar')
      

      当 S 中的一行与 T 中的一行或多行匹配时,什么也不做。但是当 S 中的一行不匹配时,插入它。有关详细信息,请参阅“合并使用”:

      https://www.h2database.com/html/commands.html#merge_using

      【讨论】:

        猜你喜欢
        • 2014-04-04
        • 2011-07-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-23
        • 2021-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多