SQLite3格式化问题,参数通过添加另一个值来更新现有值

2024-06-06 11:42:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在学习如何在Python中使用sqlite3模块。我正在尝试编写代码,通过向现有值添加新值来更新sqlite中某个列的值,但遇到了格式问题,我不知道如何解决

我知道这样做的基本语法(据我所知)如下:

sql_statement = "UPDATE table 
                 SET column_name = column_name + new_value 
                 WHERE condition;"

我遇到的问题是,我试图使用python中的dictionary参数插入列名。这就是我的代码中出现的问题:

muscle = 'Lats'
num_sets = 5
week_num = 40

sql_statement = f"UPDATE WeeklyMuscleSets 
                 SET {muscle} = (:muscle) + (:num_sets) 
                 WHERE WeekID = (:week_num);"

parameters = {'muscle':muscle,'num_sets':num_sets,'week_num':week_num}

c.execute(sql_statement,parameters)

代码运行得很好,但它不是添加到表中的现有值,而是替换它。我做了一些测试,当我手动输入“muscle”变量的值时,它会很好地更新

muscle = 'Lats'
num_sets = 5
week_num = 40

sql_statement = f"UPDATE WeeklyMuscleSets 
                 SET {muscle} = Lats + (:num_sets) 
                 WHERE WeekID = (:week_num);"

parameters = {'num_sets':num_sets,'week_num':week_num}

c.execute(sql_statement,parameters)

当我对muscle变量使用f-string格式时,它也起作用,但是我知道这是一种不好的做法,代码容易受到注入攻击

出于某种原因,当我使用参数时,它不会将新值添加到现有值中,而是替换它,我不知道为什么。非常感谢您的帮助


Tags: 代码sql格式setsupdatecolumnwherenum
2条回答

你确定你的代码运行正常吗?根据this postthis one,表名或列名不能使用命名占位符。您正在尝试为列使用命名占位符,因此我希望引发异常

我们想到了两种解决问题的方法:

  1. 使用字符串{格式化}。正如您所指出的,这有允许SQL注入攻击的缺点。但是,可以对来自用户的数据进行清理。如果安全性是一个很大的问题,那么您可能应该使用某种ORM而不是原始SQL

  2. 重新构造表格,使其看起来更像:

    create WeeklyMuscleSets (
        muscle varchar,
        number_of_sets number,
        week number
    )
    

    您的查询看起来更像这样:

    update WeeklyMuscleSets 
    set number_of_sets = number_of_sets + :extra_sets
    where muscle = :muscle
    

这是参数化查询。然后将查询和值分别发送到DBMS引擎,DBMS使用解析的查询中的值。然后将解析后的查询重新存储和使用,从而提高了性能,避免了SQL注入

如果要将num_sets添加到muscle的当前值,则必须使用muscle + :num_sets

num_sets = 5
week_num = 40

sql_statement = f"UPDATE WeeklyMuscleSets 
                 SET muscle = muscle + :num_sets
                 WHERE WeekID = :week_num;"

parameters = {'num_sets':num_sets,'week_num':week_num}

c.execute(sql_statement,parameters)

相关问题 更多 >