Inserir um nome de tabela em uma consulta fornece sqlite3.OperationalError: near “?”: Erro de syntax

Eu quero escolher dinamicamente qual tabela para usar em uma consulta SQL, mas eu continuo recebendo erro no entanto eu estou tentando formatar isso. Também tentei %s vez de ? .

Alguma sugestão?

 group_food = (group, food) group_food_new = (group, food, 1) with con: cur = con.cursor() tmp = cur.execute("SELECT COUNT(Name) FROM (?) WHERE Name=?", group_food) if tmp == 0: cur.execute("INSERT INTO ? VALUES(?, ?)", group_food_new) else: times_before = cur.execute("SELECT Times FROM ? WHERE Name=?", group_food) group_food_update = (group, (times_before +1), food) cur.execute("UPDATE ? SET Times=? WHERE Name=?", group_food_update) 

Você não pode usar parâmetros SQL para serem marcadores de posição em objects SQL; Uma das razões para usar um parâmetro SQL é escaping o valor de modo que o database nunca possa confundir o conteúdo de um object de database.

Você terá que interpolar os objects de database separadamente; Escape seus identificadores dobrando os " parâmetros de aspas duplas e use

 cur.execute('SELECT COUNT(Name) FROM "{}" WHERE Name=?'.format(group.replace('"', '""')), (food,)) 

e

 cur.execute('INSERT INTO "{}" VALUES(?, ?)'.format(group.replace('"', '""')), (food, 1)) 

e

 cur.execute('UPDATE "{}" SET Times=? WHERE Name=?'.format(group.replace('"', '""')), (times_before + 1, food)) 

As aspas duplas ".." existem para definir corretamente um identificador, mesmo se esse identificador também for uma palavra-chave válida; qualquer " caractere existente no nome deve ser duplicado; isso também ajuda a desativar as tentativas de injeção de SQL.

No entanto, se os nomes dos seus objects forem originados pelo usuário, você terá que fazer sua própria (rigorosa) validação nos nomes dos objects para evitar ataques de injeção de SQL aqui. Sempre os valide contra objects existentes nesse caso.

Você deve realmente considerar o uso de um projeto como o SQLAlchemy para gerar seu SQL; Ele pode cuidar da validação de nomes de objects e protegê-lo rigorosamente dos riscos de injeção de SQL. Ele pode carregar suas definições de tabela antecipadamente, para saber quais nomes são legais:

 from sqlalchemy import create_engine, func, select, MetaData engine = create_engine('sqlite:////path/to/database') meta = MetaData() meta.reflect(bind=engine) conn = engine.connect() group_table = meta.tables[group] # can only find existing tables count_statement = select([func.count(group_table.c.Name)], group_table.c.Name == food) count, = conn.execute(count_statement).fetchone() if count: # etc.