I am relatively new to SQL and sqlite3 in general, and have a question about using question mark or named style in executions.
I have several databases with a table called structures, and I have made a method in a class in Python that extracts the n'th value of some column using
def get_nth(self, col_name, n):
cursor = self.con.cursor()
if n == -1:
cursor.execute(f"SELECT {col_name} FROM structures ORDER BY id DESC LIMIT 1")
else:
cursor.execute(f"SELECT {col_name} FROM structures WHERE id == {n}")
try:
val = cursor.fetchall()[0][0]
except IndexError as e:
print("Faulty database - no 'structures' table found")
raise e
return val
Having googled about other sqlite3-related problems, I found that executing with f-strings or str.format will be vulnerable to injection attacks, and therefore I tried altering the execution, according to Cursor Objects, to:
if n == -1:
cursor.execute("SELECT ? FROM structures ORDER BY id DESC LIMIT 1", (col_name, ))
else:
cursor.execute("SELECT ? FROM structures WHERE id == ?", (col_name, n))
print(cursor.fetchall()[0][0])
This outputs the column name itself instead of the actual value, since .execute uses 'id' and not id if col_name='id'.
Question:
Is there a way to use question mark or named style in this way?
cursor.execute("SELECT {col_name} FROM structures WHERE id == ?", (col_name, n)). The bit to protect against injection is the value, not nessecarily the column name. Protect the value, and the column name is no longer an issue.