检查Sqlite + C#中是否存在记录

xzabzqsa  于 2023-03-13  发布在  SQLite
关注(0)|答案(4)|浏览(304)

我正在检查表中的记录是否已存在。
我怎么能这么做?
我已经写了下面的代码:

string dbName = "Data Source=searchindex.db";
SQLiteConnection con = new SQLiteConnection(dbName);
con.Open();
SQLiteCommand cmd = new SQLiteCommand(con);

// If this sql request return false
cmd.CommandText = "SELECT rowid FROM wordlist WHERE word='word'"; 
cmd.ExecuteNonQuery();

// then add record in table
cmd.CommandText = "INSERT INTO wordlist(word) VALUES ('word')";
ds97pgxw

ds97pgxw1#

要检查该记录是否存在,可以简化代码

cmd.CommandText = "SELECT count(*) FROM wordlist WHERE word='word'"; 
int count = Convert.ToInt32(cmd.ExecuteScalar());
if(count == 0)
{
    cmd.CommandText = "INSERT INTO wordlist(word) VALUES ('word')"; 
    cmd.ExecuteNonQuery();
}

ExecuteScalar将返回查询返回的第一行的第一列。
(The link用于SqlServer,但它与SQLite相同,因为SQLiteCommand应实现IDbCommand接口)
另一种使用方法如下

cmd.CommandText = "INSERT INTO wordlist (word) 
                   SELECT ('word')
                   WHERE NOT EXISTS 
                       (SELECT 1 FROM wordlist WHERE word = 'word');";
cmd.ExecuteNonQuery();

这甚至更好,因为您使用的是单个查询而不是两个(尽管本地DB中的差异应该很小)

6yjfywim

6yjfywim2#

insert into wordlist(word)
        select 'foo' 
        where not exists ( select 1 from wordlist where word = 'foo')
s1ag04yj

s1ag04yj3#

如果您使用的是sqlite-net-pcl,则可以编写以下代码。
我有一个用于几个表的基类,其中有一个RowExists方法,相关的源代码如下所示:

public abstract class BaseSQLiteAccess
{
    protected SQLiteConnection _databaseConnection;
    protected String TableName { get; set; }

    //...

    protected bool RowExists(int id) 
    {
        bool exists = false;
        try
        {
            exists = _databaseConnection.ExecuteScalar<bool>("SELECT EXISTS(SELECT 1 FROM " + TableName + " WHERE ID=?)", id);
        }
        catch (Exception ex)
        {
            //Log database error
            exists = false;
        }
        return exists;
    }
}
ecbunoof

ecbunoof4#

对于新手来说,通过引入Upsert特性,我们可以一次性插入行(如果它们存在或不存在)

CREATE TABLE "Person" (
    "Id"    INTEGER NOT NULL UNIQUE,
    "Name"  TEXT NOT NULL,
    PRIMARY KEY("Id")
)

请注意,Id列具有Unique约束,因此不能重复。
假设Person表包含以下行:

Id Name
-- ----
1  John
2  Bill

现在考虑下面的upsert语句:

INSERT INTO Person(Id, Name) VALUES (2,'Mike') ON CONFLICT DO NOTHING;
INSERT INTO Person(Id, Name) VALUES (3,'Hans') ON CONFLICT DO NOTHING;

当这些语句被执行时,执行将是 successful,并且只会插入一行(即“Hans')。

ON CONFLICT DO NOTHING

子句,并且它忽略与Insert语句的任何冲突(由于上面的“Mike”的ID已存在,因此未插入该语句)。如果没有该语句,我们将得到唯一约束错误。
上插功能的SQLite页面:
https://www.sqlite.org/draft/lang_UPSERT.html
C#示例:

public void Upsert()
    {
        string dbFilePath = "Test.db";
        string connectionString = $"Data Source={dbFilePath}";
        using (var connection = new SqliteConnection(connectionString))
        {
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandText = $"INSERT INTO Person(Id, Name) VALUES(2, 'Mike') ON CONFLICT DO NOTHING;";
                int rowsAffected = command.ExecuteNonQuery(); // is 0
                System.Console.WriteLine("rowsAffected: " + rowsAffected);
            }
        }
    }

请注意,我在C#示例中使用了Microsoft.Data.Sqlite库(而不是System.Data.Sqlite)。

相关问题