This question already has answers here:
sqlite3.OperationalError: no such column - but I'm not asking for a column?
(2 answers)
Closed 2 years ago.
Forgive me if this is a basic question, I'm learning on my own and having some trouble. I have built a database with SQLite and am trying to write something that can display the 'description' of an entry when the name is entered into an entry box.
record_id = call_field.get()
# Query the database
c.execute("SELECT name, abbr, description FROM TQ_QUICKTEXT WHERE name =" + record_id)
records = c.fetchall()
# Loop through results
for record in records:
display.insert(1.0, record[2])
When I type the name of the entry that has been put into the database, an error is returned saying there is no column with that name. However, when I type the actual word 'name' into the entry box and run the function every single description entry is returned. If someone wouldn't mind pointing out where I've made mistakes it would be greatly appreciated. Thank you in advance.
The SELECT statement that is executed currently looks like this:
SELECT name, abbr, description FROM TQ_QUICKTEXT WHERE name = something (where something is the value of record_id)
Because there are no quotes around the value of record_id, it thinks it is a column name, not text. This is why when you try the name of a record, you get an error because that is not a column name, but name works, because it is the name of a column.
Adding quotes will fix the problem, but the database is vulnerable to SQL injection.
It is good security practise to parameterise SQL queries to prevent this. This is done by using ? in place of parameters and then passing a tuple of parameters to the execute function. This protects you from SQL injection.
After these changes, the c.execute statment should look like this:
c.execute("SELECT name, abbr, description FROM TQ_QUICKTEXT WHERE name = ?", (record_id,))
Related
This question already has answers here:
SQLite INSERT - ON DUPLICATE KEY UPDATE (UPSERT)
(5 answers)
Closed 6 months ago.
Im having a problem with my sqlite database in my python program. I'm trying to create a table that will hold records of players score. Player name is saved as variable "val" and that variable is used in sql code. Also if the player is already in my table I don't want to create duplicate.
My problem is that if I don't use WHERE {v}... it all works, but the moment i try to prevent table from creating duplicates it gives me an OperationalError: near "WHERE": syntax error.
Im quite new to sql so it's hard for me to find what i'm doing wrong. I used (?) and format and as long as i don't use WHERE it's fine. How can I make sure that my variable (player name) from outside of sql code is not in my table so i can insert it?
val = "PlayerName"
cur.execute( """
INSERT INTO Table (player_name)
VALUES {v}
WHERE {v} NOT IN (
SELECT player_name FROM Table)""".format(v = val))
Ok, it works now. My main problem was that i tried to use commands from MySQL instead of sqlite. My code that worked:
cur.execute( """INSERT INTO Table (player_name)
VALUES (?)
ON CONFLICT(player_name) DO UPDATE SET player_name= player_name""",(val) )
Edit: Final version without player_name = player_name workaround:
cur.execute( """INSERT OR IGNORE INTO Table (player_name) VALUES (?)""",(val) )
Am new in coding
I have a table named 'Capitals' in database 'World'.
This table has 3 columns, namely 'Questions','Answers' and 'Points'.
(Questions column has name of country and answers column has capital of that country)
Intially all column has point=0
I want to fetch this data one by one to python and its GUI(Tkinter) and if the student/user tell capital of the country
i want to add 1 mark to 'Points'. Am able to fetch Questions and answers to python by following code:
No problem in establishing connection with database from python.
No problem in fetching question and answers.
```
X=0
sql2 = "SELECT Questions FROM Capitals"
mycursor.execute(sql2)
myresult1 = mycursor.fetchall()
print(myresult1[x])
mydb.commit()
```
i have a tkinter GUI that has a button which named 'SHOW',WHen i click it answer is fetched from following code.
```
sql3 = "SELECT Answers FROM Capitals"
mycursor.execute(sql3)
myresult1 = mycursor.fetchall()
print(myresult1[x])
mydb.commit()
```
I have a GUI button called 'NEXT', whose command is like 'x=x+1' so that i get next question from database, Till this code works smoothly, but if i want to update 1 mark for correct answers following code doesnt work as 'WHERE' clause of SQL query have to be pointed to particular row in database which is not possible as 'WHERE' clause is not reading a function in Python in my case here is'myresult1[x].
Code i used is
```
Sql4="SELECT * FROM Capitals WHERE Questions=myresult1[x]"
```
MY question is how to loop through 'WHERE' clause of SQL ..
Kindly help
Change Sql4 to use a placeholder for the value:
Sql4="SELECT * FROM Capitals WHERE Questions=%s"
then execute it like this:
mycursor.execute(Sql4, (myresult1[x],))
passing the myresult1[x] in a tuple to execute().
This question already has answers here:
Variable table name in sqlite
(9 answers)
Closed 6 years ago.
I have a program where the user can select what table they want to modify in SQLite. I store the selection in a variable called table, then try and select everything from that table
c.execute('SELECT * FROM ?', (table,))
The program gets stuck at the question mark. It says:
"Sqlite3.OperationalError: near "?": syntax error"
What am I doing wrong?
You can't use parameter substitution for the table name. You need to add the table name to the query string yourself. Something like this:
query = 'SELECT * FROM {}'.format(table)
c.execute(query)
One thing to be mindful of is the source of the value for the table name. If that comes from an untrusted source, e.g. a user, then you need to validate the table name to avoid potential SQL injection attacks. One way might be to construct a parameterised query that looks up the table name from the DB catalogue:
import sqlite3
def exists_table(db, name):
query = "SELECT 1 FROM sqlite_master WHERE type='table' and name = ?"
return db.execute(query, (name,)).fetchone() is not None
my question is, as the title says, how I can create a variable column in SQL lite used in Pyhton.
Here's my code, to show you what exactly I mean:
#Table with variables
def dynamic_data_entry(list_name, num, column):
element_name = list_name[num]
cur.execute("INSERT INTO myliltable (column) VALUES (?)", element_name)
con.commit()
I want to insert the column name, when I call the function, so I can use the function for more than one column, but I keep getting an error, that the column 'column' doesn't exist.
Is there another way to do this, so I can change set the column name when I call the function, or just change the SQL part.
If there is a thread about this already, I would appreciate it, if you could link it, so I can read it myself (I couldn't find anything similar to this topic yet, which worked).
Thanks in advance, I appreciate your help
You need to use the string's format() method to insert the column name into the SQL string:
cur.execute("INSERT INTO myliltable ({}) VALUES (?)".format(column),
element_name)
You can find more information in the Python docs.
Not sure if I phrased the title correctly, but basically my question is is it possible to have sqlite update a row which is defined by a variable? For example:
db.execute('''UPDATE CUSTOMER SET ? = ? WHERE CUSTOMER_ID = ?''', (title, info.get(), k))
where 'title' (the first question mark) is the name of the 'row' I want to update within the table Customer. I have tried the above code but it doesn't work. Does anybody know if it is possible to do this with sqlite3 in any way?
SQL parameters are designed to never be interpretable as SQL objects (like column names); that is one of their major usecases. If they didn't they wouldn't prevent SQL injection attacks. Instead, the title value is either properly escaped as a value, or rejected altogether as the syntax doesn't allow a value in that location.
As such, you need to make sure that your title variable is a proper SQL object name (never take user input directly here) and use string formatting for just that value:
db.execute(
'''UPDATE CUSTOMER SET {} = ? WHERE CUSTOMER_ID = ?'''.format(title),
(info.get(), k))
You probably want to match title against a pre-defined set of possible column names first.
Can you try like this
query = "UPDATE CUSTOMER SET %s = '%s' WHERE CUSTOMER_ID = %d" %(title, info.get(), k)
db.execute(query)
May be you need to commit it.