2014-10-28 230 views
1

我创建了一个名为'PTNList'的列表,并且我需要添加的所有内容都很好。现在我试图编写代码来从列表中检索每个元素,并针对SQL查询运行它。我有一种感觉,我不确定如何解决这个问题。 CompareNumbers.txt文件生成,但没有打印到它。任何帮助是极大的赞赏。从创建列表中检索元素

以下是我认为需要使用的代码部分。

  using (FileStream fs = new FileStream("c:/temp/CompareNumbers.txt", FileMode.Append, FileAccess.Write)) 
      using (StreamWriter sw = new StreamWriter(fs)) 


      foreach (var ptn in PTNList) 
      { 
       //create sql for getting the count using "ptn" as the variable thats changing 
       //call DB with sql 
       //Get count from query, write it out to a file; 

       Console.WriteLine("Running Query"); 
       string query2 = @"SELECT COUNT(PRODUCT_TYPE_NO) 
            AS NumberOfProducts 
            FROM dbo.PRODUCT 
            Where PRODUCT_TYPE_NO = " + ptn; 



       SqlCommand cmd2 = new SqlCommand(query2); 
       cmd2.Connection = con; 

       rdr = cmd2.ExecuteReader(); 

       while (rdr.Read()) 
       { 
        sw.WriteLine(rdr["NumberOfProducts"]); 
       } 
       rdr.Close(); 
      } 
+0

当查询运行,是rdr.HasRows真的吗? – 2014-10-28 15:02:57

回答

2

你还没有用过这些值的撇号。但无论如何你应该使用参数。您可以为每种类型使用一个查询而不是一个查询。例如这种方法:

string sql = @"SELECT COUNT(PRODUCT_TYPE_NO) AS NumberOfProducts 
       FROM dbo.PRODUCT 
       Where PRODUCT_TYPE_NO IN ({0});"; 

string[] paramNames = PTNList.Select(
    (s, i) => "@type" + i.ToString() 
).ToArray(); 

string inClause = string.Join(",", paramNames); 
using (SqlCommand cmd = new SqlCommand(string.Format(sql, inClause))) 
{ 
    for (int i = 0; i < paramNames.Length; i++) 
    { 
     cmd.Parameters.AddWithValue(paramNames[i], PTNList[i]); 
    } 

    // con.Open(); // if not already open 
    int numberOfProducts = (int) cmd.ExecuteScalar(); 
} 

更新:也许你真的只是想环路他们,得到他们的计数。那么你不需要这种复杂的方法。但你仍然应该使用sql参数来防止sql注入和其他问题,如缺少撇号等

+0

是的,我只是想输出一个文本文件的计数。它应该是一个简单的事情,但我倾向于使自己的一切... – enigmahfc 2014-10-28 15:45:38

+0

@enigmahfc:使用'where PRODUCT_TYPE_NO = @ type'而不是'where PRODUCT_TYPE_NO =“+ ptn;'。然后使用(single)sql - 参数如上图所示 – 2014-10-28 16:03:46

+0

这似乎奏效了,谢谢你,我在这里抨击我的头。 – enigmahfc 2014-10-28 17:37:30

0

你确定你的查询给出了一个结果和sw.WriteLine被执行?我会重新设计你的代码,因为如果你的数据查询有错误,你可能会遇到麻烦。我总是喜欢用这个(模式):

IDataReader reader = null; 

try 
{ 
// create every thing... 
} 
catch(Exception ex) 
{ 
// catch all exceptions 
} 
finally() 
{ 
    if(reader != null) 
    { 
     reader.Close(); 
    } 
} 

并使用相同的为您的连接,以便您可以肯定,它是关闭正确的。

1

您需要将列转换回某种类型,例如

sw.WriteLine(rdr["NumberOfProducts"] as string); 

另外,请注意您的查询很容易出现SQL注入攻击的攻击,应该是参数,并且SqlCommand也是一次性的。您可以通过重用SqlCommand更多一点儿性能:

string query2 = @"SELECT COUNT(PRODUCT_TYPE_NO) 
        AS NumberOfProducts 
        FROM dbo.PRODUCT 
        Where PRODUCT_TYPE_NO = @ptn"; 

using (var cmd2 = new SqlCommand(query2)) 
{ 
    cmd2.Connection = con; 
    cmd2.Parameters.Add("@ptn", SqlDbType.Varchar); 
    foreach (var ptn in PTNList) 
    { 
     cmd2.Parameters["@ptn"].Value = ptn; 

     Console.WriteLine("Running Query"); 
     using var (rdr = cmd2.ExecuteReader()) 
     { 
      if (rdr.Read()) 
      { 
       sw.WriteLine(rdr["NumberOfProducts"] as string); 
      } 
     } 
    } 

}