복붙노트

[PYTHON] 쿼리에 테이블 이름을 삽입하면 sqlite3.OperationalError : near "?": 구문 오류가 발생합니다.

PYTHON

쿼리에 테이블 이름을 삽입하면 sqlite3.OperationalError : near "?": 구문 오류가 발생합니다.

동적으로 SQL 쿼리에서 사용할 테이블을 선택하고 싶지만 오류가 계속 발생하지만이 형식을 지정하려고합니다. 또한? 대신 % s을 (를) 사용해 보았습니다.

어떤 제안?

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)

해결법

  1. ==============================

    1.SQL 매개 변수를 사용하여 SQL 객체에서 자리 표시자를 사용할 수 없습니다. SQL 매개 변수를 사용하는 이유 중 하나는 값을 이스케이프하여 데이터베이스가 데이터베이스 객체의 내용을 실수하지 않도록하는 것입니다.

    SQL 매개 변수를 사용하여 SQL 객체에서 자리 표시자를 사용할 수 없습니다. SQL 매개 변수를 사용하는 이유 중 하나는 값을 이스케이프하여 데이터베이스가 데이터베이스 객체의 내용을 실수하지 않도록하는 것입니다.

    데이터베이스 개체를 별도로 보간해야합니다. 이중 따옴표 매개 변수를 두 배로하여 식별자를 이스케이프하고

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

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

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

    ".."이중 따옴표는 해당 식별자가 유효한 키워드 인 경우에도 식별자를 올바르게 표시하기위한 것입니다. 이름에있는 기존의 "문자를 두 배로 늘려야하며, 이는 SQL 주입 시도를 해제하는데도 도움이됩니다.

    그러나 개체 이름이 사용자 출처 인 경우 여기에서 SQL 주입 공격을 방지하기 위해 개체 이름에 대한 자체 (엄격한) 유효성 검사를 수행해야합니다. 이 경우 기존 개체에 대해 항상 유효성 검사를 수행하십시오.

    대신 SQLAlchemy와 같은 프로젝트를 사용하여 SQL을 생성하는 것을 고려해야합니다. 개체 이름을 확인하고 SQL 주입 위험으로부터 사용자를 보호 할 수 있습니다. 테이블 정의를 앞에로드 할 수 있으므로 어떤 이름이 합법인지 알 수 있습니다.

    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.
    
  2. from https://stackoverflow.com/questions/25387537/inserting-a-table-name-into-a-query-gives-sqlite3-operationalerror-near-sy by cc-by-sa and MIT license