精华内容
下载资源
问答
  • 聊聊gorm的OnConflict

    2021-01-17 20:59:57
    本文主要研究一下gorm的OnConflict OnConflict gorm.io/gorm@v1.20.11/clause/on_conflict.go type OnConflict struct { Columns []Column Where Where OnConstraint string DoNothing bool DoUpdates Set ...

    本文主要研究一下gorm的OnConflict

    OnConflict

    gorm.io/gorm@v1.20.11/clause/on_conflict.go

    type OnConflict struct {
    	Columns      []Column
    	Where        Where
    	OnConstraint string
    	DoNothing    bool
    	DoUpdates    Set
    	UpdateAll    bool
    }
    
    func (OnConflict) Name() string {
    	return "ON CONFLICT"
    }
    
    // Build build onConflict clause
    func (onConflict OnConflict) Build(builder Builder) {
    	if len(onConflict.Columns) > 0 {
    		builder.WriteByte('(')
    		for idx, column := range onConflict.Columns {
    			if idx > 0 {
    				builder.WriteByte(',')
    			}
    			builder.WriteQuoted(column)
    		}
    		builder.WriteString(`) `)
    	}
    
    	if len(onConflict.Where.Exprs) > 0 {
    		builder.WriteString("WHERE ")
    		onConflict.Where.Build(builder)
    		builder.WriteByte(' ')
    	}
    
    	if onConflict.OnConstraint != "" {
    		builder.WriteString("ON CONSTRAINT ")
    		builder.WriteString(onConflict.OnConstraint)
    		builder.WriteByte(' ')
    	}
    
    	if onConflict.DoNothing {
    		builder.WriteString("DO NOTHING")
    	} else {
    		builder.WriteString("DO UPDATE SET ")
    		onConflict.DoUpdates.Build(builder)
    	}
    }
    
    // MergeClause merge onConflict clauses
    func (onConflict OnConflict) MergeClause(clause *Clause) {
    	clause.Expression = onConflict
    }
    

    OnConflict定义了Columns、Where、OnConstraint、DoNothing、DoUpdates、UpdateAll属性;Build方法会根据这些属性拼装sql,如果是DoNothing则追加DO NOTHING,否则追加DO UPDATE SET

    Expression

    gorm.io/gorm@v1.20.11/clause/set.go

    type Set []Assignment
    
    type Assignment struct {
    	Column Column
    	Value  interface{}
    }
    
    func (set Set) Name() string {
    	return "SET"
    }
    
    func (set Set) Build(builder Builder) {
    	if len(set) > 0 {
    		for idx, assignment := range set {
    			if idx > 0 {
    				builder.WriteByte(',')
    			}
    			builder.WriteQuoted(assignment.Column)
    			builder.WriteByte('=')
    			builder.AddVar(builder, assignment.Value)
    		}
    	} else {
    		builder.WriteQuoted(PrimaryColumn)
    		builder.WriteByte('=')
    		builder.WriteQuoted(PrimaryColumn)
    	}
    }
    
    // MergeClause merge assignments clauses
    func (set Set) MergeClause(clause *Clause) {
    	copiedAssignments := make([]Assignment, len(set))
    	copy(copiedAssignments, set)
    	clause.Expression = Set(copiedAssignments)
    }
    
    func Assignments(values map[string]interface{}) Set {
    	keys := make([]string, 0, len(values))
    	for key := range values {
    		keys = append(keys, key)
    	}
    	sort.Strings(keys)
    
    	assignments := make([]Assignment, len(keys))
    	for idx, key := range keys {
    		assignments[idx] = Assignment{Column: Column{Name: key}, Value: values[key]}
    	}
    	return assignments
    }
    
    func AssignmentColumns(values []string) Set {
    	assignments := make([]Assignment, len(values))
    	for idx, value := range values {
    		assignments[idx] = Assignment{Column: Column{Name: value}, Value: Column{Table: "excluded", Name: value}}
    	}
    	return assignments
    }
    

    的DoUpdates属性是Set类型,Set类型实际是Assignment数组;其Build方法会组装assignment的sql

    实例

    func onConflictDemo(db *gorm.DB) {
    	entities := []DemoEntity{
    		{
    			Model: gorm.Model{ID: 1},
    			Name:  "coco",
    		},
    		{
    			Model: gorm.Model{ID: 2},
    			Name:  "bear",
    		},
    	}
    	result := db.Debug().Create(&entities)
    	b, _ := json.Marshal(entities)
    	log.Println("data:", string(b))
    	log.Println("result.RowsAffected:", result.RowsAffected, "result.Error:", result.Error)
    
    	if err := db.Debug().Clauses(clause.OnConflict{DoNothing: true}).Create(&entities).Error; err != nil {
    		panic(err)
    	}
    }
    

    输出

    2021/01/17 20:03:31 /demo.go:53 UNIQUE constraint failed: demo_entities.id
    [0.487ms] [rows:0] INSERT INTO `demo_entities` (`created_at`,`updated_at`,`deleted_at`,`name`,`id`) VALUES ("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"coco",1),("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"bear",2)
    2021/01/17 20:03:31 data: [{"ID":1,"CreatedAt":"2021-01-17T20:03:31.71143+08:00","UpdatedAt":"2021-01-17T20:03:31.71143+08:00","DeletedAt":null,"Name":"coco"},{"ID":2,"CreatedAt":"2021-01-17T20:03:31.71143+08:00","UpdatedAt":"2021-01-17T20:03:31.71143+08:00","DeletedAt":null,"Name":"bear"}]
    2021/01/17 20:03:31 result.RowsAffected: 0 result.Error: UNIQUE constraint failed: demo_entities.id
    
    2021/01/17 20:03:31 /demo.go:58
    [0.123ms] [rows:0] INSERT INTO `demo_entities` (`created_at`,`updated_at`,`deleted_at`,`name`,`id`) VALUES ("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"coco",1),("2021-01-17 20:03:31.711","2021-01-17 20:03:31.711",NULL,"bear",2) ON CONFLICT DO NOTHING
    

    小结

    gorm的OnConflict定义了Columns、Where、OnConstraint、DoNothing、DoUpdates、UpdateAll属性;Build方法会根据这些属性拼装sql,如果是DoNothing则追加DO NOTHING,否则追加DO UPDATE SET

    doc

    展开全文
  • on conflict的用法

    2021-02-01 16:05:04
    on conflict用法 今天给大家分享一下sql中的小知识(我用的是pgsql,mysql也同样有这个on conflict) 比如有一天啊,威风凛凛的客户需要你写一个入库数据的接口提供他们使用,虽然你满不情愿,但是为了生存你勉强...

    on conflict用法

    今天给大家分享一下sql中的小知识(我用的是pgsql,mysql也同样有这个on conflict)


    比如有一天啊,威风凛凛的客户需要你写一个入库数据的接口提供他们使用,虽然你满不情愿,但是为了生存你勉强接受!!!

    但是写到一半的时候(本人用的mybatis),你突然发现那些gogogogogogo的客户竟然推的有重复数据,这这这!!!!天理难容。
    唉~~~~那我们不要着急,这时候就出现了 on conflict,丫的,who pa who

    它的作用呢就是insert的时候遇到冲突的时候做一些操作,今天给大家写几个不同的例子。

    在这里插入图片描述


    第一种:

    on conflict on constraint unique_cbxxb do

    这一种方式: 大家看在 constraint 后有一个unique_cbxxb,那么这个呢就是你在数据库设定的唯一键名 然后写到这,随后在do后面就可以做操作了。比如: 如下图

    在这里插入图片描述

    那我这段代码就是循环添加操作,那当我遇到重复数据就会去更新那条数据.

    第二种:

    on conflict (zwdm,tbxzdm,tkdm,bxgsdm,syjg) do nothing;

    这种呢 在 on conflict括号里面的就是你表中的唯一键,第一种呢直接是唯一键名,这种就是把你的各个唯一键写进来,那后面的do nothing就代表如果遇到重复数据就什么都不干(也不添加)。如下:

    在这里插入图片描述

    第三种:

    在这里插入图片描述

    第三种就不多讲什么了,就是第二种去掉了do nothing

    今天分享到此结束!!!!!!!!!!!!

    展开全文
  • PostgreSQL的ON CONFLICT

    千次阅读 2020-04-26 17:26:16
    PostgreSQL的ON CONFLICTPostgreSQL 的 upsert 简介 PostgreSQL 的 upsert 功能:当记录不存在时,执行插入;否则,进行更新。 PostgreSQL 的 upsert 简介 在关系数据库中,术语 upsert 被称为合并(merge)。意思是...

    PostgreSQL的ON CONFLICT

    PostgreSQL 的 upsert 功能:当记录不存在时,执行插入;否则,进行更新。

    PostgreSQL 的 upsert 简介

    在关系数据库中,术语 upsert 被称为合并(merge)。意思是,当执行 INSERT 操作时,如果数据表中不存在对应的记录,PostgreSQL 执行插入操作;如果数据表中存在对应的记录,则执行更新操作。这就是为什么将其称为 upsert(update or insert)的原因。

    通过 INSERT ON CONFLICT 来使用 upsert 功能:

    INSERT INTO table_name(column_list) VALUES(value_list)
    ON CONFLICT target action;
    

    target 可以是:

    • (column_name):一个字段名
    • ON CONSTRAINT constraint_name:其中的 constraint_name 可以是一个唯一约束的名字
    • WHERE predicate:带谓语的 WHERE 子句

    action 可以是:

    • DO NOTHING:当记录存在时,什么都不做
    • DO UPDATE SET column_1 = value_1, … WHERE condition:当记录存在时,更新表中的一些字段

    注意,ON CONFLICT 只在 PostgreSQL 9.5 以上可用。

    PostgreSQL 的 upsert 示例
    我们新建一个 customers 表来进行演示:

    CREATE TABLE customers (
     customer_id serial PRIMARY KEY,
     name VARCHAR UNIQUE,
     email VARCHAR NOT NULL,
     active bool NOT NULL DEFAULT TRUE
    );
    

    customers 表有4个字段:customer_id、name、email 和 active。其中,name 字段有唯一约束,用于确保客户的唯一性。

    upsert

    下面,往 customers 表里插入几行:

    INSERT INTO customers (NAME, email)
    VALUES
     ('IBM', 'contact@ibm.com'),
     (
     'Microsoft',
     'contact@microsoft.com'
     ),
     (
     'Intel',
     'contact@intel.com'
     );
    
    #SELECT * FROM customers;
    customer_id |   name    |         email         | active
    -------------+-----------+-----------------------+--------
              1 | IBM       | contact@ibm.com       | t
              2 | Microsoft | contact@microsoft.com | t
              3 | Intel     | contact@intel.com     | t
    (3 rows)
    

    假设 Microsoft 更换了联系方式 email:由 contact@microsoft.com 变成了 hotline@microsoft.com,我们可以使用 UPDATE 语句进行修改。然而,为了演示 upsert 功能,我们使用 INSERT ON CONFLICT 语句:

    INSERT INTO customers (NAME, email)
    VALUES
     (
     'Microsoft',
     'hotline@microsoft.com'
     ) 
    ON CONFLICT ON CONSTRAINT customers_name_key 
    DO NOTHING;
    

    这个语句指明了,当数据存在时,什么都不做(DO NOTING)。下面的语句有一样的效果,区别在于使用的是 name 字段,而不是约束的名字:

    INSERT INTO customers (name, email)
    VALUES
     (
     'Microsoft',
     'hotline@microsoft.com'
     ) 
    ON CONFLICT (name) 
    DO NOTHING;
    

    我们的目标是修改客户的 email,所以应该用这条语句:

    INSERT INTO customers (name, email)
    VALUES
     (
     'Microsoft',
     'hotline@microsoft.com'
     ) 
    ON CONFLICT (name) 
    DO
     UPDATE
       SET email = EXCLUDED.email;
    upsert
    
    展开全文
  • on conflict 用法真的很方便,不存在就插入,存在可以更新 可以do nothing,就是用起来要注意几点: 字段必须完全同名。试了半天不行,改了同名就行。 拿不到原表的内容。退而求其次用原表做一个内连接就行,取原值...

    mark一下
    on conflict 用法真的很方便,不存在就插入,存在可以更新 可以do nothing,就是用起来要注意几点:

    1. 字段必须完全同名。试了半天不行,改了同名就行。
    2. 拿不到原表的内容。退而求其次用原表做一个内连接就行,取原值然后想怎么玩都行。下面这个例子就是取原值并加上新统计值更新回原表。
    3. 建临时表可以加入很多自己需要的内容,操作空间更大
    4. excluded代表新选择出来的内容。
    	insert into plate_no_info  
    	select plate_no,total_orders ,first_parking_time,last_parking_time
    	from (
    	select t1.plate_no,(plate_no_info.total_orders + cnt ) as total_orders,plate_no_info.first_parking_time,t1.last_parking_time
    	from (
    	select plate_no,count(id) cnt,min(parking_time) first_parking_time,max(parking_time) last_parking_time
    	from order_list 
    	WHERE created_at > CURRENT_DATE - 1
    	and plate_no ~'^[\u2e80-\ua4cf]|[\uf900-\ufaff]|[\ufe30-\ufe4f]'
    	GROUP BY plate_no
    	) t1,
    	plate_no_info
    	WHERE 1=1
    	AND t1.plate_no = plate_no_info.plate_no
    	)
    	as t_temp
    	on conflict(plate_no) 
    -- 	do NOTHING
    	do update 
    	set 
    	total_orders = excluded.total_orders,
    	first_parking_time = excluded.first_parking_time,
    	last_parking_time = excluded.last_parking_time;
    
    展开全文
  • INSERT INTO users ( name, niki_name, password ) VALUES ( '川川川川普', '123123aweq', '123qseasd' ),('张三','昵称','他的密码')ON CONFLICT ( NAME ) DO UPDATE --这个exclude可以将它理解为这些values存在...
  • PostgreSQL , upsert , insert on conflict do 背景 PostgreSQL 9.5 引入了一项新功能,UPSERT(insert on conflict do),当插入遇到约束错误时,直接返回,或者改为执行UPDATE。 语法如下 Command: INSERT ...
  • ON CONFLICT ON CONSTRAINT pr_key_cd DO UPDATE SET NAME = '更新' WHERE GOODS.STORE_CD = '104' AND GOODS.GOOD_CD = '4' pr_key_cd为必须为唯一主键,也可以用下面写法(注意:必须保证筛选出数据唯一...
  • ON CONFLICT 只在 PostgreSQL 9.5 以上可用 PostgreSQL 的 upsert 功能就是当执行INSERT操作时,如果数据表中不存在对应的记录,PostgreSQL 执行插入操作;如果数据表中存在对应的记录,则执行更新操作。这就是为...
  • insert on conflict合并更新即存在则更新,不存在则写入。在oracle中可以通过merge语法来实现同样的功能,不过这种语法有个缺陷就是:某些情况下存在并不一定要更新,因为可能更新的数据是一样的,这就完全没必要了...
  • 本篇博客参考博主:DemonHunter211的博客: PostgreSQL upsert功能(insert on conflict do)的用法,如有侵权请联系删除! PostgreSQL 9.5 中引入了一项新功能,UPSERT(insert on conflict do),当插入遇到约束错误...
  • 直接绑定主键名称,主键重复则更新 insert into 表名称 (字段a, 字段b, ...) values (value_a, value_b, ...) on conflict on constraint this_table_key do update set ...略 使用以上的SQL语句后...
  • PostgreSQL INSERT ON CONFLICT不存在则插入,存在则更新 1、不存在则插入,存在则更新 insert into test values (1,'test',now()) on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time...
  • PostgreSQL , 合并写 , insert on conflict , 不必要更新 背景 合并更新的应用非常广泛,存在则更新,不存在则写入。 但是在某些场景中,存在并不一定要更新,原因是新的内容可能和老的内容完全一致。这种更新操作是...
  • on conflict(a1) do update set (b1,c1) = (1,2) conflict里的字段必须为主键或者唯一索引,可以多个字段作为唯一索引,在数据库设置不然会报 "there is no unique or exclusion constraint matching the ON ...
  • 在项目中使用 ON CONFLICT DO UPDATE SET 语法进行批量数据合并插入&更新,如果一条SQL语句中出现多条相同KEY的数据(冲突键,或冲突约束),会报错。 在SQL标准中,MERGE 也有同样的问题,因为一次请求中对行...
  • 摘要: 标签 PostgreSQL , Greenplum , merge insert , insert on conflict , 合并插入 , 有则更新 , 无则插入 背景 PostgreSQL insert on conflict语法非常强大,支持合并写入(当违反某唯一约束时,冲突则更新,...
  • In the Wireless Sensor Network, a new MAC protocol: one-persistent CSMA protocol .with monitoring functions and multichannel mechanism for Wireless Sensor Network .based on conflict resolution ...
  • 原因是sql语句中用到了conflict但表结构里面没有相关的限制 举例: 表结构如下: CREATE TABLE "public"."test" ( "a" varchar(255) COLLATE "pg_catalog"."default", "b" varchar(255) COLLATE "pg_catalog"....
  • 解决这两个问题的方法就是在alertId上添加ON CONFLICT REPLACE [java]   view plain   copy   private   static   final  String TABLE_CREATE_ALERTS =  "CREATE ...
  • org.postgresql.util.PSQLException: 错误: 没有匹配ON CONFLICT说明的唯一或者排除约束 pgSQL使用upsert进行插入或更新操作时,报错: 没有匹配ON CONFLICT说明的唯一或者排除约束。 由于进行操作的表包含4个主键,...
  • postgres=# insert into uk_test values (1,'digoal',now()) on conflict on constraint uk_test_pkey do update set info=excluded.info,crt_time=excluded.crt_time; INSERT 0 1 postgres=# select ctid,* from uk...
  • 背景使用insert into on conflict update语法,可以支持UPSERT的功能,但是到底这条SQL是插入的还是更新的呢?如何判断 通过xmax字段的值是否不为0,可以判断,如果是UPDATE,XMAX里面会填充更新事务号。 注意直接用...
  • 【故障处理】 PostgreSQL : ERROR: syntax error at or near ...pg数据库无法支持 ON conflict语法 故障发生现象及报错信息 报错sql with tmp_t0 as ( select 'a'::varchar as c0 union all select 'b'::varcha
  • SQLite on conflict子句

    千次阅读 2015-01-25 16:22:04
    conflict-clause ::= ON CONFLICT conflict-algorithm  conflict-algorithm ::= ROLLBACK | ABORT | FAIL | IGNORE | REPLACE  ON CONFLICT子句不是独立的SQ
  • 解决这两个问题的方法就是在alertId上添加ON CONFLICT REPLACE 1 2 3 4 5 6 7 8 private static final String TABLE_CREATE_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 27,950
精华内容 11,180
关键字:

onconflict