SQLite: bind list of values to “WHERE col IN ( :PRM )”

后端 未结 9 651
轮回少年
轮回少年 2020-12-16 09:53

all I want to do is send a query like

SELECT * FROM table WHERE col IN (110, 130, 90);

So I prepared the following statement



        
相关标签:
9条回答
  • 2020-12-16 10:17

    Even simpler, build your query like this:

    "SELECT * FROM TABLE WHERE col IN ("+",".join(["?"]*len(lst))+")"
    
    0 讨论(0)
  • 2020-12-16 10:17

    this works fine aswell (Javascript ES6):

    let myList = [1, 2, 3];
    `SELECT * FROM table WHERE col IN (${myList.join()});`
    
    0 讨论(0)
  • 2020-12-16 10:17

    You can try this

    RSQLite in R:
    lst <- c("a", "b", "c")
    
    dbGetQuery(db_con, paste0("SELECT * FROM table WHERE col IN (", paste0(shQuote(lst), collapse=", ") , ");"))
    
    0 讨论(0)
  • 2020-12-16 10:18

    A much simpler and safer answer simply involves generating the mask (as opposed to the data part of the query) and allowing the SQL-injection formatter engine to do its job.

    Suppose we have some ids in an array, and some cb callback:

    /* 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);
    
    0 讨论(0)
  • 2020-12-16 10:28

    You cannot pass an array as one parameter, but you can pass each array value as a separate parameter (IN (?, ?, ?)).

    The safe way to do this for dynamic number parameters (you should not use string concatenation, .format(), etc. to insert the values themselves into the query, it can lead to SQL injections) is to generate the query string with the needed number of ? placeholders and then bind the array elements. Use array concatenation or spread syntax (* or ... in most languages) if you need to pass other parameters too.

    Here is an example for Python 3:

    c.execute('SELECT * FROM TABLE WHERE col IN ({}) LIMIT ?'
           .format(', '.join(['?'] * len(values))), [*values, limit])
    
    0 讨论(0)
  • 2020-12-16 10:29

    You can dynamically build a parameterized SQL statement of the form

     SELECT * FROM TABLE WHERE col IN (?, ?, ?)
    

    and then call sqlite_bind_int once for each "?" you added to the statement.

    There is no way to directly bind a text parameter to multiple integer (or, for that matter, multiple text) parameters.

    Here's pseudo code for what I have in mind:

    -- 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.
    
    0 讨论(0)
提交回复
热议问题