我想做的就是发送一个像
这样的查询SELECT * FROM table WHERE col IN (110, 130, 90);
所以我准备了以下声明
SELECT * FROM table WHERE col IN (:LST);
然后我用
sqlite_bind_text(stmt, 1, "110, 130, 90", -1, SQLITE_STATIC);
不幸的是,这变成了
SELECT * FROM table WHERE col IN ('110, 130, 90');
并且没用(请注意另外两个单引号)。我已经尝试在字符串中添加额外的'但它们会被转义。我没有找到关闭转义或防止文本被单引号括起来的选项。我能想到的最后一件事是没有使用准备好的声明,但我只把它作为最后一个选项。你有什么想法或建议吗?
由于
编辑:
参数的数量是动态的,因此它可能是三个数字,如上例所示,一个或十二个。
答案 0 :(得分:26)
您可以动态构建表单
的参数化SQL语句 SELECT * FROM TABLE WHERE col IN (?, ?, ?)
然后为每个“?”调用一次sqlite_bind_int你加入了声明。
无法将文本参数直接绑定到多个整数(或者,就此而言,多个文本)参数。
这是我想到的伪代码:
-- Args is an array of parameter values
for i = Lo(Args) to Hi(Args)
paramlist = paramlist + ', ?'
sql = 'SELECT * FROM TABLE WHERE col IN (' + Right(paramlist, 3) + ')'
for i = Lo(Args) to Hi(Args)
sql_bind_int(sql, i, Args[i]
-- execute query here.
答案 1 :(得分:9)
我自己刚刚面对这个问题,但是通过创建一个临时表并将所有值插入其中来回答它,以便我可以这样做:
SELECT * FROM TABLE WHERE col IN (SELECT col FROM temporarytable);
答案 2 :(得分:6)
更简单,建立您的查询:
"SELECT * FROM TABLE WHERE col IN ("+",".join(["?"]*len(lst))+")"
答案 3 :(得分:2)
根据您的 sqlite 构建(它不是默认构建的一部分),您可以使用:
SELECT * FROM table WHERE col IN carray(?42);
然后使用(假设是 C API)绑定 ?42
:
int32_t data[] = {110, 130, 90};
sqlite3_carray_bind(
stmtPtr, 42,
data, sizeof(data)/sizeof(data[0]),
CARRAY_INT32, SQLITE_TRANSIENT);
我还没有实际测试过,我只是阅读了文档:https://sqlite.org/carray.html
答案 4 :(得分:1)
您不能将数组作为一个参数传递,但可以将每个数组值作为单独的参数(IN (?, ?, ?)
)传递。
对动态数字参数执行此操作的安全方法(不应该使用字符串串联,.format()
等将值本身插入查询中,这可能导致SQL注入)是生成查询具有所需数量的?
占位符的字符串,然后绑定数组元素。如果还需要传递其他参数,请使用数组串联或扩展语法(在大多数语言中为*
或...
)。
以下是Python 3的示例:
c.execute('SELECT * FROM TABLE WHERE col IN ({}) LIMIT ?'
.format(', '.join(['?'] * len(values))), [*values, limit])
答案 5 :(得分:0)
使用相同的功能引导我采用这种方法: (nodejs,es6,Promise)
var deleteRecords = function (tblName, data) {
return new Promise((resolve, reject) => {
var jdata = JSON.stringify(data);
this.run(`DELETE FROM ${tblName} WHERE id IN (?)`, jdata.substr(1, jdata.length - 2), function (err) {
err ? reject('deleteRecords failed with : ' + err) : resolve();
});
});
};
答案 6 :(得分:0)
例如,如果你想要sql查询:
select * from table where col in (110, 130, 90)
怎么样:
my_list = [110, 130, 90]
my_list_str = repr(my_list).replace('[','(').replace(']',')')
cur.execute("select * from table where col in %s" % my_list_str )
答案 7 :(得分:0)
这很好用(Javascript ES6):
let myList = [1, 2, 3];
`SELECT * FROM table WHERE col IN (${myList.join()});`
答案 8 :(得分:0)
一个更简单,更安全的答案只涉及生成掩码(与查询的数据部分相对)并允许SQL注入格式化程序引擎完成其工作。
假设我们在数组中有一些id
,并且有一些cb
回调:
/* we need to generate a '?' for each item in our mask */
const mask = Array(ids.length).fill('?').join();
db.get(`
SELECT *
FROM films f
WHERE f.id
IN (${mask})
`, ids, cb);
答案 9 :(得分:0)
您可以尝试
RSQLite in R:
lst <- c("a", "b", "c")
dbGetQuery(db_con, paste0("SELECT * FROM table WHERE col IN (", paste0(shQuote(lst), collapse=", ") , ");"))
答案 10 :(得分:0)
我的节点解决方案(ES6,Promises):
let records = await db.all(`
SELECT * FROM table
WHERE (column1 = ?) and column2 IN ( ${[...val2s].fill('?').join(',')} )
`, [val1, ...val2s])
适用于可变数量的可能值。
这使用了 sqlite-async,但您可以为回调样式版本简单地修改它。