变量以错误的方式被切割,但现在知道为什么了吗?
A variable is cut in a wrong way but now sure why?
我正在编写一个脚本,用于查找超过 6 个月未收到任何提交的特定回购协议的所有分支并将它们删除(在通知提交者之后)。
这个脚本每周 运行 来自 Jenkins,将所有这些分支存储在一些 MySQL 数据库中,然后在下一个 运行 (1 周后),将从中提取相关分支名称数据库并将删除它们。
我想确保如果由于某种原因脚本在同一天两次 运行,相关分支将不会再次添加到数据库中,所以我使用 [=31= 检查它] 查询:
def insert_data(branch_name):
try:
connection = mysql.connector.connect(user=db_user,
host=db_host,
database=db_name,
passwd=db_pass)
cursor = connection.cursor(buffered=True)
insert_query = """insert into {0}
(
branch_name
)
VALUES
(
\"{1}\"
) where not exists (select 1 from {0} where branch_name = \"{1}\" and deletion_date is NULL) ;""".format(
db_table,
branch_name
)
cursor.execute(insert_query, multi=True)
connection.commit()
except Exception as ex:
print(ex)
finally:
cursor.close()
connection.close()
当我运行脚本时,由于某种原因,branch_name变量在中间被切断,然后检查分支名称是否已存在于数据库中的查询失败:
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 'where not exists (select 1 from branches_to_delete where branch_name = `AUT-1868' at line 8
因此,它不会检查 'AUT-18681_designer_create_new_name_if_illegal_char_exist',而是检查数据库中不存在的 'AUT-1868'。
我试过以下方法:
'{1}'
"{1}"
{1}
但是没有用。
我做错了什么?
我没有发现任何错误 假设 branch_name
的来源是安全的(你不会对 SQL 注入攻击开放),但是作为实验,您可以尝试:
insert_query = f"""insert into {db_table}(branch_name) VALUES(%s) where not exists
(select 1 from {db_table} where branch_name = %s and deletion_date is NULL)"""
cursor.execute(insert_query, (branch_name, branch_name))
我正在使用准备好的语句(这也是 SQL 注入攻击安全的)因此将 branch_name 作为参数传递给 execute
方法并且还删除了multi=True
参数。
更新
我觉得自己有点像个傻瓜,因为我遗漏了明显非法的 WHERE
条款。尽管如此,建议使用准备好的语句的其余答案是值得遵循的建议,因此我会保留它。
在 INSERT INTO
查询中使用 WHERE
语句是非法的:
INSERT INTO `some_table`(`some_column`)
VALUES ('some_value') WHERE [some_condition]
所以,上面的例子是无效的MySQL查询。为了防止 branch_name
重复,您应该在 table 上添加唯一索引,例如:
ALTER TABLE `table` ADD UNIQUE INDEX `unique_branch_name` (`branch_name`);
在此之后您可以使用下一个查询:
INSERT INTO `table` (`branch_name`) VALUES ('branch_name_1')
ON DUPLICATE KEY UPDATE `branch_name` = `branch_name`;
注意:如果你的table有自动增加的id,它会在每次插入尝试时增加
从 MySQL 8.0 开始,您可以使用 JASON_TABLE function for generate pseudo table from your values filter it from already exists values and use it fro insert. Look here for example
我正在编写一个脚本,用于查找超过 6 个月未收到任何提交的特定回购协议的所有分支并将它们删除(在通知提交者之后)。 这个脚本每周 运行 来自 Jenkins,将所有这些分支存储在一些 MySQL 数据库中,然后在下一个 运行 (1 周后),将从中提取相关分支名称数据库并将删除它们。
我想确保如果由于某种原因脚本在同一天两次 运行,相关分支将不会再次添加到数据库中,所以我使用 [=31= 检查它] 查询:
def insert_data(branch_name):
try:
connection = mysql.connector.connect(user=db_user,
host=db_host,
database=db_name,
passwd=db_pass)
cursor = connection.cursor(buffered=True)
insert_query = """insert into {0}
(
branch_name
)
VALUES
(
\"{1}\"
) where not exists (select 1 from {0} where branch_name = \"{1}\" and deletion_date is NULL) ;""".format(
db_table,
branch_name
)
cursor.execute(insert_query, multi=True)
connection.commit()
except Exception as ex:
print(ex)
finally:
cursor.close()
connection.close()
当我运行脚本时,由于某种原因,branch_name变量在中间被切断,然后检查分支名称是否已存在于数据库中的查询失败:
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 'where not exists (select 1 from branches_to_delete where branch_name = `AUT-1868' at line 8
因此,它不会检查 'AUT-18681_designer_create_new_name_if_illegal_char_exist',而是检查数据库中不存在的 'AUT-1868'。
我试过以下方法:
'{1}'
"{1}"
{1}
但是没有用。
我做错了什么?
我没有发现任何错误 假设 branch_name
的来源是安全的(你不会对 SQL 注入攻击开放),但是作为实验,您可以尝试:
insert_query = f"""insert into {db_table}(branch_name) VALUES(%s) where not exists
(select 1 from {db_table} where branch_name = %s and deletion_date is NULL)"""
cursor.execute(insert_query, (branch_name, branch_name))
我正在使用准备好的语句(这也是 SQL 注入攻击安全的)因此将 branch_name 作为参数传递给 execute
方法并且还删除了multi=True
参数。
更新
我觉得自己有点像个傻瓜,因为我遗漏了明显非法的 WHERE
条款。尽管如此,建议使用准备好的语句的其余答案是值得遵循的建议,因此我会保留它。
在 INSERT INTO
查询中使用 WHERE
语句是非法的:
INSERT INTO `some_table`(`some_column`)
VALUES ('some_value') WHERE [some_condition]
所以,上面的例子是无效的MySQL查询。为了防止 branch_name
重复,您应该在 table 上添加唯一索引,例如:
ALTER TABLE `table` ADD UNIQUE INDEX `unique_branch_name` (`branch_name`);
在此之后您可以使用下一个查询:
INSERT INTO `table` (`branch_name`) VALUES ('branch_name_1')
ON DUPLICATE KEY UPDATE `branch_name` = `branch_name`;
注意:如果你的table有自动增加的id,它会在每次插入尝试时增加
从 MySQL 8.0 开始,您可以使用 JASON_TABLE function for generate pseudo table from your values filter it from already exists values and use it fro insert. Look here for example