繁体   English   中英

索引超出了数组异常的范围

[英]Index was outside the bounds of the array exception

这是我的代码,用于从平面文件获取数据并将其插入SQL Server。 它正在生成一个异常( Index was outside the bounds of the array )。

string path = string.Concat(Server.MapPath("~/TempFiles/"), Fileupload1.FileName);                       
string text = System.IO.File.ReadAllText(path);               
string[] lines = text.Split(' ');                                  
con.Open();                 
SqlCommand cmd = new SqlCommand();                 
string[] Values = new string[3];                                 
foreach (string line1 in lines)                 
{                     
    Values = line1.Split(';');                                           
    string query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')";                     
    cmd = new SqlCommand(query,con);                     
    cmd.ExecuteNonQuery();                  
} 

发生这种情况是因为您的一行中有少于三个用分号分隔的元素 即使您将Values声明String.Split()三个元素组成的String数组,将变量影响到String.Split()函数的结果也会使这一点无关紧要:您的数组将具有返回数组具有的任何长度。 如果更少,您的代码肯定会失败。

如果不希望发生这种情况,建议您在代码中做一个断言以帮助您调试:

// ...
Values = line1.Split(';');
// the following will make the debugger stop execution if line.Length is smaller than 3
Debug.Assert(line1.Length >= 3);
// ...

附带说明一下,我应该提到进行批处理INSERT会更加有效。 另外,您声明和重新影响cmd变量的方法也不是正确的。 最后,您应该在值上调用String.Replace ,以确保所有的撇号都加倍。 否则,您的代码将对SQL注入攻击开放。

有关代码在运行时的行为的一些详细信息:

// This line declares a variable named Values and sets its value to 
// a new array of strings. However, this new array is never used 
// because the loop overwrites Values with a new array before doing 
// anything else with it.
string[] Values = new string[3];                                 
foreach (string line1 in lines)                 
{                     
    Values = line1.Split(';');        
// At this point in the code, whatever was previously stored in Values has been
// tossed on the garbage heap, and Values now contains a brand new array containing
// the results of splitting line1 on semicolons.
// That means that it is no longer safe to assume how many elements the Values array has.
// For example, if line1 is blank (which often happens at the end of a text file), then
// Values will be an empty array, and trying to get anything out of it will throw an
// exception                                   
    string query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')";                     
    cmd = new SqlCommand(query,con);                     
    cmd.ExecuteNonQuery();                  
} 

与Values不断被覆盖的方式类似,在循环外部创建的SqlCommand也将永远不会被使用。 将这两个声明放入循环内是安全的。 下面的代码可以做到这一点,并且还添加了一些错误检查,以确保从该行中检索了可用数量的值。 它只会跳过任何时间不够长的行-如果那行不行,那么您可能需要创建自己的一些更复杂的错误处理代码。

foreach(string line in lines) 
{
    string[] values = line.split[';'];
    if(values.Length >= 3)
    {
        string query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')";      
        using (SqlCommand command = new SqlCommand(query, con))
        {
            cmd.ExecuteNonQuery();
        }
    }
}

最后一点,如果您在Web应用程序中使用上述代码,那么这些代码可能容易受到黑客的攻击。 考虑一下如果正在处理如下所示的文件,则可能会向服务器发送什么命令:

1;2;3
4;5;6
7;8;9') DROP TABLE demooo SELECT DATALENGTH('1    

一个更安全的选择是使用参数化查询,这将有助于防止此类攻击。 他们通过将命令与其参数分开来实现此目的,这有助于保护您避免传递类似SQL代码的参数值。 如何以这种方式进行设置的示例看起来像这样:

string query = "INSERT INTO demooo VALUES (@val1, @val2, @val3);
using (var command = new SqlCommand(query, con))
{
    command.Parameters.AddWithValue("@val1", Values[0]);
    command.Parameters.AddWithValue("@val2", Values[1]);
    command.Parameters.AddWithValue("@val3", Values[2]);
    command.ExecuteNonQuery();
}

尝试这个。

string path = string.Concat(Server.MapPath("~/TempFiles/"), Fileupload1.FileName);
string text = System.IO.File.ReadAllText(path);
string[] lines = text.Split(' ');
con.Open();
string[] Values;
foreach (string line1 in lines)
{
    Values = line1.Split(';');

    if (Values.Length >= 3)
    {
        string query = "INSERT INTO demooo VALUES ('" + Values[0] + "','" + Values[1] + "','" + Values[2] + "')";
    }
    else
    {
      //Some error occured
    }

    using (var cmd = new SqlCommand(query,con))
    {
        cmd.ExecuteNonQuery();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM