为什么在我的应用程序中没有返回行,而同一查询在DBBrowser中返回行?

问题描述

使用针对我的sqlite数据库的简单查询

SELECT MovieTitle,MPAArating,IMDBrating,DurationInMinutes,YearReleased,genres,actors,directors,screenwriters 
FROM MOVIES_SINGLETABLE 
WHERE IMDBrating >= @IMDBMinrating 
ORDER BY IMDBrating DESC,YearReleased DESC LIMIT 1000

...我得到记录:

enter image description here

但要进行更多过滤:

SELECT MovieTitle,screenwriters 
FROM MOVIES_SINGLETABLE 
WHERE IMDBrating >= @IMDBMinrating 
AND (YearReleased BETWEEN @EarliestYear AND @LatestYear) 
AND (genres LIKE '%@genre1%' OR genres LIKE '%@genre2%') 
AND (MPAArating = '@mpaarating1') 
ORDER BY IMDBrating DESC,YearReleased DESC LIMIT 1000

...我什么也没得到(是的,为所有这些参数分配了适当的值,即:5.0,'1958','2019','Drama','Western'和'PG'):

enter image description here

但是,使用相同的查询,我执行获取在DBbrowser中返回的记录:

enter image description here

这是怎么回事?为什么同一个查询在我的应用程序中什么都不会返回,而从DBbrowser中返回什么呢?

更新

根据流行的需求,这是将参数分配给的方式( genresSelected 是字符串列表):

