我在从Python内部执行某些SQL时遇到了问题,尽管类似的SQL在mysql
命令行中也能正常工作。
该表如下所示:
mysql> SELECT * FROM foo;
+-------+-----+
| fooid | bar |
+-------+-----+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
+-------+-----+
4 rows in set (0.00 sec)
我可以从mysql命令行执行以下SQL查询,而不会出现问题:
mysql> SELECT fooid FROM foo WHERE bar IN ('A','C');
SELECT fooid FROM foo WHERE bar IN ('A','C');
+-------+
| fooid |
+-------+
| 1 |
| 3 |
+-------+
2 rows in set (0.00 sec)
但是,当我尝试在Python中执行相同操作时,没有任何行,而我希望有2行:
import MySQLdb
import config
connection=MySQLdb.connect(
host=config.HOST,user=config.USER,passwd=config.PASS,db='test')
cursor=connection.cursor()
sql='SELECT fooid FROM foo WHERE bar IN %s'
args=[['A','C']]
cursor.execute(sql,args)
data=cursor.fetchall()
print(data)
# ()
所以,问题是:应该如何Python代码进行修改,以选择那些fooid
S其中bar
是('A','C')
?
顺便说一句,我注意到,如果我切换的角色bar
和fooid
,我可以得到代码选择那些bar
S其中fooid
是(1,3)
成功的。我不明白为什么一个这样的查询(下面)有效,而另一个(上面)却无效。
sql='SELECT bar FROM foo WHERE fooid IN %s'
args=[[1,3]]
cursor.execute(sql,args)
data=cursor.fetchall()
print(data)
# (('A',), ('C',))
绝对要清楚,这是foo
表的创建方式:
mysql> DROP TABLE IF EXISTS foo;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `foo` (
`fooid` int(11) NOT NULL AUTO_INCREMENT,
`bar` varchar(10) NOT NULL,
PRIMARY KEY (`fooid`));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT into foo (bar) values ('A'),('B'),('C'),('D');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
编辑 :当我启用通用查询日志,mysqld -l /tmp/myquery.log
我看到
mysqld, Version: 5.1.37-1ubuntu5.5-log ((Ubuntu)). started with:
Tcp port: 3306 Unix socket: /var/run/mysqld/mysqld.sock
Time Id Command Argument
110101 11:45:41 1 Connect unutbu@localhost on test
1 Query set autocommit=0
1 Query SELECT fooid FROM foo WHERE bar IN ("'A'", "'C'")
1 Query SELECT bar FROM foo WHERE fooid IN ('1', '3')
1 Quit
实际上,似乎在A
和周围放置了过多的引号C
。
感谢@Amber的评论,我更好地了解出了什么问题。MySQLdb将参数化参数转换['A','C']
为("'A'","'C'")
。
有没有一种方法可以使用IN
SQL语法进行参数化查询?还是必须手动构造SQL字符串?
这是一个类似的解决方案,我认为在SQL中建立%s字符串列表更有效:
list_of_ids
直接使用:format_strings = ','.join(['%s'] * len(list_of_ids)) cursor.execute("DELETE FROM foo.bar WHERE baz IN (%s)" % format_strings, tuple(list_of_ids))
这样,您就不必引用自己的报价,并避免各种SQL注入。
请注意,html" target="_blank">数据(
list_of_ids
)作为参数直接进入mysql的驱动程序(不在查询文本中),因此没有注入。您可以在字符串中保留所需的任何字符,而无需删除或引用字符。
问题内容: 如何使用MySQLdb python驱动程序执行* .sql文件中存储的sql脚本。我在尝试 但这不起作用,因为 cursor.execute 一次只能运行一个sql命令。我的sql脚本改为包含多个sql语句。我也在尝试 但也没有成功。 问题答案: 假设文件中每行有一条SQL语句。否则,您将需要编写一些规则以将行连接在一起。
本文向大家介绍MySQL SELECT WHERE,包括了MySQL SELECT WHERE的使用技巧和注意事项,需要的朋友参考一下 示例 询问 结果 使用WHERE子句中的嵌套SELECT查询 该WHERE子句可以包含任何有效的SELECT语句以编写更复杂的查询。这是一个“嵌套”查询 询问 嵌套查询通常用于从查询中返回单个原子值以进行比较。 选择所有没有电子邮件地址的用户名 免责声明:比较整个
我使用此函数运行SQL查询: 但是我得到了这个错误 2017-08-05 18:54:18,421 INFOsqlalchemy.engine.base.Engine(4L,)2017-08-05 18:54:18,424 INFOsqlalchemy.engine.base.Engine COMMIT127.0.0.1--[05/Aug/2017 18:54:18]"GET/HTTP/1.1"2
问题内容: 使用SELECT WHERE IN()时,是否可以保持顺序?例如,使用以下查询: 结果将使用ID的默认顺序返回。1,7,54,55,56 当我想保留IN中使用的顺序时:56,55,54,1,7 有没有一种快速的方法可以在MySQL中执行此操作,或者我将被迫在代码后对其进行排序? 问题答案: 使用FIND_IN_SET:
问题内容: 在WHERE子句中有使用SELECT语句描述的名称吗?这是好/不好的做法吗? 这会是更好的选择吗? 它远没有那么优雅,但是运行起来比以前的版本要快。我不喜欢它,因为它在GUI中没有非常清晰地显示(并且SQL初学者需要理解它)。我可以将其分为两个独立的查询,但是随后事情变得混乱了…… 注意:我不仅需要日期和分数(例如姓名) 问题答案: 称为相关子查询。它有它的用途。
问题内容: 我试图弄清楚如何在MySQL中优化一个非常慢的查询(我没有设计这个): 比较一下: 说明语句对我没有帮助: 好的,它仍然认为它需要大约400万个条目才能计数,但是我可以计算文件中的行数比这还要快!我不明白为什么MySQL要花这么长时间。 这是表的定义: 版: 有什么明显的我想念的东西吗?(是的,我已经尝试过“ SELECT COUNT(change_event_id)”,但是没有性能差