在我的Python代码中,当我要求用户向SELECT输入一个字符串时,它可以正常工作,但是当我尝试使用相同输入的UPDATE时,不允许我执行
连接成功完成后,这是我的代码
curs = connection.cursor()
str_input1 = str(input("Input : "))
str_input2 = str(input("Input : "))
statement = "UPDATE table SET variable1 = "+str_input1+" WHERE name = "+str_input2
curs.execute(statement)
connection.commit
理论上,下面的代码应该可以工作并更新变量,但是我在行curs.execute(语句)中得到错误
cx_Oracle.DatabaseError: ORA-00904: John: invalid identifier
John是where子句
的str_input2也许它的格式给我一个错误,但我不太确定。
有人可以指出我的代码有什么问题吗?
答案 0 :(得分:3)
错误是因为您没有引用这些值。您从SELECT
语句中得到完全相同的错误。
这些语句搜索name
列与字符串John
匹配的行:
SELECT * FROM table WHERE name = "John"
UPDATE table SET variable1 = "Hi" WHERE name = "John"
这些语句搜索name
列与John
列匹配的行 - 如果没有John
列,则表示错误:
SELECT * FROM table WHERE name = John
UPDATE table SET variable1 = "Hi" WHERE name = John
所以,你可以通过在值周围加上引号来解决这个问题。
但你真的,真的,真的不应该。这样可以打开SQL injection attacks,以及您不能正确引用或转义特殊字符的愚蠢错误,以及数据库引擎无法告诉您运行相同字符的性能问题一遍又一遍地查询,等等。
您要做的是使用SQL parameters,而不是尝试格式化字符串。我不记得cx_Oracle使用哪种参数样式,但你可以import cx_Oracle; print(cx_Oracle.paramstyle)
,然后查找in the table来查找。然后做一些像:
statement = "UPDATE table SET variable1 = :v WHERE name = :n"
curs.execute(statement, {'v': str_input1, 'n': str_input2})
另外,还有一些附注:
connection.commit
没有做任何事情;您只是引用commit
方法,而不是调用它。您需要括号:connection.commit()
str(input())
毫无意义。 input
函数始终返回一个字符串,因此没有理由在其上调用str
。 (除非你使用的是Python 2.x,在这种情况下你应该使用raw_input()
,它返回一个字符串,而不是使用input
到eval
字符串开放与上面的SQL注入攻击相同的安全问题 - 仅将其转换回字符串。)