简体   繁体   中英

Syntax error in MySQL query: check the syntax near '?'. Where does the '?' come from?

I'm writing a module to use connector in Python in a more clever way (in terms of my needs) and I'm stuck into an error raised by self.__cursor.execute(query, values_escaped) .

Here's the code:

class MySQL:
    # [...]
    def query(self, query: str, values_escaped: tuple = ()) -> MySQLCursorPrepared | MySQLCursorBuffered:
        # [...] <-- Here I don't change any parameter of the ones up, they stay untouched until reaching the bugged row below
        try:
            if values_escaped:
                self.__cursor = self.__conn.cursor(prepared = True)
                self.__cursor.execute(query, values_escaped) # <-- this is the bugged row
                
            else: 
                self.__cursor = self.__conn.cursor(buffered = True)
                self.__cursor.execute(query)
        # [...]
    # [...]


def test() -> None:
    with MySQL(database = "lockfile") as conn:
        res = conn.query("SELECT * FROM %s", ("fileslocked",)) # <-- I can't see any '?' sign! :(
        print(f"Rows: {res.rowcount}")

# Output:
Traceback (most recent call last):
  File "e:\xampp\htdocs\it-exercises\python\mylockfile\database.py", line 61, in query
    self.__cursor.execute(query, values_escaped)
  File "E:\Apps\Python310\lib\site-packages\mysql\connector\cursor_cext.py", line 1031, in execute
    self._stmt = self._cnx.cmd_stmt_prepare(operation)
  File "E:\Apps\Python310\lib\site-packages\mysql\connector\connection_cext.py", line 517, in cmd_stmt_prepare
    raise InterfaceError(str(err)) from err
mysql.connector.errors.InterfaceError: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?' at line 1
Rows: 0

I searched online but I've only found this solution: the prepared parameter in the cursor method. I found it in some unofficial docs of connector while in the official ones I couldn't find anything useful (I may have left something behind, but I've been struggling with this for some days), but it doesn't seem to work.

Moreover, where does the '?' sign come from?

? represents the placeholder in the query, which is represented by %s in Python.
The issue is that you're attempting to dynamically bind a tablename, which isn't possible - placeholders can only be dynamically bound to values, not object names. Remove the placeholder and you should be OK:

res = conn.query("SELECT * FROM fileslocked")

I think the ? comes from the string formatting syntax %s after the string was changed to a sql statement under the hood by the library you are using to create a connection.

I have seen a similar syntax when using string sql statements for sqlite3 - using ? for the variables passed to the sql statement. eg

db.conn.execute('SELECT * FROM table_1 WHERE id=?', id)

First step is checking if your query works fine without variables:

res = conn.query("SELECT * FROM fileslocked")

If it works, you can try to use the %(name) style:

res = conn.query("SELECT * FROM %(database_name)", {"database_name": "fileslocked"})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM