英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论