【问题标题】:C# code not returning parameterized query values (Datetime) - Same query works in SQLC# 代码不返回参数化查询值(日期时间) - 相同的查询在 SQL 中有效
【发布时间】:2018-05-08 00:48:54
【问题描述】:

我在动态查询中遇到问题,我通过查询字符串接收值作为选择查询的搜索参数。

当它读取时,它根本没有值,当我查看 SQL 活动监视器以查看实际传递给它的 SQL 时。我选择查询并自行在 SQL Server 上运行它,它会返回值。

我现在很困惑,除了日期之外,所有其他字段都可以搜索。我也尝试了很多其他方式参数化日期值,但我得到了错误。 "从字符串转换日期和/或时间时转换失败。'"

我现在很困惑。

为了便于阅读,我已尝试尽可能多地删减代码。

var queryString = this.Request.GetQueryNameValuePairs();
List<KeyValuePair<string, object>> QueryStringKeys = new List<KeyValuePair<string, object>>();

foreach (var pair in queryString)
{
     QueryStringKeys.Add(new KeyValuePair<string, object>(pair.Key.ToString(), pair.Value));
}

 DateTime thedates;
 thedates = DateTime.ParseExact(keys.Value.ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture);
 string tempdatestring = thedates.Year.ToString() + "-" + thedates.Month.ToString() + "-" + thedates.Day.ToString();
 SqlCommand cmd = new SqlCommand("", connection);
 StringBuilder QString = new StringBuilder();
 StringBuilder sqlBuilder = new StringBuilder();

 QString.Append(" Where @").Append(keys.Key).Append("=@" + keys.Key + "value");
 cmd.Parameters.AddWithValue("@" + keys.Key, keys.Key);
 cmd.Parameters.AddWithValue("@" + keys.Key + "value", "cast('" + tempdatestring + "' as datetime)");

 sqlBuilder.Append("SELECT [EMP_ID],[EMP_SURNAME],[EMP_GIVENNAMES],[EMP_TITLE],[EMP_STARTDATE] from EMPLOYEES " + QString.ToString() + ")");
 cmd.CommandText = sqlBuilder.ToString(); 

 SqlDataReader test;
 test = cmd.ExecuteReader();

 while (test.Read())
 {
     //No values returned from dates searches
 }

我尝试添加日期的其他方式。

另请注意,日期字段是日期字段,而不是日期时间。

cmd.Parameters.Add("@" + keys.Key + "value", SqlDbType.DateTime).Value = tempdatestring;
// -----
SqlParameter parameter = cmd.Parameters.Add("@" + keys.Key + "value", System.Data.SqlDbType.DateTime);
parameter.Value = DateTime.Parse(tempdatestring);
//------
cmd.Parameters.AddWithValue("@" + keys.Key + "value", new SqlDateTime(thedates));
//----
cmd.Parameters.AddWithValue("@" + keys.Key + "value", thedates);

sql 表和变量中的值

【问题讨论】:

  • cast('" + tempdatestring + "' as datetime) => 我认为这不是执行字符串到日期转换的好方法。转换应完全在 C# 中完成,并将结果作为 datetimedatetime2 传递给 DB。
  • 我知道,到目前为止,这是我实际运行它而不会出现异常的唯一方法。如您所见,我尝试使用以下其他方法
  • 你有DateTime thedates = DateTime.ParseExact(keys.Value.ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture);,尝试直接将DateTime传递给没有tempdatestring的参数:cmd.Parameters.AddWithValue("@" + keys.Key + "value", thedates);
  • 我试过 cmd.Parameters.AddWithValue("@" + keys.Key + "value", DateTime.ParseExact(keys.Value.ToString(), "dd/MM/yyyy", CultureInfo.不变文化));并得到“从字符串转换日期和/或时间时转换失败。”
  • 那么你应该检查keys.Value,它有什么样的字符串&它是否包含有效的日期时间字符串?如果传递了无效的日期时间字符串,DateTime.ParseExact 将抛出错误(请注意DateTime 没有特定格式,它将每个日期组件存储为属性)。

标签: c# asp.net sql-server parameters parameter-passing


【解决方案1】:

从结果查询来看:

SELECT [EMP_ID],[EMP_CREATIONDATE],[EMP_LASTCHANGED],[EMP_CREATEDBY‌​],[EMP_UPDATEDBY],[E‌​MP_SURNAME],[EMP_GIV‌​ENNAMES],[EMP_TITLE]‌​,[EMP_STARTDATE]
FROM [SQLDEMO].[dbo].[EMPLOYEES]
Where @EMP_STARTDATE=@EMP_STARTDATEvalue

您实际上传递了 2 个参数作为比较的一部分:

  • @EMP_STARTDATE as string 参数(包含列名);
  • @EMP_STARTDATEvalue 作为date 参数(包含DateTime 值)。

当两个参数值都被传递时,它将形成这个示例查询(正如我在 SSMS 中分析的那样):

SELECT [EMP_ID],[EMP_CREATIONDATE],[EMP_LASTCHANGED],[EMP_CREATEDBY‌​],[EMP_UPDATEDBY],[E‌​MP_SURNAME],[EMP_GIV‌​ENNAMES],[EMP_TITLE]‌​,[EMP_STARTDATE]
FROM [SQLDEMO].[dbo].[EMPLOYEES] 
Where 'EMP_STARTDATE' = [any datetime value]

上面的查询尝试将'EMP_STARTDATE' 字符串值转换为日期时间(作为日期比较)并抛出转换失败作为结果。您可以按字面意思传递列名,如下所示:

QString.Append(" Where ").Append(keys.Key).Append(" = @" + keys.Key + "value");
DateTime thedates = DateTime.ParseExact(keys.Value.ToString(), "dd/MM/yyyy", CultureInfo.InvariantCulture);

using (SqlCommand cmd = new SqlCommand("", connection))
{
    StringBuilder QString = new StringBuilder();
    StringBuilder sqlBuilder = new StringBuilder();

    // note there is no '@' before Append(keys.Key) method
    // so that it becomes column name instead of parameter name
    QString.Append(" Where ").Append(keys.Key).Append(" = @" + keys.Key + "value");
    // just pass single parameter value
    cmd.Parameters.AddWithValue("@" + keys.Key + "value", thedates);

    sqlBuilder.Append("SELECT [EMP_ID],[EMP_SURNAME],[EMP_GIVENNAMES],[EMP_TITLE],[EMP_STARTDATE] from EMPLOYEES " + QString.ToString() + ")");
    cmd.CommandText = sqlBuilder.ToString(); 

    SqlDataReader test = cmd.ExecuteReader();

    // other stuff
}

上面的语句生成了这个例子,这是一个有效的查询(EMP_STARTDATE变成了列名标识符而不是参数值):

SELECT [EMP_ID],[EMP_CREATIONDATE],[EMP_LASTCHANGED],[EMP_CREATEDBY‌​],[EMP_UPDATEDBY],[E‌​MP_SURNAME],[EMP_GIV‌​ENNAMES],[EMP_TITLE]‌​,[EMP_STARTDATE]
FROM [SQLDEMO].[dbo].[EMPLOYEES]
Where EMP_STARTDATE = @EMP_STARTDATEvalue

注意:最好使用参数开关创建存储过程来确定应该执行哪个查询,而不是构建动态查询。

【讨论】:

  • 非常感谢!,就是这样。我在 where 之后有 @。
猜你喜欢
  • 2014-11-03
  • 2016-09-09
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 2019-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多