Можно ли использовать INSERT OR REPLACE без значения UNIQUE или PRIMARY KEY? - PullRequest
0 голосов
/ 27 июня 2019

Есть ли какой-нибудь возможный способ использования INSERT OR REPLACE INTO без PRIMARY KEY или UNIQUE в SQLite?

Я хочу обновить значения в таблице, где 4 параметра совпадают со значениями, если не существует, я хочу вставить новую строку. Но эти 4 параметра НЕ PRIMARY KEY или UNIQUE (могут дублироваться, но комбинация из четырех уникальна).

Я пытался использовать WHERE, но это не разрешено с INSERT. Также UPDATE сам по себе не добавит новую строку.

cur.execute('''INSERT OR REPLACE INTO FileNameStatus
    (FileName, Delivery, SW, FuncName, 
    LinkModDate, ExtSrcModDate, ExtSrcModifier,
    ExtAttModDate, ExtAttModifier, Error, Warning)
    VALUES (?, ?, ?, ?, ? ,? ,? ,? ,? ,? ,?)
    WHERE FileName = :file AND Delivery = :dvry AND SW = :sw AND FuncName = :func''',
    (eachRow, {"file": eachRow[0], "dvry": eachRow[1], "sw": eachRow[2], "func": eachRow[3]},
    ))

Можно ли сделать с SQLite?

Ответы [ 3 ]

0 голосов
/ 27 июня 2019

Вы можете использовать EXISTS, чтобы проверить, присутствует ли уже значение:

INSERT INTO FileNameStatus(FileName, Delivery, SW, FuncName, 
    LinkModDate, ExtSrcModDate, ExtSrcModifier,ExtAttModDate, ExtAttModifier, Error, Warning)
SELECT ?, ?, ?, ?, ? ,? ,? ,? ,? ,? ,?
WHERE NOT EXISTS(SELECT 1 
                 FROM FileNameStatus
                 WHERE FileName = :file AND Delivery = :dvry 
                   AND SW = :sw AND FuncName = :func)
0 голосов
/ 28 июня 2019

Я решил добавить запрос, чтобы проверить, существуют ли данные, как показано ниже:

    for eachRow in data:
        cur.execute('''SELECT FileName, Delivery, SW, FuncName
                    FROM FileNameStatus
                    WHERE FileName = :file AND Delivery = :dvry AND SW = :sw AND FuncName = :func''',
                    {"file": eachRow[0], "dvry": eachRow[1], "sw": eachRow[2], "func": eachRow[3]})

        row = cur.fetchone()
        if row is None: # row not exist
            cur.execute('''INSERT INTO FileNameStatus
                        (FileName, Delivery, SW, FuncName, LinkModDate, ExtSrcModDate, ExtSrcModifier,
                        ExtAttModDate, ExtAttModifier, Error, Warning)
                        VALUES (?, ?, ?, ?, ? ,? ,? ,? ,? ,? ,?)''',
                        eachRow)
        else: # row exist, just update
            cur.execute('''UPDATE FileNameStatus
                            SET FileName = :file, Delivery = :drvy, SW = :sw, FuncName = :func,
                            LinkModDate = :ld, ExtSrcModDate = :sd, ExtSrcModifier = :sm,
                            ExtAttModDate = :ad, ExtAttModifier = :am, Error = :err, Warning = :warn
                            WHERE FileName = :file AND Delivery = :drvy AND SW = :sw AND FuncName = :func;''',
                        {"file": eachRow[0], "drvy": eachRow[1], "sw": eachRow[2], "func": eachRow[3],
                         "ld": eachRow[4], "sd": eachRow[5], "sm": eachRow[6],
                         "ad": eachRow[7], "am": eachRow[8], "err": eachRow[9], "warn": eachRow[10]})
    # apply the changes
    conn.commit()
0 голосов
/ 27 июня 2019

Вместо этого вы можете

  • Выполнить запрос, чтобы проверить, существует ли кортеж с 4 параметрами
    QUERY = "query to select the 4 fields"
    cursor.execute(QUERY, params)
#if cursor row count is > 0 then you have the fields present in the database and you can update
#if it is == 0, then you know that they don't exist and you can insert
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...