C#代码不返回参数化查询值(Datetime) - 相同的查询在SQL中有效

时间:2017-11-24 03:24:41

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

我一直遇到动态查询问题,我通过querystring接收值作为select查询的搜索参数。

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

我现在非常困惑,所有其他领域除日期外都在搜索。我尝试了很多其他方法参数化日期值,但我得到了错误。 “从字符串转换日期和/或时间时转换失败。”

我现在很困惑。

我试图尽可能多地删除代码以便于阅读。

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表和变量中的

1 个答案:

答案 0 :(得分: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作为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'字符串值转换为datetime(作为日期比较)并将转换失败作为结果。您可以按字面意思传递列名:

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

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