考虑一个由以下定义的表
CREATE TABLE Example (id INTEGER)
和一个用于向 Example
添加元组的 INSERT
语句,在 SQL 注释中包含单引号:
my_cmd = """-- Comment's device
INSERT INTO Example (id) VALUES (?)
"""
我通过 pyodbc 模块连接到 MySQL。令人惊讶的效果似乎是 INSERT 命令始终失败.IFF。评论中有奇数个撇号。该消息提到 HY000 和:
'The SQL contains 0 parameter markers, but 1 parameters were supplied'
更新:该行为现已由 MySQL 支持人员验证,因此实际上它有可能被归类为错误。请参阅 Gord 的回答,其中列出了另一个样本,以及指向 MySQL bug 数据库的评论。
下面列出了完整的测试脚本。我想知道这句话是否只是一个陷阱?但这很奇怪:
如果语句文本是通过 ODBC 传递的,那么假设注释从 --
开始并延伸到行尾是否错误? (我确实在 --
之后放了一个空格,并且为了可移植性而使用 SQL 注释。不同的注释字符或 MySLQ block 注释不会改变效果。)
对于下面列出的成功和失败案例,ODBC session 的跟踪显示 SQLNumParams
分别为 1 和 0。然而,这些陈述本身看起来就是给定的。我很想假设换行符('\n')是无效的。但这在某种程度上与下面的工作示例相矛盾,这些示例有两个引号 (my_cmd_with_two_qutoes
),或者没有引号(即 my_cmd
用“*”替换“'”)。
或者是驱动程序问题?
import pyodbc
my_cmd = """-- Comment's device
INSERT INTO Example (id) VALUES (?)
"""
my_cmd_with_two_quotes = """-- Comment's device's
INSERT INTO Example (id) VALUES (?)
"""
conn = pyodbc.connect("DSN=Abcdef;PWD=...")
thing_named_cursor = conn.cursor()
# success, replacing the single apostrophe:
thing_named_cursor.execute(my_cmd.replace("'", "*"), (123, ))
# success, too:
thing_named_cursor.execute(my_cmd_with_two_quotes, (456, ))
# failure:
try:
thing_named_cursor.execute(my_cmd, (789, ))
except pyodbc.Error, e:
print("Error: %s" % e)
conn.commit()
conn.close()
最佳答案
Or is it a driver issue?
是的。我使用以下针对 MySQL 数据库的测试代码重新创建了您的问题
import pyodbc
cnxn = pyodbc.connect("DSN=usbMySQL")
crsr = cnxn.cursor()
sql = """
-- Comment's device
INSERT INTO Example (id) VALUES (?)
"""
crsr.execute(sql, [11])
cnxn.commit()
cnxn.close()
但是当 DSN 指向 Microsoft SQL Server 数据库(使用 SQL Server Native Client 11.0)时,它可以正常工作。
当对 MySQL 数据库使用 pypyodbc 时,代码也会失败,因此这不仅仅是 pyodbc 的问题。
此外,以下 VBScript 代码...
Option Explicit
Const adParamInput = 1
Const adInteger = 3
Dim con, cmd
Set con = CreateObject("ADODB.Connection")
con.Open "DSN=usbMySQL"
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandText = _
"-- Gord's test" & vbCrLf & _
"INSERT INTO Example (id) VALUES (?)"
cmd.Parameters.Append cmd.CreateParameter("?", adInteger, adParamInput, , 121)
cmd.Execute
con.Close
...失败并...
[MySQL][ODBC 5.2(w) Driver][mysqld-5.6.13-log]You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?)' at line 2
...但是将 CommandText 中的 Gord's
更改为 Gord''s
...
cmd.CommandText = _
"-- Gord''s test" & vbCrLf & _
"INSERT INTO Example (id) VALUES (?)"
...允许它毫无怨言地运行。
其他信息:
郑重声明,MySQL Connector/Python 问题中的原始注释字符串没有问题。这工作正常:
import mysql.connector
cnxn = mysql.connector.connect(port=3307, user='root', password='whatever', database='mydb')
crsr = cnxn.cursor()
sql = """
-- Comment's device
INSERT INTO Example (id) VALUES (%s)
"""
crsr.execute(sql, [101])
cnxn.commit()
cnxn.close()
关于python - 使用 ODBC 时可以在 SQL 注释中添加任意文本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30174882/