无法在准备好的 INSERT 语句中的 python mysql.connector 中使用 None (NULL) 值

Posted

技术标签:

【中文标题】无法在准备好的 INSERT 语句中的 python mysql.connector 中使用 None (NULL) 值【英文标题】:Unable to use None (NULL) values in python mysql.connector in prepared INSERT statement 【发布时间】:2014-08-04 05:28:34 【问题描述】:

当尝试使用准备好的游标并插入 NULL 值时,mysql.connector 报告错误:

mysql.Error: 1210 (HY000): Incorrect arguments to mysqld_stmt_execute

这是一个准确显示这一点的代码。

from __future__ import print_function
import mysql.connector

def execsql(cursor, sqlstmt):
    try:
        cursor.execute(sqlstmt)
    except mysql.connector.Error as e:
        print("mysql.Error: %s" % e)
    print(cursor._executed, '\n')


def execsqlwithparams(cursor, sqlstmt, params):
    try:
        cursor.execute(sqlstmt, params)
    except mysql.connector.Error as e:
        print("mysql.Error: %s" % e)
    print(cursor._executed, "params:", params, '\n')


def main():
    print("mysql.connector.__version__", mysql.connector.__version__)
    db = mysql.connector.connect(db="test")
    print("mysql.db. get server version", db.get_server_version())
    c1 = db.cursor()
    c2 = db.cursor(prepared=False)
    c3 = db.cursor(prepared=True)

    execsql(c1, "drop table if exists test1")
    execsql(c1, "create table test1 (col1 int not null, col2 int null, primary key(col1))")

    print("insert with pure SQL")
    execsql(c1, "insert into test1(col1,col2) values (1, 1)")
    execsql(c1, "insert into test1(col1,col2) values (2, NULL)")

    print("insert with prepared statement format %s")
    sql = "insert into test1(col1,col2) values (%s, %s)"
    execsql(c2, sql)
    execsqlwithparams(c2, sql, (20, 20))
    execsqlwithparams(c2, sql, (21, None))

    print("insert with prepared statement format %s using prepared cursor")
    sql = "insert into test1(col1,col2) values (%s, %s)"
    execsql(c3, sql)
    execsqlwithparams(c3, sql, (30, 30))
    execsqlwithparams(c3, sql, (31, None))

    execsql(c1, "select * from test1")
    row = c1.fetchone()
    while row:
        print(row)
        row = c1.fetchone()
    db.close()


if __name__ == '__main__':
    status = main()

输出是这样的:

mysql.connector.__version__ 1.2.2
mysql.db. get server version (5, 5, 37)
drop table if exists test1 

create table test1 (col1 int not null, col2 int null, primary key(col1)) 

insert with pure SQL
insert into test1(col1,col2) values (1, 1) 
insert into test1(col1,col2) values (2, NULL) 

insert with prepared statement format %s
mysql.Error: 1064 (42000): 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 '%s, %s)' at line 1
insert into test1(col1,col2) values (%s, %s) 
insert into test1(col1,col2) values (20, 20) params: (20, 20) 
insert into test1(col1,col2) values (21, NULL) params: (21, None) 

insert with prepared statement format %s using prepared cursor
insert into test1(col1,col2) values (%s, %s) 
insert into test1(col1,col2) values (%s, %s) params: (30, 30) 

mysql.Error: 1210 (HY000): Incorrect arguments to mysqld_stmt_execute
insert into test1(col1,col2) values (%s, %s) params: (31, None)

select * from test1 

(1, 1)
(2, None)
(20, 20)
(21, None)
(30, 30)

意想不到的结果是这样的:

mysql.Error: 1210 (HY000): Incorrect arguments to mysqld_stmt_execute
insert into test1(col1,col2) values (%s, %s) params: (31, None)

并且数据库中缺少行 (31, None)。

【问题讨论】:

【参考方案1】:

您与在最后一种情况下传递的 None 相关的问题可能是由于 None 没有被解释为表中定义的类型。

【讨论】:

文档指出 None 将被转换为 NULL。 mysql.connector 的代码检查确认它是以这种方式处理的。但这似乎在接下来的过程中被错误地处理了。

以上是关于无法在准备好的 INSERT 语句中的 python mysql.connector 中使用 None (NULL) 值的主要内容,如果未能解决你的问题,请参考以下文章

SELECT LAST_INSERT_ID() 使用准备好的语句后返回 0

使用 ruby​​ pg gem 准备好的 INSERT 语句示例

Ruby `prepare':错误:准备好的语句“should_insert”已经存在(PG::DuplicatePstatement)

如何将多个 INSERT INTO 与准备好的语句结合起来?

准备好的语句适用于 INSERT 但不适用于 SELECT

PHP 准备 MySQL UPDATE 语句,其中包含字符串中的变量