C# tvp.值=表; 命令.参数.添加(tvp); 使用(var reader=command.ExecuteReader()) while(reader.Read()) { 添加(reader.GetInt(“ID”); } } 您知道它们都可以接受SQL注
tvp.值=表; 命令.参数.添加(tvp); 使用(var reader=command.ExecuteReader()) while(reader.Read()) { 添加(reader.GetInt(“ID”); } }C# tvp.值=表; 命令.参数.添加(tvp); 使用(var reader=command.ExecuteReader()) while(reader.Read()) { 添加(reader.GetInt(“ID”); } } 您知道它们都可以接受SQL注,c#,sql,.net,collections,ado.net,C#,Sql,.net,Collections,Ado.net,tvp.值=表; 命令.参数.添加(tvp); 使用(var reader=command.ExecuteReader()) while(reader.Read()) { 添加(reader.GetInt(“ID”); } } 您知道它们都可以接受SQL注入吗?@user2711965谢谢,我知道,这只是一个简单的示例。第二个示例将所有where块连接起来,并将它们与或链接起来。然后在末尾,将1=1附加到where语句,该语句也是或链接的。这意味着它返回所有行,因为1=1始终为真。我更想知道为什
您知道它们都可以接受SQL注入吗?@user2711965谢谢,我知道,这只是一个简单的示例。第二个示例将所有where块连接起来,并将它们与
或
链接起来。然后在末尾,将1=1
附加到where语句,该语句也是或
链接的。这意味着它返回所有行,因为1=1
始终为真。我更想知道为什么差异如此之小。如果查询的条件包含数千个运算符,则运行该查询所需的时间会更长……我怀疑第二种方法的主要问题是使用query+=
构建查询,在每个循环中,这会在堆上创建一个新字符串,而不仅仅是添加到现有字符串中。改用StringBuilder。已经说过,有更好更安全的方法将列表作为参数传递。您使用的是什么DBMS?您知道它们都对SQL注入开放吗?@user2711965谢谢,我知道,这只是一个快速示例。第二个示例将所有where块连接起来,并将它们与或
链接。然后在末尾,将1=1
附加到where语句,该语句也是或
链接的。这意味着它返回所有行,因为1=1
始终为真。我更想知道为什么差异如此之小。如果查询的条件包含数千个运算符,则运行该查询所需的时间会更长……我怀疑第二种方法的主要问题是使用query+=
构建查询,在每个循环中,这会在堆上创建一个新字符串,而不仅仅是添加到现有字符串中。改用StringBuilder。已经说过,有更好更安全的方法将列表作为参数传递。您使用的是什么DBMS?谢谢,我更改了1=1
(请参见我的编辑),并且我使用了字符串生成器而不是字符串,这次我得到了54sec@Lamloumi:现在它返回的记录越来越少。但它仍在执行大量字符串连接和字符串比较。你到底在问什么?我在问为什么第一种方法仍然是最快的,即使我在每次调用该方法时都连接/关闭连接,第二种方法只过滤一次列表以获得结果,并且它是在DBMS sideADO.NET中使用的,所以即使你在代码中打开/关闭连接,很可能ADO.NET能够一次又一次地重复使用同一个连接,因此您实际上没有获得打开和关闭连接11000次的成本。谢谢,我更改了1=1
(请参见我的编辑),我使用了字符串生成器而不是字符串,这次我得到了54sec@Lamloumi:现在它返回的记录越来越少。但它仍在执行大量字符串连接和字符串比较。你到底在问什么?我在问为什么第一种方法仍然是最快的,即使我在每次调用该方法时都连接/关闭连接,第二种方法只过滤一次列表以获得结果,并且它是在DBMS sideADO.NET中使用的,所以即使你在代码中打开/关闭连接,很可能ADO.NET能够一次又一次地重用同一个连接,因此您实际上没有获得打开和关闭连接11000次的成本。
public void GetList(List<string> liste, List<int> outliste)
{
foreach( string s in liste){
outliste.Add(SqlFunction(s));
}
}
public int SqlFunction(string str)
{
string query = "select id from user where name="+str;
...................
// return the id
}
public void SqlSecondWayFunction(List<string> liste, List<int> outliste)
{
string query ="select id from user where (";
foreach(string str in liste){
query += "name=" str + "or ";
}
query += " 1=0 )";
...................
// fill outliste by the result of the query
}
CREATE TYPE dbo.ListOfInt AS TABLE(Value INT);
var table = new DataTable();
table.Columns.Add("Value", typeof(int));
for (int i = 0; i < liste.Count; i++)
{
var row = table.NewRow();
row[0] = liste[i];
table.Rows.Add(row);
}
string sql = "SELECT ID FROM [User] WHERE ID IN (SELECT Value FROM @Liste)";
using (var connection = new SqlConnection("Your connection String"))
using (var command = new SqlCommand(sql, connection))
{
connection.Open();
var tvp = new SqlParameter("@Liste", SqlDbType.Structured).TypeName = "ListOfInt";
tvp.Value = table;
command.Parameters.Add(tvp);
using (var reader = command.ExecuteReader())
while (reader.Read())
{
outliste.Add(reader.GetInt("ID"));
}
}