python mysql 中 table 个名称的占位符

placeholders for table names in python mysql

我正在使用 python sql 编辑一个名为 students 的非常简单的 table(其列为 nameage) ,如下图:

('Rachel', 22)
('Linckle', 33)
('Bob', 45)
('Amanda', 25)
('Jacob', 85)
('Avi', 65)
('Michelle', 45)

我正在定义 python 函数来执行 SQL 代码。

在我的第一个函数中,我想更新 students table 中的 age 值,其中 name 匹配某些东西(例如 Bob)。如果我定义以下函数:

def update_age(age, name):
    c.execute("""UPDATE students SET age = %s
    WHERE name = %s""", (age, name))

然后:

update_age(99, 'Bob')

我会得到:

('Rachel', 22)
('Linckle', 33)
('Bob', 99)
('Amanda', 25)
('Jacob', 85)
('Avi', 65)
('Michelle', 45)

在第二个函数中,我还想使用以下代码指定 table 的名称:

def update_age_table(table, age, name):
    c.execute("""UPDATE %s SET age = %s
    WHERE name = %s""", 
             (table, age, name)) # note that here I am only replacing students by the placeholder %s

那么如果我这样做:

update_age_table(table='students', age=95, name='Jacob')

我会得到如下错误信息(很长,我只显示最后一句:

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 ''students' SET age = 95
    WHERE name = 'Jacob'' at line 1

我猜这个错误是因为我分配两个占位符给变量,即agename,这是不是 table 名称的情况,那里没有变量赋值。

有谁知道如何在 SQL 命令中使用占位符而不将它们分配给变量?

那是因为您不能将 table 名称作为执行语句中的参数传递。你应该这样做:

def update_age_table(table, age, name):
    c.execute("UPDATE "+table+" SET age = %s
    WHERE name = %s", 
             (table, age, name)) #

准备好的语句不适用于 table 个名称

编辑 您必须像这样删除 table 参数:

def update_age_table(table, age, name):
    c.execute("UPDATE "+table+" SET age = %s WHERE name = %s",(age, name)) #

抱歉弄错了

    dt= datetime.datetime.now()
    new_date=str(dt)
    idname=input("Please enter Your Id.  ")
    bname= input("Please Enter name of book which you want to Issue: ")
    idn=(idname,)
    sql="insert into id%s (issuedbook,date)"%idn +"values (%s,%s)"

    val=(bname,new_date)
    cursor.execute(sql,val)
    cnx.commit()
insert_data()```

未经测试,这应该是公认答案的更好编码风格。正如整个 Q/A 所示,变量仅在 cursor.execution() 时间传递以使其更安全,但是 execute() 字符串的 table 语句在参数被评估之前被评估求值,这就是为什么 tables 必须在 execute() 之前进行纯文本求值,而变量却不需要。请参阅 处具有类似挑战的另一个示例,其中 table 也未通过。

因此,作为正确接受的查询的 add-on:

def update_age_table(UPDATE_QUERY, args):
    c.execute(UPDATE_QUERY, args)
    c.commit()

# example for string testing:
table, age, name = "table_x", 2, "name_y"

UPDATE_QUERY = f"""
   UPDATE {table}
   SET age = %s
   WHERE name = %s
"""

# # UPDATE_QUERY Out:
# '\n    UPDATE table_x\n    SET age = %s\n    WHERE name = %s\n'

args = [age, name]
update_age_table(UPDATE_QUERY, args)