英文:
golang mysql why this delete not working properly with IN condition of mysql
问题
我使用golang mysql执行删除语句,删除的目标是使用IN条件,但只删除了一条记录。这是什么原因?
go 1.16
import (
"database/sql"
"errors"
"fmt"
"io"
"log"
"net/http"
"strconv"
"strings"
"time"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
// "github.com/leekchan/timeutil"
_ "github.com/go-sql-driver/mysql" //v1.7.1
)
func SelectQuery(action string, schema string) string {
if action == "del" {
switch schema {
case "schema1":
return "DELETE FROM `schema1` WHERE `id` IN (?)"
default:
panic("bad request")
}
}
}
func DelAction(db *sql.DB, schema string, list []int) int64 {
strList := []string{}
for _, v := range list { // this is id list ex.[1, 2, 3]
strList = append(strList, strconv.Itoa(v))
}
delQeury := SelectQuery("del", schema) // "DELETE FROM `schema1` WHERE `id` IN (?)"
param := strings.Join(strList, ",") // param: 1,2,3
delRes, err := db.Exec(delQeury, param)
delCnt, err := delRes.RowsAffected()
return delCnt // delete only 1 records. even if param have 3 values
}
例如,我想删除所有3条记录,但只删除了1条记录。
添加信息:
创建一个要删除的ID int切片数组。
例如:[1, 2, 3]
res, err := db.Query(query) // select query
list := []int{}
for res.Next() {
u := &Logs{} // 类型logs是id int
if err := res.Scan(&u.id); err != nil {
fmt.Println("scan error")
panic(err.Error())
} else {
list = append(list, u.id)
}
}
英文:
I use golang mysql to execute the delete statement,
the target of the delete is using IN condition, but only one record is deleted. What is causing this?
go 1.16
import (
"database/sql"
"errors"
"fmt"
"io"
"log"
"net/http"
"strconv"
"strings"
"time"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
// "github.com/leekchan/timeutil"
_ "github.com/go-sql-driver/mysql" //v1.7.1
)
func SelectQuery(action string, schema string) string {
if action == "del" {
switch schema {
case "schema1":
return "DELETE FROM `schema1` WHERE `id` IN (?)"
default:
panic("bad request")
}
}
}
func DelAction(db *sql.DB, schema string, list []int) int64 {
strList := []string{}
for _, v := range list { // this is id list ex.[1, 2, 3]
strList = append(strList, strconv.Itoa(v))
}
delQeury := SelectQuery("del", schema) // "DELETE FROM `schema1` WHERE `id` IN (?)"
param := strings.Join(strList, ",") // param: 1,2,3
delRes, err := db.Exec(delQeury, param)
delCnt, err := delRes.RowsAffected()
return delCnt // delete only 1 records. even if param have 3 values
}
example. I want to delete all 3 records but only 1 record is deleted
add info
Create an array of ID int slices to be deleted.
ex. [1, 2, 3]
res, err := db.Query(query) // select query
list := []int{}
for res.Next() {
u := &Logs{} // type logs is id int
if err := res.Scan(&u.id); err != nil {
fmt.Println("scan error")
panic(err.Error())
} else {
list = append(list, u.id)
}
}
答案1
得分: 1
这解决了问题。
我不知道这是否是最好的方法,但它可以这样工作。
args := []interface{}{}
for _, x := range list {
args = append(args, x)
}
stmt := `DELETE FROM schema WHERE id IN (?` + strings.Repeat(", ?", len(list)-1) + `)`
db.Exec(stmt, args...)
英文:
This solved it.
I don't know if this is the best way, but it works this way.
args := []interface{}{}
for _, x := range list {
args = append(args, x)
}
stmt := `DELETE FROM schema WHERE id IN (?` + strings.Repeat(", ?", len(list)-1) + `)`
db.Exec(stmt, args...)
答案2
得分: 0
一个问号表示一个参数,而不是参数列表。传递的参数列表将被转换为其字符串表示形式,然后被截断。
以下是纯SQL的等效写法:
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1),(2),(3);
DELETE FROM t1 WHERE a in ("1,2,3");
Query OK, 1 row affected, 1 warning (0.009 sec)
SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1292 | Truncated incorrect DECIMAL value: '1,2,3' |
+---------+------+--------------------------------------------+
1 row in set (0.001 sec)
SELECT a FROM t1;
+------+
| a |
+------+
| 2 |
| 3 |
+------+
2 rows in set (0.001 sec)
我建议在Go中构建整个SQL语句而不使用参数。在Python中,你可以使用execute_many
方法,我不知道Go是否提供类似的方法。
英文:
A question mark represents exact one parameter not a list of parameters. The passed parameter list will be converted to it's string representation and then truncated.
Here is the equivalent in pure SQL:
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1),(2),(3);
DELETE FROM t1 WHERE a in ("1,2,3");
Query OK, 1 row affected, 1 warning (0,009 sec)
SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------+
| Warning | 1292 | Truncated incorrect DECIMAL value: '1,2,3' |
+---------+------+--------------------------------------------+
1 row in set (0,001 sec)
SELECT a FROM t1;
+------+
| a |
+------+
| 2 |
| 3 |
+------+
2 rows in set (0,001 sec)
I would suggest to build the entire SQL statement in go without parameters. In Python you would use execute_many method(), I don't know if go provides something similiar.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论