如何在 SQLite 插入中添加关系?

问题描述 投票:0回答:1

我想知道,对于Int和Text的添加,如何在insert中添加relation?

我找不到 sqlite3_bind_relationship 或外键。

let insertRequest = "INSERT INTO Entity (Id, Name, OtherClass) VALUES (?, ?, ?);"

func insert(class: Class, otherClass : OtherClass) {
    var insertQuery: OpaquePointer?

    if sqlite3_prepare_v2(openDatabase(), insertRequest, -1, &insertQuery, nil) == SQLITE_OK {
        let id: Int32 = class.id
        let name: String = class.name
        let otherClass : OtherClass = otherClass

        sqlite3_bind_int(insertQuery, 1, id)
        sqlite3_bind_text(insertQuery, 2, descriptionPrevent, -1, nil)
            // What sqlite3_bin_ for other class ?
        sqlite3_bind_??
           
            
        if sqlite3_step(insertQuery) == SQLITE_DONE {
            print("Successfully inserted row prevent.")
        } else {
            print("Could not insert row.")
        }
    } else {
        print("\nINSERT statement is not prepared.")
    }
    sqlite3_finalize(insertQuery)
}

我使用 CoreData 来制作我的实体,并使用关系来链接它们。

swift sqlite core-data
1个回答
0
投票

你说:

我使用 CoreData 来制作我的实体,我使用关系来链接它们

如果您正在使用 CoreData,那么您真的应该使用 CoreData 将项目插入持久存储中,而不是使用 SQLite 进入后门。你可以很容易地通过自己插入值来破坏数据库的完整性。

然后,你的列名又不像标准的 CoreData 数据库。例如,如果我查看我刚刚为“书籍”和“作者”创建的一个简单的 CoreData 数据库,它的架构如下所示:

CREATE TABLE ZAUTHOR ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZNAME VARCHAR );
CREATE TABLE ZBOOK ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZAUTHOR INTEGER, ZTITLE VARCHAR );
CREATE INDEX ZBOOK_ZAUTHOR_INDEX ON ZBOOK (ZAUTHOR);
CREATE TABLE Z_PRIMARYKEY (Z_ENT INTEGER PRIMARY KEY, Z_NAME VARCHAR, Z_SUPER INTEGER, Z_MAX INTEGER);
CREATE TABLE Z_METADATA (Z_VERSION INTEGER PRIMARY KEY, Z_UUID VARCHAR(255), Z_PLIST BLOB);
CREATE TABLE Z_MODELCACHE (Z_CONTENT BLOB);

然而,如果我自己在 SQLite 中创建它,它可能看起来像:

CREATE TABLE author (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL);
CREATE TABLE book (id INTEGER PRIMARY KEY NOT NULL, title TEXT NOT NULL, author_id INTEGER NOT NULL, FOREIGN KEY(author_id) REFERENCES author(id));
CREATE INDEX idx_book_author ON book(author_id);

让我们考虑后一个示例,并假设数据库如下所示:

sqlite> SELECT * FROM author;
id  name
--  -------------------
1   William Faulkner
2   William Shakespeare

sqlite> SELECT * FROM book;
id  title                   author_id
--  ----------------------  ---------
1   The Sound and the Fury  1
2   As I Lay Dying          1
3   Henry V                 2

如果我要为莎士比亚插入一本新书,那将是:

INSERT INTO book (title, author_id) VALUES('Romeo and Juliet', 2);

如果以编程方式执行此操作,则该

author_id
参数将是值
sqlite3_bind_int
2
,这是
author
表中 Shakespeare 的主键。我个人会让 SQLite 为这一行生成
id
,可以用
sqlite3_last_insert_rowid
获取。

现在,这是一个过于简化的例子。有时(例如这本书作者的例子),你会有一个多对多的关系(一本书可以有多个作者,每个作者可能有多本书,他们是作者)。在这种情况下,

book
表可能没有
author_id
列,而是可能有一个单独的交叉引用表,例如,
book_author
包含这些
id
书籍和作者的交叉引用。但是,同样,这些
id
列将是一种与外键类型(通常是 SQLite 数据库中的整数)相匹配的类型。关键只是这些外国参考的方式和位置可能会根据实体关系的类型而有所不同。

但是,如果这真的是 CoreData 数据库,那么这一切都没有实际意义,因为我建议不要通过 SQLite 插入行(或进行任何直接交互)。使用核心数据。例如,回到这个答案顶部的 CoreData 模式中捕获的一对多示例,添加一个

Book
和一个
Author
的引用,我可能会执行以下操作:

private func addBook(_ title: String, for author: Author) throws {
    let book = Book(context: viewContext)
    book.title = title
    book.author = author

    try viewContext.save()
}

在幕后,CoreData 确实在做一些非常接近上面概述的

id
外键模式的事情,但它为我们处理了所有这些细节,我们将避免绕过 CoreData。我们让 CoreData 为我们做这件事。

© www.soinside.com 2019 - 2024. All rights reserved.