0

I would like to allow users to query a sql database. The database is here

So the user will be able to enter the queries they want:

csr_city= input("Enter a city >>").lower().strip().replace(' ','')
csr_type = input("Enter a type >>").lower().strip()

and then the query will execute:

cur = conn.cursor()
cur.execute('SELECT * FROM crime_scene_report WHERE city=?  AND type=? ', (csr_city,csr_type))
rows = cur.fetchall()
rows

If the user enters both variables like city='SQL City' and type='murder' it works as it finds both values in the same row, but if the user leaves one empty, ex type, then it returns a blank table as both conditions do not exist on one single row.

What I would like to do is for SELECT to ignore the variable if it is empty. I guess I could do it with if statements but that would create a mess?? Is there a better way?

I tried How to ignore the condition that user did not pass in SQLITE?, but didnt work for me, still getting empty tables.

5
  • Try passing the city as a parameter twice coupled with: WHERE (city = ? or ? IS NULL)might work. Alternatively you might try WHERE city LIKE ISNULL(?,'')+'%' Commented Feb 3, 2023 at 15:37
  • @JonSG ? will never be NULL, since that corresponds to None in Python, not an empty string. Commented Feb 3, 2023 at 15:38
  • The solution in that question should have worked. Show how you tried to implement it. Commented Feb 3, 2023 at 15:39
  • Well to improve it, you can fetch all unique city and type and keep them in set and for user input check if that match to cities and types present or not if match then run the query to fetch all result. Commented Feb 3, 2023 at 15:47
  • I read somewhere that None is interpreted by SQLite as null but not sure if it is true Commented Feb 3, 2023 at 16:13

1 Answer 1

1

You're effectively looking for an SQL query builder (such as SQLAlchemy's core layer), but to begin with, some ifs are just fine:

csr_city = input("Enter a city >>").lower().strip().replace(" ", "")
csr_type = input("Enter a type >>").lower().strip()

cur = conn.cursor()

sql_where = []
args = []
if csr_city:
    sql_where.append("city = ?")
    args.append(csr_city)
if csr_type:
    sql_where.append("type = ?")
    args.append(csr_type)

if not sql_where:
    sql_where.append("1 = 1")  # always true

sql_query = f'SELECT * FROM crime_scene_report WHERE {" AND ".join(sql_where)}'
cur.execute(sql_query, args)
rows = cur.fetchall()
Sign up to request clarification or add additional context in comments.

5 Comments

Works perfectly and it wasnt as complicated as I thought it would be with if statements. Fabulous. One question, do you mean that if i use SQL Alchemy to query SQLite I can then avoid the if statements?
Another question, what is this doing? if not sql_where: sql_where.append("1 = 1") # always true
It makes sure there's always some where clause if the user didn't enter anything else. If you use SQLAlchemy, it basically generates the SQL for you.
Thanks! Last question: I have been told that the code is vulnerable to sql injections. Is there a way to protect it or sqlalchemy is the only way?
This code is not vulnerable, as it uses parameterized queries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.