我需要一个SQL表来更新Unit#,而不是如果它检测到Unit已经存在就创建一个新条目

问题描述

我正在尝试建立一个数据库来管理居住在封闭社区中的居民。目标是创建一个功能,使物业经理可以轻松地填写表格,然后将信息提交到数据库中。如果单元号不存在,我需要sql创建一个新条目,但如果单元确实存在,则需要用新数据覆盖该单元号的条目。这是我目前的代码。因此,基本上我要说的是,不仅仅是盲目地在适当的列中输入数据,我需要它检查:unit值是否已经存在,以及是否确实覆盖了那里的数据。

def submit():

    #logging
    logger.info("Resident info added for")
    logger.info(unit.get())
    print(logger.level)

    #Databases
    conn = sqlite3.connect('rdata.db')
    c = conn.cursor()
    c.execute("INSERT INTO rdata VALUES (:name,:unit,:phone1,:phone2,:snote,:snote2,:guest1,:guest2,:guest3,:guest4,:guest5,:guest6,:guest7,:guest8,:guest9,:guest10,:guest11,:guest12,:guest13,:guest14,:guest15)",{
            'name': name.get(),'unit': unit.get(),'phone1': phone1.get(),'phone2': phone2.get(),'snote': snote.get(),'snote2':snote2.get(),'guest1': guest1.get(),'guest2': guest2.get(),'guest3': guest3.get(),'guest4': guest4.get(),'guest5': guest5.get(),'guest6': guest6.get(),'guest7': guest7.get(),'guest8': guest8.get(),'guest9': guest9.get(),'guest10': guest10.get(),'guest11': guest11.get(),'guest12': guest12.get(),'guest13': guest13.get(),'guest14': guest14.get(),'guest15': guest15.get(),})

    conn.commit()
    conn.close()

    name.delete(0,END)
    unit.delete(0,END)
    phone1.delete(0,END)
    phone2.delete(0,END)
    snote.delete(0,END)
    snote2.delete(0,END)
    guest1.delete(0,END)
    guest2.delete(0,END)
    guest3.delete(0,END)
    guest4.delete(0,END)
    guest5.delete(0,END)
    guest6.delete(0,END)
    guest7.delete(0,END)
    guest8.delete(0,END)
    guest9.delete(0,END)
    guest10.delete(0,END)
    guest11.delete(0,END)
    guest12.delete(0,END)
    guest13.delete(0,END)
    guest14.delete(0,END)
    guest15.delete(0,END)

解决方法

您正在描述一个upsert查询。在SQLite中,这是通过on conflict实现的。

要执行此操作,您需要在列unit上使用唯一约束-或将该列用作主键。

然后,您可以按如下方式查询短语。为了减少可读性,我减少了列的数量...并且因为我对您的设计感到怀疑-这15 guest列可能应该是另一个表中的行。

INSERT INTO rdata (name,unit,phone,snote,guest)
VALUES (:name,:unit,:phone,:snote,:guest)
ON CONFLICT(unit)
UPDATE SET
    name  = excluded.name,phone = excluded.phone,snote = excluded.snote,guest = excluded.guest

如果存在具有相同unit的行,则查询将使用新值更新现有行。

请注意,我在insert中枚举了目标列:出于多种原因(例如可维护性),这是SQL中的一种好习惯。