我的查询只给出一个结果,即一个url的一个单词应该为dt中的每个条目运行。这里的dt是 DataTable 并且包含很多行, url_given 是一个字符串。 temp 是包含要匹配的字词的表格。任何人都可以告诉我我的查询有什么问题。 wordcount是表的名称。 url_String,word和count是列。
查询的目的是获取与给定网址匹配的网址 列表中的单词 temp 。
foreach (DataRow row in dt.Rows)
{
// read item
url_given = row["url_String"].ToString();
String qrystring = "select url_String,word,count from wordcount where url_String='" + url_given + "' and word in (select * from temp) ";
dt1 = db.searchandorder(qrystring);
// searchandorder is a call to a function that establishes the db connections and passes the query to the data adapter.
}
这是我的搜索功能
public DataTable searchandorder (String sql)
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
DataSet ds = new DataSet();
DataTable dt = new DataTable();
da.Fill( dt);
conn.Close();
Console.Write("table coloumns" + dt.Columns.ToString());
return dt;
}
答案 0 :(得分:3)
你的问题来自你每次循环覆盖dt1
的事实。你需要合并结果而不是替换它们,但我不能说如何在没有看到db.searchandorder
的情况下这样做。
你也有一个非常危险的SQL注入攻击。如果url_given
是'; drop table wordcount; --
那么程序将在服务器上执行的查询是什么?您需要将parameters与数据适配器一起使用。
编辑:那么,既然你已经展示了代码,那么就是你如何修复它。您每次通过时都不会创建一个新的DataTable
,而是在循环之外创建一个并且每次都传入同一个表。 TableAdapter
默认填写之前不会清除表格。
private YourFunction(DataTable dt)
{
DataTable dt1 = new DataTable();
foreach (DataRow row in dt.Rows)
{
// read item
url_given = row["url_String"].ToString();
String qrystring = "select url_String,word,count from wordcount where url_String='" + url_given + "' and word in (select * from temp) ";
db.searchandorder(qrystring, dt1);
// searchandorder is a call to a function that establishes the db connections and passes the query to the data adapter.
}
DoSomthingWithResults(dt1);
}
public void searchandorder (String sql, DataTable dt)
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(sql, conn);
da.Fill( dt);
conn.Close();
Console.Write("table coloumns" + dt.Columns.ToString());
return dt;
}
现在,这是使您的计划有效的最低要求。你正在做很多其他不好的做法。
不要重复使用连接:您的conn
对象应该在searchandorder
内创建,并且在using
语句中。不要担心连接太多",.NET会使用connection pooling并重复使用旧连接。
使用using
语句:任何实现IDisposable的内容都应该在using
语句中(除非该项目被返回)
遵循命名标准:后面有set of standards个C#代码,您的班级searcandhorder
应命名为SerchAndOrder
。
使用参数:您容易受到数据适配器的SQL injection attack使用参数的攻击。它不仅提高了安全性,还允许SQL服务器缓存查询执行计划,从而加快程序运行。
以下是应用了这些修补程序的程序版本。
private YourFunction(DataTable dt)
{
DataTable dt1 = new DataTable();
foreach (DataRow row in dt.Rows)
{
// read item
url_given = row["url_String"].ToString();
var parameter = new SqlParameter("@urlGiven", SqlDbType.VarChar, url_given.Length);
parameter.Value = url_given;
String qrystring = "select url_String,word,count from wordcount where url_String=@urlGiven and word in (select * from temp) ";
db.searchandorder(qrystring, dt1, parameter);
// searchandorder is a call to a function that establishes the db connections and passes the query to the data adapter.
}
DoSomthingWithResults(dt1);
}
public void SearchAndOrder (String sql, DataTable dt, params SqlParameter[] parameters)
{
using(var conn = new SqlConnection(_connectionString))
using(var da = new SqlDataAdapter(sql, conn))
{
da.SelectCommand.Parameters.AddRange(parameters);
conn.Open();
da.Fill(dt);
}
Console.Write("table coloumns" + dt.Columns.ToString());
return dt;
}