问题描述
SELECT MovieTitle,MPAArating,IMDBrating,DurationInMinutes,YearReleased,genres,actors,directors,screenwriters
FROM MOVIES_SINGLETABLE
WHERE IMDBrating >= @IMDBMinrating
ORDER BY IMDBrating DESC,YearReleased DESC LIMIT 1000
...我得到记录:
但要进行更多过滤:
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'):
但是,使用相同的查询,我执行获取在DBbrowser中返回的记录:
这是怎么回事?为什么同一个查询在我的应用程序中什么都不会返回,而从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
我尝试了以下所有排列,但没有一个返回任何数据:
-
"AND (genres = @genre1 OR genres = @genre2) "
-
"AND ((genres = @genre1) OR (genres = @genre2)) "
-
"AND ((genres LIKE '%' || @genre1 || '%') OR (genres LIKE '%' || @genre2 || '%')) "
-
AND (genres LIKE '%'+@genre1+'%' OR genres LIKE '%'+@genre2+'%')
-
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”不是列名,而是用单引号引起来:
因此,我尝试了以下所有排列,但没有一个返回任何记录:
// @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());