发现问题:
- SqlKata编译器正在将列名转换为字符串文本,以便在找不到匹配列时返回。
- 将查询更新为使用方括号而不是引号解决了该问题。
- 在此创建了关于此问题的github问题:https://github.com/sqlkata/querybuilder/issues/655
初始帖子内容保留如下。
我正在对一个Sqlite数据库进行一些单元测试,以确保我的创建和读取方法都能正常工作(它们确实如此),但是其中一个测试失败了,我完全不知道为什么。
Sqlite db由单个表组成,定义如下:表名称:学生列:ID(主键)、名字(字符串)、姓氏(字符串)
以下查询工作正常,返回数据库中的"FirstName"值:
"SELECT \"FirstName\" FROM \"Students\" WHERE \"ID\" = @p0"
下面的查询可能会导致异常,因为列名不存在:
"SELECT \"UnknownCol\" FROM \"Students\" WHERE \"ID\" = @p0"
相反,我收到的值'UnknownCol'是字符串结果。
作为参考,我使用相同的方法(处理DbCommand对象)通过OledbCommand对Excel文件执行相同的操作。该函数产生了一个异常(不是一个有用的异常,但至少它错误我们的)。所以我知道底层方法是有效的。
为什么sqlite会返回查询中不存在的列的名称?
其他信息编辑:
当我在查询中请求无效列时,使用OledbConnection以相同的方法读取Excel工作表会导致以下异常(虽然它不会告诉您这是一个由于列名无效而导致的错误查询,但至少它会出错):
Exception Message: No value given for one or more required parameters.
完整代码链:
//db object has a method that returns a SqliteConnection, and has a 'Compiler' property that returns the SqlKata.Compiler object for SqlLite
var qry = new SqlKata.Query("Students").Select("UnknownCol").Where("ID",1);
return GetValue(db.GetConnection(), qry, db.Compiler);
//Results in the following sql:
"SELECT \"UnknownCol\" FROM \"Students\" WHERE \"ID\" = 1"
---
public static object GetValue(DbConnection connection, Query query, SqlKata.Compilers.Compiler compiler)
{
using (var cmd = connection.CreateCommand(query, compiler))
{
connection.Open();
try
{
return cmd.ExecuteScalar();
}
finally
{
connection.Close();
}
}
}
public static DbCommand CreateCommand(this DbConnection connection, SqlKata.Query query, SqlKata.Compilers.Compiler compiler)
{
if (connection is null) throw new ArgumentNullException(nameof(connection));
if (compiler is null) throw new ArgumentNullException(nameof(compiler));
var result = compiler.Compile(query ?? throw new ArgumentNullException(nameof(query)));
var cmd = connection.CreateCommand();
cmd.CommandText = result.Sql;
foreach (var p in result.NamedBindings)
{
_ = cmd.AddParameter(p.Key, p.Value);
}
return cmd;
}
public static DbParameter AddParameter(this DbCommand command, string name, object value)
{
var par = command.CreateParameter();
par.ParameterName = name;
par.Value = value;
command.Parameters.Add(par);
return par;
}
1条答案
按热度按时间ff29svar1#
在SQL中
select
字符串是法律的的。这是一个有效的SQL查询,它返回上述字符串:它将返回包含此字符串literal的单行。
对于表中的每一行,它都将返回一个包含此字符串literal的行。下面是一个测试数据库中包含几行的测试表的示例:
如果你想查询一个特定的列名,而不是字符串,你必须删除列名周围的
''
字符,那么这是一个未定义列的结果:或对于定义的列: