使用ODBC时,我可以在SQL注释中放置任意文本吗?

时间:2015-05-11 18:20:26

标签: python mysql sql odbc pyodbc

考虑由

定义的表格
CREATE TABLE Example (id INTEGER)

以及INSERT语句,用于将元组添加到Example,在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支持人员现在已经验证了该行为,因此实际上有可能将其归类为错误。请参阅戈德的答案,其中列出了另一个样本,以及指向MySQL错误数据库的评论。

下面列出了完整的测试脚本。我想知道这个引用的东西是不是 gotcha ?但这很奇怪:

如果语句文本是通过ODBC传递的,那么假设注释从--开始并延伸到行尾是不对的? (我确实在--之后放了一个空格,我使用SQL注释来实现可移植性。不同的注释字符或MySLQ块注释不会改变效果。)

对于下面列出的成功和失败案例,ODBC会话的跟踪显示{1}为1和0。但是,这些陈述本身就是给定的。我很想假设换行(' \ n')无效。但是,这在某种程度上与下面的工作示例相矛盾,这些示例有两个引号(SQLNumParams),或者没有(即my_cmd_with_two_qutoes和" *"替换"' &#34)

或者是驱动程序问题?

my_cmd

2 个答案:

答案 0 :(得分:2)

  

或者是驱动程序问题?

是。我使用针对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()

但它适用于指向Microsoft SQL Server数据库的DSN(使用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)驱动程序] [mysqld-5.6.13-log]您有错误   在你的SQL语法中;检查与MySQL服务器版本相对应的手册,以便在第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()

答案 1 :(得分:0)

您是否尝试过阻止评论? /* mycomment */

我的猜测是这种情况下语言的换行不被MySQL视为新行;或者连接可以处理"空白"降低到最低限度以优化发送查询(有效地剥离换行符)。