变量以错误的方式被切割,但现在知道为什么了吗?

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