Browse Source

修复达梦8和pgsql中merge into的bug

master
lijianbin 2 days ago
parent
commit
322600d5ee
3 changed files with 108 additions and 55 deletions
  1. +51
    -27
      chain.go
  2. +6
    -1
      go.mod
  3. +51
    -27
      transaction_chain.go

+ 51
- 27
chain.go View File

@ -15,27 +15,28 @@ var stmt *sql.Stmt
var err error
type Query struct {
dbname string
table string
alias string
title string
where []string
where_or []string
join [][]string //[["tablea as a","a.id=b.id","left"]]
save_data []map[string]interface{} //批量操作的数据[["title":"a","num":1,],["title":"a","num":1,]]
upd_field []string // 批量更新时需要更新的字段,为空时按除id外的字段进行更新
data []string
value []interface{}
orderby string
groupby string
having string
page int
page_size int
stmt *sql.Stmt
conn *sql.DB
debug bool
dbtype string
with [][]string //[[临时表的sql语句,临时表的名称]]
dbname string
table string
alias string
title string
where []string
where_or []string
join [][]string //[["tablea as a","a.id=b.id","left"]]
save_data []map[string]interface{} //批量操作的数据[["title":"a","num":1,],["title":"a","num":1,]]
upd_field []string // 批量更新时需要更新的字段,为空时按除id外的字段进行更新
merge_into_where_field string //达梦8和pgsql中,替换ON DUPLICATE KEY UPDATE时的唯一键名/主键名
data []string
value []interface{}
orderby string
groupby string
having string
page int
page_size int
stmt *sql.Stmt
conn *sql.DB
debug bool
dbtype string
with [][]string //[[临时表的sql语句,临时表的名称]]
}
func NewQuery(t ...string) *Query {
@ -161,6 +162,12 @@ func (this *Query) Join(join []string) *Query {
return this
}
// 在达梦和pgsql中,使用merge into去替换mysql--insert into...ON DUPLICATE KEY UPDATE时,需指定唯一键,字段存在id时无需设置
func (this *Query) MergeIntoWhereField(value string) *Query {
this.merge_into_where_field = value
return this
}
/**
* 左连接
* 2023/08/10
@ -690,12 +697,17 @@ func (this *Query) UpdateAllStmt() error {
if DB_PROVIDER == "PgsqlDb" {
setText = " values "
val_field := addPrefixInField(this.data, "s.")
//和mysql更新或添加机制不一样,需指定on条件
on_field := `t.id = s.id`
if this.merge_into_where_field != "" {
on_field = `t.` + this.merge_into_where_field + ` = s.` + this.merge_into_where_field
}
sql = `merge into ` + dbName + ` as t
using (
` + setText + strings.Join(valSql, ",") + `
) s (` + strings.Join(this.data, " , ") + `)
on (t.id = s.id)
on (` + on_field + `)
when matched then
update set
` + strings.Join(updSql_dm, " , ") + `
@ -707,13 +719,25 @@ func (this *Query) UpdateAllStmt() error {
val_field := addPrefixInField(this.data, "s.")
title_field := addPrefixInField(this.data, "? AS ")
sql = `MERGE INTO ` + dbName + ` AS t
USING (
SELECT
select_sql := `SELECT
` + strings.Join(title_field, " , ") + `
FROM DUAL
FROM DUAL`
if len(valSql) > 1 {
for i := 0; i < len(valSql)-1; i++ {
select_sql += ` UNION ALL ` + select_sql
}
}
//和mysql更新或添加机制不一样,需指定on条件
on_field := `t.id = s.id`
if this.merge_into_where_field != "" {
on_field = `t.` + this.merge_into_where_field + ` = s.` + this.merge_into_where_field
}
sql = `MERGE INTO ` + dbName + ` AS t
USING (` + select_sql + `
) s
ON (t.id = s.id)
ON (` + on_field + `)
WHEN MATCHED THEN
UPDATE SET
` + strings.Join(updSql_dm, " , ") + `


+ 6
- 1
go.mod View File

@ -5,7 +5,7 @@ go 1.23.0
toolchain go1.24.0
require (
git.tetele.net/tgo/helper v0.1.0
git.tetele.net/tgo/helper v0.8.0
gitee.com/opengauss/openGauss-connector-go-pq v1.0.7
github.com/denisenkom/go-mssqldb v0.11.0
github.com/go-sql-driver/mysql v1.8.1
@ -14,8 +14,13 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
git.tetele.net/tgo/crypter v0.2.2 // indirect
github.com/ZZMarquis/gm v1.3.2 // indirect
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/text v0.28.0 // indirect


+ 51
- 27
transaction_chain.go View File

@ -15,27 +15,28 @@ import (
)
type TxQuery struct {
dbname string
table string
alias string
title string
where []string
where_or []string
join [][]string //[["tablea as a","a.id=b.id","left"]]
data []string
value []interface{}
save_data []map[string]interface{} //批量操作的数据[["title":"a","num":1,],["title":"a","num":1,]]
upd_field []string // 批量更新时需要更新的字段,为空时按除id外的字段进行更新
orderby string
groupby string
having string
page int
page_size int
stmt *sql.Stmt
conn *sql.DB
tx *sql.Tx
debug bool
with [][]string //[[临时表的sql语句,临时表的名称]]
dbname string
table string
alias string
title string
where []string
where_or []string
join [][]string //[["tablea as a","a.id=b.id","left"]]
data []string
value []interface{}
save_data []map[string]interface{} //批量操作的数据[["title":"a","num":1,],["title":"a","num":1,]]
upd_field []string // 批量更新时需要更新的字段,为空时按除id外的字段进行更新
merge_into_where_field string //达梦8和pgsql中,替换ON DUPLICATE KEY UPDATE时的唯一键名/主键名
orderby string
groupby string
having string
page int
page_size int
stmt *sql.Stmt
conn *sql.DB
tx *sql.Tx
debug bool
with [][]string //[[临时表的sql语句,临时表的名称]]
}
func NewTxQuery(t ...string) *TxQuery {
@ -158,6 +159,12 @@ func (this *TxQuery) Join(join []string) *TxQuery {
return this
}
// 在达梦和pgsql中,使用merge into去替换mysql--insert into...ON DUPLICATE KEY UPDATE时,需指定唯一键,字段存在id时无需设置
func (this *TxQuery) MergeIntoWhereField(value string) *TxQuery {
this.merge_into_where_field = value
return this
}
/**
* 左连接
* 2023/08/10
@ -646,12 +653,17 @@ func (this *TxQuery) UpdateAllStmt() error {
if DB_PROVIDER == "PgsqlDb" {
setText = " values "
val_field := addPrefixInField(this.data, "s.")
//和mysql更新或添加机制不一样,需指定on条件
on_field := `t.id = s.id`
if this.merge_into_where_field != "" {
on_field = `t.` + this.merge_into_where_field + ` = s.` + this.merge_into_where_field
}
sql = `merge into ` + dbName + ` as t
using (
` + setText + strings.Join(valSql, ",") + `
) s (` + strings.Join(this.data, " , ") + `)
on (t.id = s.id)
on (` + on_field + `)
when matched then
update set
` + strings.Join(updSql_dm, " , ") + `
@ -663,13 +675,25 @@ func (this *TxQuery) UpdateAllStmt() error {
val_field := addPrefixInField(this.data, "s.")
title_field := addPrefixInField(this.data, "? AS ")
sql = `MERGE INTO ` + dbName + ` AS t
USING (
SELECT
select_sql := `SELECT
` + strings.Join(title_field, " , ") + `
FROM DUAL
FROM DUAL`
if len(valSql) > 1 {
for i := 0; i < len(valSql)-1; i++ {
select_sql += ` UNION ALL ` + select_sql
}
}
//和mysql更新或添加机制不一样,需指定on条件
on_field := `t.id = s.id`
if this.merge_into_where_field != "" {
on_field = `t.` + this.merge_into_where_field + ` = s.` + this.merge_into_where_field
}
sql = `MERGE INTO ` + dbName + ` AS t
USING (` + select_sql + `
) s
ON (t.id = s.id)
ON (` + on_field + `)
WHEN MATCHED THEN
UPDATE SET
` + strings.Join(updSql_dm, " , ") + `


Loading…
Cancel
Save