查询无法在SQLReader

时间:2016-05-18 19:41:39

标签: c# sql sql-server console-application

我的项目中有这个代码来运行查询并将其粘贴到Excel中。我目前在一个项目中工作(使用不同的查询),但现在我试图让它使用不同的查询,它将无法正常工作。但是,如果我在SQL Server中运行查询,它就可以工作。

以下是查询:

public static string Query (DateTime startDate, DateTime endDate)
{
     //string Query = "SELECT * from access";
     string Query = "SELECT distinct s.first_nme + ' ' + s.last_nme as Student ,convert(Date, e.entrydate) as date ,od.u_order_id as 'Order#'";
     Query = Query + " " + "FROM enrollment e";
     Query = Query + " " + "join registration r on e.u_registration_id = r.u_registration_id";
     Query = Query + " " + "join student s on r.u_student_id = s.u_student_id";
     Query = Query + " " + "join order_pack_list opl on r.u_ord_pack_list_id = opl.u_ord_pack_list_id";
     Query = Query + " " + "join product p on opl.u_product_id = p.u_product_id";
     Query = Query + " " + "join order_detail od on opl.u_order_detail_id = od.u_order_detail_id";
     Query = Query + " " + "where e.entrydate >= " + startDate.ToString();
     Query = Query + " " + "and e.entrydate <= " + endDate.ToString();
     Query = Query + " " + "and p.prod_type_cd = 'B' and opl.modify_user_id = 'STCUSA30'";
     Query = Query + " " + "order by Student";

     return Query;
}

顶部有一个注释掉的行的原因是测试 - 当我运行这个简单的查询时,它不会崩溃。

以下是我用来获取日期(并运行查询)的代码,以此作为问题进行排除:

DateTime startDate = DateTime.Today.AddDays(-1);
DateTime endDate = DateTime.Today;

SqlDataReader rdr = null;

try
{

     // 2. Open the connection
     conn.Open();

     string query = Query(startDate, endDate);

     // 3. Pass the connection to a command object
     using (SqlCommand cmd = new SqlCommand(query, conn))
     {
           //
           // 4. Use the connection
           //

           // get query results
           rdr = cmd.ExecuteReader();

它在rdr线上崩溃说,

  

类型&#39; System.Data.SqlClient.SqlException&#39;未处理的异常   发生在System.Data.dll

中      

其他信息:&#39; 12&#39;附近的语法不正确。

我在线查看并且没有与我的情况有关的答案(我可以告诉)。

1 个答案:

答案 0 :(得分:2)

根据您的错误,您可以看到这可能会如何呈现如下所示的查询,这是无效的SQL(因为这些常量值需要用引号括起来):

WHERE e.entryDate >= 12/31/2016

之所以发生这种情况是因为您将DateTime对象连接成一个字符串,但由于它没有用引号括起来,所以它已经爆炸了。您可以轻松添加引号以帮助防止这种情况:

Query = Query + " " + "where e.entrydate >= '" + startDate.ToString() + "' ";
Query = Query + " " + "and e.entrydate <= " + endDate.ToString() + "' ";;

更好的方法:参数化

这里更大的问题是你应该使用参数化来填充这些值以避免这些类型的问题(以及任何SQL注入的可能性):

Query = Query + " " + "where e.entrydate >= @start";
Query = Query + " " + "and e.entrydate <= @end";

然后在执行查询之前将这些值作为参数添加:

using (SqlCommand cmd = new SqlCommand(query, conn))
{
       // Add your parameters
       cmd.Parameters.AddWithValue("@start",startDate);
       cmd.Parameters.AddWithValue("@end",endDate);

       // Execute here
}