如何创建以列表作为参数的 SELECT 语句?
How do I create a SELECT statement with a list as a parameter?
代码
以下代码仅在列表targets_in_sw
中只有一个值时起作用:
sw_current = cursor.execute("SELECT * from SOFTWARE_")
sw_current = sw_current.fetchall()
for sw_item in sw_current:
current_software_id = sw_item[0]
# Create Software XML Element
sw_element = ET.SubElement(root, "Software")
# Get all Targets for current sw_element
targets_in_sw = cursor.execute("SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1=?", (current_software_id,))
targets_in_software = targets_in_sw.fetchall()
targets_in_software = list(chain.from_iterable(targets_in_sw))
# Get all Target IDs for current sw_element
current_target_IDs = cursor.execute("SELECT * from TARGET_ WHERE id_=?", targets_in_software)
current_target_IDs = current_target_IDs.fetchall()
## The following line ONLY prints when my list contains one value ##
print current_target_IDs
问题
当 targets_in_software
是一个包含多个值的列表时,我该如何更改它以便我可以 select 来自 TARGET_
的所有内容?
备注:
如果你没有看到标签,我正在使用 SQLite3。
下面是循环过程中 targets_in_software
中值的示例:
iteration targets_in_software
1 [21]
2 [28]
3 [29]
4 [91]
5 [92]
6 [94]
7 [217]
8 [218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228]
9 [251]
10 [261]
...etc.
您可以使用 IN
以这种方式创建查询:
SELECT * from TARGET_ WHERE id IN tuple(targets_in_software)
这将在 targets_in_software
有多个值时起作用。
您需要将 SQL IN operator 与您的 ORM 一起使用。我没有足够的详细信息来了解您使用的是什么。尝试使用 SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1 IN ?
或 SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1 IN ?
将 sw_item 作为参数而不是 current_software_id。
您的原始 SQL 查询应如下所示:
SELECT val FROM table_name WHERE ref_val in ('val_one','val_two');
所以对于你的情况,你应该这样做:
targets_in_sw = cursor.execute("SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1=(" + ",".join(targets_in_software) + ");")
请注意,这不会保护您免受 SQL 注入。
如果你传递一个元组作为execute的第二个参数,它会尝试用元组的每个元素替换查询字符串中的占位符,例如:
stmt = "INSERT INTO mytable (name, id, rank) VALUES (%s, %s, %s)"
cursor.execute(stmt, (a, b, c))
创建一个查询,其中每个 %s 都被元组的一个元素替换。在您的情况下,您希望最终得到一个查询,其中整个元组都在一个地方,因此您需要将其转换为字符串:
stmt = "SELECT * from TARGET_ WHERE id_ IN %s"
#convert list of ints to tuple of strings
stmt_param = str(tuple(map(str, targets_in_software)))
cursor.execute(stmt, stmt_param)
我认为这应该可行,但我无法对其进行测试,因为我没有可供测试的数据库。希望对您有所帮助。
代码
以下代码仅在列表targets_in_sw
中只有一个值时起作用:
sw_current = cursor.execute("SELECT * from SOFTWARE_")
sw_current = sw_current.fetchall()
for sw_item in sw_current:
current_software_id = sw_item[0]
# Create Software XML Element
sw_element = ET.SubElement(root, "Software")
# Get all Targets for current sw_element
targets_in_sw = cursor.execute("SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1=?", (current_software_id,))
targets_in_software = targets_in_sw.fetchall()
targets_in_software = list(chain.from_iterable(targets_in_sw))
# Get all Target IDs for current sw_element
current_target_IDs = cursor.execute("SELECT * from TARGET_ WHERE id_=?", targets_in_software)
current_target_IDs = current_target_IDs.fetchall()
## The following line ONLY prints when my list contains one value ##
print current_target_IDs
问题
当 targets_in_software
是一个包含多个值的列表时,我该如何更改它以便我可以 select 来自 TARGET_
的所有内容?
备注:
如果你没有看到标签,我正在使用 SQLite3。
下面是循环过程中 targets_in_software
中值的示例:
iteration targets_in_software
1 [21]
2 [28]
3 [29]
4 [91]
5 [92]
6 [94]
7 [217]
8 [218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228]
9 [251]
10 [261]
...etc.
您可以使用 IN
以这种方式创建查询:
SELECT * from TARGET_ WHERE id IN tuple(targets_in_software)
这将在 targets_in_software
有多个值时起作用。
您需要将 SQL IN operator 与您的 ORM 一起使用。我没有足够的详细信息来了解您使用的是什么。尝试使用 SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1 IN ?
或 SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1 IN ?
将 sw_item 作为参数而不是 current_software_id。
您的原始 SQL 查询应如下所示:
SELECT val FROM table_name WHERE ref_val in ('val_one','val_two');
所以对于你的情况,你应该这样做:
targets_in_sw = cursor.execute("SELECT TARGET2 from SOFTWARE_TARGET_ WHERE SOFTWARE1=(" + ",".join(targets_in_software) + ");")
请注意,这不会保护您免受 SQL 注入。
如果你传递一个元组作为execute的第二个参数,它会尝试用元组的每个元素替换查询字符串中的占位符,例如:
stmt = "INSERT INTO mytable (name, id, rank) VALUES (%s, %s, %s)"
cursor.execute(stmt, (a, b, c))
创建一个查询,其中每个 %s 都被元组的一个元素替换。在您的情况下,您希望最终得到一个查询,其中整个元组都在一个地方,因此您需要将其转换为字符串:
stmt = "SELECT * from TARGET_ WHERE id_ IN %s"
#convert list of ints to tuple of strings
stmt_param = str(tuple(map(str, targets_in_software)))
cursor.execute(stmt, stmt_param)
我认为这应该可行,但我无法对其进行测试,因为我没有可供测试的数据库。希望对您有所帮助。