使用C#代码从SQlite表中安全删除多行

ercv8c1e  于 2022-12-23  发布在  SQLite
关注(0)|答案(2)|浏览(309)

我在这里和网上搜索了一种使用C#代码从SQlite表中删除多行的方法。我已经能够将不同的代码粘在一起,我认为应该工作,但不幸的是它没有。
这个函数的结果总是0条记录被更新而没有错误。那么,有人能告诉我这个RemoveLinks方法有什么问题吗?
该函数应仅删除URL列与列表中的任何URL字符串匹配的行。URL列是唯一的,但不是主键。

public static int RemoveLinks(string table, List<string> urls)
{
    SQLiteConnection sqlite_conn;
    sqlite_conn = CreateConnection();
    try
    {
        var urlsString = string.Join(",", urls.Select(p => p));
        var deleteQuery = string.Format("delete from {0} where {1} in ({2})", table, "url", "@urlsStr");
        SQLiteCommand sqlite_cmd;
        sqlite_cmd = sqlite_conn.CreateCommand();
        sqlite_cmd.CommandText = deleteQuery;
        sqlite_cmd.Parameters.Add(new SQLiteParameter("@urlsStr", urlsString));
        int rslt = sqlite_cmd.ExecuteNonQuery();
        sqlite_conn.Close();
        return rslt;
    }
    catch (Exception e)
    {
        sqlite_conn.Close();
        MessageBox.Show(e.Message);
        return 0;
    }
}
    • 更新**

根据评论和回答中的建议更新,但仍然没有记录被删除。

public static bool RemoveLinks(string table, List<string> urls)
    {
        bool result = false;
        SQLiteConnection sqlite_conn;
        sqlite_conn = CreateConnection();
        try
        {
            var urlsString = string.Join(",", urls);
            var deleteQuery = string.Format("delete from {0} where {1} in ('{2}')", table, "url", urlsString);
            SQLiteCommand sqlite_cmd = sqlite_conn.CreateCommand();
            sqlite_cmd.CommandText = deleteQuery;
                      
            var rslt = sqlite_cmd.ExecuteScalar();
            result = (rslt != null);
            return result;
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
            return result;
        }
        finally { sqlite_conn.Close(); }
    }
kxxlusnw

kxxlusnw1#

您提供的RemoveLinks方法存在一些问题:
urlsString变量未正确转义。这意味着,如果URL列表中的任何URL包含单引号字符(')或逗号(,),则生成的删除查询将无效。若要修复此问题,可以使用SQLiteConnection类提供的EscapeString方法对URL列表中的URL进行转义。
deleteQuery变量正在使用字符串格式来构建删除查询,但它没有正确地将urlsString变量括在引号中。这意味着,如果URL列表中的任何URL包含单引号字符(')或逗号(,),则生成的删除查询将无效。要解决此问题,应将urlsString变量括在引号中,如下所示:“从{0}中删除(”{2}“)中的{1}”
您正在使用ExecuteNonQuery方法执行删除查询,但此方法不返回已删除的行数,而是返回受查询影响的行数,该行数可能与已删除的行数不同。若要获取已删除的行数,请执行以下操作:您可以使用ExecuteScalar方法执行选择查询,该查询对符合删除条件的行数进行计数,如下所示:

var countQuery = string.Format("select count(*) from {0} where {1} in ('{2}')", table, "url", urlsString);
SQLiteCommand countCommand = sqlite_conn.CreateCommand();
countCommand.CommandText = countQuery;
int countBefore = Convert.ToInt32(countCommand.ExecuteScalar());

var deleteQuery = string.Format("delete from {0} where {1} in ('{2}')", table, "url", urlsString);
SQLiteCommand deleteCommand = sqlite_conn.CreateCommand();
deleteCommand.CommandText = deleteQuery;
deleteCommand.ExecuteNonQuery();

countCommand.CommandText = countQuery;
int countAfter = Convert.ToInt32(countCommand.ExecuteScalar());
int rowsDeleted = countBefore - countAfter;
ckx4rj1h

ckx4rj1h2#

唯一有效的代码是下面的代码,其中每个链接都被两个'包围。仍然无法找到一种方法来判断删除是否完成,因为ExecuteScalar总是返回null,ExecuteNonQuery总是返回-1。

public static bool RemoveLinks(string table, List<string> urls)
    {
        bool result = false;
        SQLiteConnection sqlite_conn;
        sqlite_conn = CreateConnection();
        try
        {
            var urlsString = string.Join("','", urls);
            var deleteQuery = string.Format("delete from {0} where {1} in ('{2}')", table, "url", urlsString);
            SQLiteCommand sqlite_cmd = sqlite_conn.CreateCommand();
            sqlite_cmd.CommandText = deleteQuery;
                      
            var rslt = sqlite_cmd.ExecuteScalar();
            result = (rslt != null);
            return result;
        }
        catch (Exception e)
        {
            MessageBox.Show(e.Message);
            return result;
        }
        finally { sqlite_conn.Close(); }
    }

相关问题