0

我有以下代码:

### Write the new userid to the sql database
# Open database connection
db = MySQLdb.connect("sql01.domain1.lan","webuserid","test","webuserid" )
# prepare a cursor object using cursor() method
cursor = db.cursor()



dub_userid = int(userid)
# Check for dublicate of current userid value
sql = "SELECT * FROM webuserid WHERE userid = '"+str(dub_userid)+"'"
try:
        # Execute the SQL command
        cursor.execute(sql)
        # Fetch all the rows in a list of lists.
        results = cursor.fetchone()
        data = cursor.fetchone()
except:
        print "SQL Error: Unable to fetch data"
if data == None:
        print "User doesn't exist - Creating"
else:
        sys.exit("User exists")

# Prepare SQL query to INSERT a record into the database.
sql = """INSERT INTO webuserid(userid)
         VALUES ('"""+userid+"""')"""
try:
        # Execute the SQL command
        cursor.execute(sql)
        # Commit your changes in the database
        db.commit()
except:
        #Rollback in case there is any error
        db.rollback()
# disconnect from server
db.close()

变量 userid 的字符串值为 00001

我想要代码做的是连接到数据库(工作),将 userid 转换为 dub_userid 中的整数,并使用结果值查找重复项。

问题是,当我运行代码时,用户 ID 值为 00001 时会发生以下情况:

  1. 用户 ID 1 已提交到数据库(应该如此,因为没有其他名为 1 的用户 ID
  2. 下一次运行,用户 ID 1 再次提交到数据库(不应该,因为用户 ID 1 已经存在)
  3. 第三次运行,脚本与“用户存在”消息一样存在。

我已经尝试过数据和数据 [1],但似乎无法弄清楚出了什么问题。

4

2 回答 2

2

您真的不想使用字符串插值,而是使用 SQL 参数。接下来,您将获取行;您真正需要做的就是测试是否有任何行:

sql = "SELECT * FROM webuserid WHERE userid = %s"

try:
    # Execute the SQL command
    cursor.execute(sql, (dub_userid,))
    found = cursor.rowcount
except:
    print "SQL Error: Unable to fetch data"
if not found:
    print "User doesn't exist - Creating"
else:
    sys.exit("User exists")

sql = """INSERT INTO webuserid(userid)
         VALUES (%s)"""
try:
    # Execute the SQL command
    cursor.execute(sql, (userid,))
    # Commit your changes in the database
    db.commit()
except:
    #Rollback in case there is any error
    db.rollback()
# disconnect from server
db.close()

这可以进一步简化;您可以db用作上下文管理器来自动提交或在失败时回滚:

with db:
    cursor.execute(sql, (userid,))

db.close()
于 2013-04-07T15:40:15.290 回答
1

这个问题可以而且应该通过向表中添加一个 UNIQUE 约束来解决,而不是通过编写 Python 代码。如果您尝试通过编写 Python 代码来强制执行约束,仍然有可能有人通过其他方法插入数据。如果添加约束,则约束由数据库本身强制执行。

ALTER TABLE tablename ADD UNIQUE indexname (userid)

添加此约束后,INSERT如果违反约束,语句将引发异常。您可以将其包装cursor.execute在 atry...except中以处理违规行为。

如果您的表已经有违反约束的行,那么

ALTER IGNORE TABLE tablename ADD UNIQUE indexname (userid)

将添加约束删除所有违反约束的行(为每个唯一的 useid 保留一行)。

于 2013-04-07T15:40:02.683 回答