python - 使用 ODBC 时可以在 SQL 注释中添加任意文本吗?

标签 python mysql sql odbc pyodbc

考虑一个由以下定义的表

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/

相关文章:

python - 如何避免 for 循环并正确迭代 pandas 数据框?

php - php 页面中的查询不起作用

php - 白色日期和两个变量的问题

mysql - (My)SQL 迭代地使用一个表中的数据填充另一个表/从列表中选择

python - 在 BeautifulSoup、python 中仅从表 (td) 中提取特定的行和列

python - 如何让cmd正确显示阿拉伯文字?

mysql - Kohana 3.2 选择问题

mysql - 如何使用查询写入 VB.net 中的 Mysql 数据库

mysql - 从 2 个连接表中选择最新数据

python - 如何检查是否使用 conda 或 pip 安装了 Python、pandas 和 Jupyter?我应该用 conda 重新安装它吗?