如何实现current_schedule表存在则取ID插入statistic,不存在则新增后插入?
完善你的日程与统计关联逻辑
首先得指出你原代码里的两个容易踩的小坑:
- 连续调用两次
cursor.fetchone()会导致逻辑出错——第一次已经把查询结果取走了,第二次调用只会返回None; - 直接用
format拼接SQL语句存在SQL注入风险,必须用参数化查询来规避这个问题。
下面是完善后的完整代码,我加了详细注释,完全覆盖你需要的“存在则取ID,不存在则创建再取ID”的核心逻辑:
# 1. 用参数化查询检查指定日期的日程是否存在(避免SQL注入) cursor.execute("SELECT id FROM current_schedule WHERE date = %s", (lessondate,)) schedule_record = cursor.fetchone() if schedule_record: # 如果日程存在,直接取出对应的ID schedule_id = schedule_record[0] else: # 如果日程不存在,先插入新的日程记录 # 注意:这里要根据你current_schedule表的实际结构,补充其他必填字段和对应值 cursor.execute( "INSERT INTO current_schedule (date, [其他必填字段]) VALUES (%s, [对应值])", (lessondate, [其他字段的具体值]) ) # 获取刚插入记录的自增ID(不同数据库写法略有区别) # - MySQL/SQLite:用cursor.lastrowid # - PostgreSQL:可以在INSERT语句末尾加 RETURNING id,然后用cursor.fetchone()[0]获取 schedule_id = cursor.lastrowid # 2. 根据flag判断是否插入统计记录 if flag == str_to_bool('true'): # 同样用参数化查询插入statistic表,替换成你实际需要的字段和值 cursor.execute( "INSERT INTO statistic (id_student, id_current_schedule, [其他字段]) VALUES (%s, %s, [对应值])", (student_id, schedule_id, [其他字段的具体值]) ) # 记得提交事务(如果你的数据库连接没有开启自动提交的话) conn.commit()
关键细节说明:
- 参数化查询:把变量放在SQL的占位符(
%s,不同数据库可能用?或$1)位置,而非直接拼接字符串,这是防止SQL注入的标准做法; - 自增ID获取:不同数据库获取刚插入记录ID的方式不同,要根据你使用的数据库调整:
- MySQL/SQLite:直接用
cursor.lastrowid; - PostgreSQL:修改INSERT语句为
INSERT INTO current_schedule (date) VALUES (%s) RETURNING id,再用cursor.fetchone()[0]获取ID;
- MySQL/SQLite:直接用
- 事务提交:如果你的连接没有开启自动提交,一定要最后调用
conn.commit(),否则所有操作都不会生效。
内容的提问来源于stack exchange,提问作者Demmy
相关产品推荐
相关产品推荐

