第七章:数据持久存储与交换-sqlite3:嵌入式关系数据库-在查询中使用变量-位置参数

7.4.5 在查询中使用变量
如果查询被定义为字面量字符串,要嵌入到程序中,那么使用这种查询会很不灵活。例如,向数据库增加另一个项目时,显示前5个任务的查询就应当更新,从而能处理其中任意一个项目。要向增加灵活性,一种方法是建立一个SQL语句,通过在Python中结合相应的值来提供所需的查询。不过,以这种方式构造查询串很危险,应当尽量避免。如果未能对查询中可变部分的特殊字符正确地转义,则可能会导致SQL解析错误,或者更糟糕地,还有可能导致一类被称为SQL注入攻击(SQL-injection attack)的安全漏洞,这会使入侵者能够在数据库中执行任意的SQL语句。
要在查询中使用动态值,正确的方法是利用随SQL指令一起传入execute()的宿主变量(host variable)。执行SQL语句时,SQL中的占位符值会替换为宿主变量的值。通过使用宿主变量,而不是解析之前在SQL语句中插入任意的值,这样可以避免注入攻击,因为不可信的值没机会影响SQL语句的解析。SQLite支持练个形式带占位符的查询,分别是位置参数和命名参数。

7.4.5.1 位置参数
问号(?)指示一个位置参数,将作为元组的一个成员被传至execute()。

import sqlite3
import sys

db_filename = 'todo.db'
project_name = sys.argv[1]

with sqlite3.connect(db_filename) as conn:
    cursor = conn.cursor()

    query = """
    select id,priority,details,status,deadline from task
    where project = ?
    """
    cursor.execute(query,(project_name,))

    for row in cursor.fetchall():
        task_id,priority,details,status,deadline = row
        print('{:2d} [{:d}] {:<25} [{:<8}] ({})'.format(
            task_id,priority,details,status,deadline))

命令行参数会作为位置参数安全地传至查询,所以恶意数据不可能破坏数据库。
运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值