diff --git a/chain.go b/chain.go index c656f63..5e95f52 100644 --- a/chain.go +++ b/chain.go @@ -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, " , ") + ` diff --git a/go.mod b/go.mod index 4fd9950..adc3178 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/transaction_chain.go b/transaction_chain.go index 1924ef8..169f6ce 100644 --- a/transaction_chain.go +++ b/transaction_chain.go @@ -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, " , ") + `