if (GenresFiltered())
{
    if (genresSelected.Count > 0)
    {
        cmd.Parameters.AddWithValue("@genre1",genresSelected[0].ToString());
    }
    if (genresSelected.Count > 1)
    {
        cmd.Parameters.AddWithValue("@genre2",genresSelected[1].ToString());
    }
    . . .

...以及在分配参数之前的查询字符串如下所示:

“ SELECT MovieTitle,MPAArating,IMDBrating,DurationInMinutes, 发行年份,类型,演员,导演,编剧来自 MOVIES_SINGLETABLE在哪里进行IMDBrating> = @IMDBMinrating AND YearReleased @EarliestYear AND @LatestYear AND之间(类型为'%@ genre1%',或 像'%@ genre2%'的流派或像'%@ genre3%'的流派 '%@ genre4%'或流派,如'%@ genre5%'或流派,如'%@ genre6%' 或类型,例如'%@ genre7%'或类型,例如'%@ genre8%'或类型 '%@ genre9%')和(MPAArating like'%@ mpaarating1%')排序依据 IMDBrating DESC,年发行的DESC LIMIT 1000“

更新2

现在,最终查询查询字符串(已删除单引号):

选择MovieTitle,MPAArating,IMDBrating,DurationInMinutes, 发行年份,类型,演员,导演,编剧来自 MOVIES_SINGLETABLE在哪里进行IMDBrating> = @IMDBMinrating并且 (年份发布于@EarliestYear和@LatestYear之间)和(类型 @ genre1或类型@@ genre2)和(MPAArating = @ mpaarating1)订单 通过IMDBrating DESC,年发行的DESC LIMIT 1000

我尝试了以下所有排列,但没有一个返回任何数据:

  1. "AND (genres = @genre1 OR genres = @genre2) "

  2. "AND ((genres = @genre1) OR (genres = @genre2)) "

  3. "AND ((genres LIKE '%' || @genre1 || '%') OR (genres LIKE '%' || @genre2 || '%')) "

  4. AND (genres LIKE '%'+@genre1+'%' OR genres LIKE '%'+@genre2+'%')

  5. AND (genres LIKE @genre1 OR genres LIKE @genre2) -with:

    cmd.Parameters.AddWithValue(“ @ genre1”,string.Format(“%{0}%”,genresSelected [0] .ToString())); cmd.Parameters.AddWithValue(“ @ genre2”,string.Format(“%{0}%”,genresSelected 1。ToString()));

更新3

尽我所能将来自forpas的想法整合进去,我能够在DBbrowser中获得返回的记录,但是在实际的应用程序中还没有。注释掉的行和下面用于过滤类型的现有行都可以使用。如果没有用单引号引起来的值,我会得到一个错误消息,内容是“ Western”不是列名,而是用单引号引起来:

enter image description here

因此,我尝试了以下所有排列,但没有一个返回任何记录:

// @genre1 and @genre2 not surrounded by single quotes
return "AND ((genres LIKE '%' || @genre1 || '%') OR (genres LIKE '%' || @genre2 || '%')) "; 

// @genre1 and @genre2 surrounded by single quotes
return "AND ((genres LIKE '%' || '@genre1' || '%') OR (genres LIKE '%' || '@genre2' || '%')) "; 

// @genre1 and @genre2 not surrounded by single quotes,string prepended with "@"
return @"AND ((genres LIKE '%' || @genre1 || '%') OR (genres LIKE '%' || @genre2 || '%')) "; 

// @genre1 and @genre2 surrounded by single quotes,string prepended with "@"
return @"AND ((genres LIKE '%' || '@genre1' || '%') OR (genres LIKE '%' || '@genre2' || '%')) ";             

然后,我想问题是:我如何在C#中产生与 在DBbrowser中工作的相同的sql,即以下行:

AND ((genres LIKE '%' || 'Western' || '%') OR (genres LIKE '%' || 'Drama' || '%')) 

注意:这也不会返回任何内容

AND ((genres LIKE @genre1) OR (genres LIKE @genre2)) 

解决方法

在sql语句中,传递的参数一定不能用单引号引起来。
还让SQLite使用'%'运算符将||通配符连接到参数。 因此,编写这样的代码:

WHERE IMDBRating >= @IMDBMinRating 
AND (YearReleased BETWEEN @EarliestYear AND @LatestYear) 
AND ((genres LIKE '%' || @genre1 || '%') OR (genres LIKE '%' || @genre2 || '%')) 
AND (MPAARating = @mpaaRating1)

更新
我看到您添加了如下类型的参数值:

cmd.Parameters.AddWithValue("@genre1",string.Format("%{0}%",genresSelected[0].ToString()));

因此您将通配符包含在字符串中。
这意味着无需在sql语句中再次连接它们。
因此,请使用运算符LIKE及其参数:

WHERE IMDBRating >= @IMDBMinRating 
AND (YearReleased BETWEEN @EarliestYear AND @LatestYear) 
AND ((genres LIKE @genre1) OR (genres LIKE @genre2)) 
AND (MPAARating = @mpaaRating1)
,

我相信问题出在您的查询中。看起来您正在使用参数化查询,因此您应该使用以下任一方法:

var query = "SELECT MovieTitle,MPAARating,IMDBRating,DurationInMinutes,YearReleased,genres,actors,directors,screenwriters 
FROM MOVIES_SINGLETABLE 
WHERE IMDBRating >= @IMDBMinRating 
AND (YearReleased BETWEEN @EarliestYear AND @LatestYear) 
AND (genres LIKE '%'+@genre1+'%' OR genres LIKE '%'+@genre2+'%') 
AND (MPAARating = @mpaaRating1) 
ORDER BY IMDBRating DESC,YearReleased DESC LIMIT 1000";

...

cmd.Parameters.AddWithValue("@genre1","gener1");
cmd.Parameters.AddWithValue("@genre2","gener2");
cmd.Parameters.AddWithValue("@mpaaRating1","rating");

var query = "SELECT MovieTitle,screenwriters 
FROM MOVIES_SINGLETABLE 
WHERE IMDBRating >= @IMDBMinRating 
AND (YearReleased BETWEEN @EarliestYear AND @LatestYear) 
AND (genres LIKE @genre1 OR genres LIKE @genre2) 
AND (MPAARating = @mpaaRating1) 
ORDER BY IMDBRating DESC,"%gener1%");
cmd.Parameters.AddWithValue("@genre2","%gener2%");
cmd.Parameters.AddWithValue("@mpaaRating1","rating");
,

在大多数应用程序层SQL参数化中,必须在通配符绑定到准备的SQL语句之前,在原始字符串上连接通配符。

if (GenresFiltered())
{
    if (genresSelected.Count > 0)
    {
        cmd.Parameters.AddWithValue("@genre1","%" + genresSelected[0].ToString() + "%");
        // cmd.Parameters.AddWithValue("@genre1",String.concat("%",genresSelected[0].ToString(),"%"));
    }
    if (genresSelected.Count > 1)
    {
        cmd.Parameters.AddWithValue("@genre2","%" + genresSelected[1].ToString() "%");
        // cmd.Parameters.AddWithValue("@genre2",genresSelected[1].ToString(),"%"));
    }
    . . .

此外,准备好的语句中的所有参数通常都不会被引号,通配符或其他符号引起来。

SELECT MovieTitle,screenwriters 
FROM MOVIES_SINGLETABLE 
WHERE IMDBRating >= @IMDBMinRating 
  AND (YearReleased BETWEEN @EarliestYear AND @LatestYear) 
  AND (genres LIKE @genre1 OR genres LIKE @genre2) 
  AND (MPAARating = @mpaaRating1) 
ORDER BY IMDBRating DESC,YearReleased DESC 
LIMIT 1000
,

我终于可以使用它了:

    return string.Format("AND instr(genres,'{0}') > 0 OR instr(genres,'{1}') > 0 ",genresSelected[1].ToString());

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...