webentwicklung-frage-antwort-db.com.de

SQLite: Liste der Werte an "WHERE col IN (: PRM)" binden

ich möchte nur eine Anfrage senden

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

Also habe ich die folgende Aussage vorbereitet

SELECT * FROM table WHERE col IN (:LST);

Dann benutze ich 

sqlite_bind_text(stmt, 1, "110, 130, 90", -1, SQLITE_STATIC);

Leider wird dies

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

und ist unbrauchbar (beachten Sie die zwei zusätzlichen einfachen Anführungszeichen). Ich habe bereits versucht, extra 'in die Zeichenfolge zu legen, aber sie werden entkommen. Ich habe keine Option gefunden, um das Escaping zu deaktivieren oder zu verhindern, dass der Text in einfache Anführungszeichen gesetzt wird. Das letzte, was mir einfällt, ist die Verwendung einer vorbereiteten Aussage, aber ich würde es nur als letzte Option nehmen. Haben Sie Ideen oder Vorschläge?

Vielen Dank

Bearbeiten:

Die Anzahl der Parameter ist dynamisch, es können also drei Zahlen sein, wie im obigen Beispiel eine oder zwölf.

28
Sebastian

Sie können eine parametrisierte SQL-Anweisung des Formulars dynamisch erstellen

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

und rufen Sie dann sqlite_bind_int einmal für jedes "?" Sie haben die Aussage hinzugefügt.

Es gibt keine Möglichkeit, einen Textparameter direkt an mehrere Integer-Parameter (oder auch an mehrere Textparameter) zu binden.

Hier ist der Pseudocode für das, was ich mir vorstelle:

-- 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.
26
Larry Lustig

Ich habe mich gerade mit dieser Frage konfrontiert, aber darauf geantwortet, indem ich eine temporäre Tabelle erstellt und alle Werte in diese eingefügt habe, sodass ich dies tun konnte:

SELECT * FROM TABLE WHERE col IN (SELECT col FROM temporarytable);
9
hatfinch

Bauen Sie Ihre Abfrage noch einfacher so auf:

"SELECT * FROM TABLE WHERE col IN ("+",".join(["?"]*len(lst))+")"
6
xtin

Sie können ein Array nicht als einen Parameter übergeben, aber Sie können jeden Array-Wert als separaten Parameter übergeben (IN (?, ?, ?)).

Der sichere Weg, dies für dynamische Zahlenparameter zu tun (Sie sollten keine Zeichenfolgenverkettung, .format() usw. verwenden, um die Werte selbst in die Abfrage einzufügen, da dies zu SQL-Injections führen kann), besteht darin, die Abfragezeichenfolge zu generieren mit der benötigten Anzahl von ? Platzhalter und binden Sie dann die Array-Elemente. Verwenden Sie Array-Verkettung oder Spread-Syntax (* oder ... in den meisten Sprachen), wenn Sie auch andere Parameter übergeben müssen.

Hier ist ein Beispiel für Python 3:

c.execute('SELECT * FROM TABLE WHERE col IN ({}) LIMIT ?'
       .format(', '.join(['?'] * len(values))), [*values, limit])
0
AlexP11223

Sie können es versuchen

RSQLite in R:
lst <- c("a", "b", "c")

dbGetQuery(db_con, paste0("SELECT * FROM table WHERE col IN (", paste0(shQuote(lst), collapse=", ") , ");"))
0
Ksenia

Die Arbeit an einer gleichen Funktionalität führte mich zu diesem Ansatz: (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();
            });
        });
    };
0
Reza Afzalan

das funktioniert auch gut (Javascript ES6) :

let myList = [1, 2, 3];
`SELECT * FROM table WHERE col IN (${myList.join()});`
0
Moritz

Eine viel einfachere und sicherere Antwort besteht einfach darin, die Maske zu generieren (im Gegensatz zum Datenteil der Abfrage) und dem SQL-Injection-Formatierungsmodul zu erlauben, seine Arbeit zu erledigen.

Angenommen, wir haben einige ids in einem Array und einige 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
jasonseminara

Zum Beispiel, wenn Sie die SQL-Abfrage wünschen:

select * from table where col in (110, 130, 90)

Wie wäre es mit:

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 )
0
pgalilea