2017-03-03 2 views
0

(kein Duplikat Ich weiß, dass es eine Möglichkeit gibt, dies zu tun, das funktioniert:.. Parameter substitution for a SQLite "IN" clause)Warum funktioniert das nicht? WO IN

Ich würde gerne wissen, was ich in diesen Code bin fehle. Ich baue einen einfachen Tisch. Dann kopiere ich erfolgreich einige seiner Datensätze in eine neue Tabelle, wo die Datensätze durch eine WHERE-Klausel qualifiziert sind, die zwei Listen umfasst. Nachdem ich diese Tabelle geworfen habe, versuche ich, dieselben Datensätze zu kopieren, aber dieses Mal lege ich die Liste in eine Variable, die ich in die SQL-Anweisung einfüge. Diesmal werden keine Datensätze kopiert.

Wie kommt es?

import sqlite3 

conn = sqlite3.connect(':memory:') 
curs = conn.cursor() 

oldTableRecords = [ [ 15, 3 ], [ 2, 1], [ 44, 2], [ 6, 9 ] ] 

curs.execute('create table oldTable (ColA integer, ColB integer)') 
curs.executemany('insert into oldTable (ColA, ColB) values (?,?)', oldTableRecords) 

print ('This goes ...') 
curs.execute('''create table newTable as 
    select * from oldTable 
    where ColA in (15,3,44,9) or ColB in (15,3,44,9)''') 

for row in curs.execute('select * from newTable'): 
    print (row) 

curs.execute('''drop table newTable''') 

print ('This does not ...') 
TextTemp = ','.join("15 3 44 9".split()) 
print (TextTemp) 
curs.execute('''create table newTable as 
    select * from oldTable 
    where ColA in (?) or ColB in (?)''', (TextTemp,TextTemp)) 

for row in curs.execute('select * from newTable'): 
    print (row) 

Ausgang:

This goes ... 
(15, 3) 
(44, 2) 
(6, 9) 
This does not ... 
15,3,44,9 

TIA!

+0

Warum 'TextTemp = '' join ("15 3 44 9" .split())' statt von nur ''15, 3,44,9''? –

+0

Weil ich geistesabwesend bin. –

+0

Das ist ein ziemlich guter Grund :-) –

Antwort

3

Der ganze Punkt eines SQL-Parameters ist verhindern SQL-Syntax in Werte ausgeführt werden. Dazu gehören Kommata zwischen Werten; Wenn dies nicht der Fall wäre, könnten Sie niemals Werte mit Kommas in Abfrageparametern verwenden und ist wahrscheinlich ein Sicherheitsproblem beim Booten.

Sie können nicht einfach eine ? verwenden, um mehrere Werte in eine Abfrage einzufügen;

create table newTable as 
select * from oldTable 
where ColA in ('15,3,44,9') or ColB in ('15,3,44,9') 

Keiner der Werte in ColAColB oder eine einzige Reihe mit dem Zeichenfolgenwert 15,3,44,9 hat: der gesamte TextTemp Wert wird als ein Wert, Erzeugen der folgenden äquivalenten gesehen.

Sie benötigen separate Platzhalter für jeden des Wertes in den Parametern zu verwenden:.

col_values = [int(v) for v in "15 3 44 9".split()] 

placeholders = ', '.join(['?'] * len(col_values)) 
sql = '''create table newTable as 
    select * from oldTable 
    where ColA in ({0}) or ColB in ({0})'''.format(placeholders) 

curs.execute(sql, col_values * 2) 
+0

Ich wollte gerade OP fragen, was passiert, wenn Sie es formatieren :) –

+0

Ich wusste nur, dass dies schmerzhaft wäre. –