从文件读取时从字符串转换日期和/或时间时转换失败

时间:2014-06-27 19:53:06

标签: c# sql-server

我知道这个问题已经以不同的形式发布在stackoverflow上,但我没有设法解决我的问题。我试图插入从文本文件中读取的SQL Server数据库数据。我已经将以前的数据插入到数据库中,格式为' 2014-02-02'所以我不认为它来自这里。我的文本文件如下所示:

1213 3 2013-01-03 2013-03-03
1263 2 2014-01-01 2014-01-10

我的代码是:

        private void importComandăToolStripMenuItem_Click(object sender, EventArgs e)
         {
            string cale = Application.StartupPath;
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                cale = ofd.FileName;
                System.IO.StreamReader sr = new System.IO.StreamReader(cale);
                string linie = null;
                while ((linie = sr.ReadLine()) != null)
                {
                        string comanda = sr.ReadLine();
                        string[] vcmd = comanda.Split(' ');

                        foreach (string cmd in vcmd)
                        {
                             SqlConnection conn = new SqlConnection("server=localhost;" +
    "Trusted_Connection=yes;" +
    "database=erp; " +
    "connection timeout=30");
                SqlCommand cmd1 = new SqlCommand();
                cmd1.CommandText = "Insert into [erp].[dbo].[Comenzi] values("+Int32.Parse(cmd[0].ToString())+","+Int32.Parse(cmd[1].ToString())+",'"+cmd[2].ToString()+"','"+cmd[3].ToString()+"');";
                cmd1.CommandType = CommandType.Text;
                cmd1.Connection = conn;
                conn.Open();
                cmd1.ExecuteNonQuery();
                conn.Close();

                        }

                    }
                MessageBox.Show("Comanda inserată");

                }

            else
                MessageBox.Show("Inserare eșuată");
            }
        }

有什么建议吗?

4 个答案:

答案 0 :(得分:1)

第一个问题是文件中的两个日期。如果它们以您的区域设置接受的格式表示,那么转换就足够了。但是,尝试更新数据库的代码有很多错误。

我试图修复它们。

  • 首先。使用using语句正确关闭连接时 你做完了
  • 二。使用参数化查询将数据传递到数据库。 字符串连接容易出错,因为解析错误并且打开 sql注入黑客。
  • 第三。在进入循环之前打开连接并创建 该命令及其参数带有一些虚拟值。在 - 的里面 循环将参数的值更改为实际值和 执行查询
  • 四。分裂字符串会产生一个数组,你需要 使用数组的四个元素不是不可能的元素 cmd单字符串变量
  • 第五。您为每个循环读取了两次该行。除非你有 空行每行数据然后你应该删除ReadLine 在循环中

 private void importComandăToolStripMenuItem_Click(object sender, EventArgs e)
 {
    string cale = Application.StartupPath;
    OpenFileDialog ofd = new OpenFileDialog();
    if (ofd.ShowDialog() == DialogResult.OK)
    {
        cale = ofd.FileName;
        System.IO.StreamReader sr = new System.IO.StreamReader(cale);
        using(SqlConnection conn = new SqlConnection("server=localhost;" +
                                 "Trusted_Connection=yes;" +
                                 "database=erp; " +
                                 "connection timeout=30"))
        using(SqlCommand cmd1 = new SqlCommand(@"Insert into [erp].[dbo].[Comenzi] values 
                                                @p1, @p2, @p3, @p4", conn)
        {
            conn.Open();
            cmd1.Parameters.AddWithValue("@p1", 0);
            cmd1.Parameters.AddWithValue("@p2", 0);
            cmd1.Parameters.AddWithValue("@p3", DateTime.MinValue);
            cmd1.Parameters.AddWithValue("@p4", DateTime.MinValue);
            string comanda = null;
            while ((comanda = sr.ReadLine()) != null)
            {
                string[] vcmd = comanda.Split(' ');
                cmd1.Parameters["@p1"].Value = Convert.ToInt32(vcmd[0]));
                cmd1.Parameters["@p2"].Value = Convert.ToInt32(vcmd[1]));
                cmd1.Parameters["@p3"].Value = Convert.ToDateTime(vcmd[2]));
                cmd1.Parameters["@p4"].Value = Convert.ToDateTime(vcmd[3]));
                cmd1.ExecuteNonQuery();
            }
        }
    }
}

答案 1 :(得分:0)

删除foreach。

private void importComandaToolStripMenuItem_Click(object sender, EventArgs e)
         {
            string cale = Application.StartupPath;
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                cale = ofd.FileName;
                System.IO.StreamReader sr = new System.IO.StreamReader(cale);
                string linie = null;
                while ((linie = sr.ReadLine()) != null)
                {
                        string comanda = sr.ReadLine();
                        string[] vcmd = comanda.Split(' ');

                        //foreach (string cmd in vcmd)
                        //{
                             SqlConnection conn = new SqlConnection("server=localhost;" +
    "Trusted_Connection=yes;" +
    "database=erp; " +
    "connection timeout=30");
                SqlCommand cmd1 = new SqlCommand();
                cmd1.CommandText = "Insert into [erp].[dbo].[Comenzi] values("+vcmd[0]+","+vcmd[1]+",'"+vcmd[2]+"','"+vcmd[3]+"');";
                cmd1.CommandType = CommandType.Text;
                cmd1.Connection = conn;
                conn.Open();
                cmd1.ExecuteNonQuery();
                conn.Close();

                        //}

                    }
                MessageBox.Show("Comanda inserata");

                }

            else
                MessageBox.Show("Inserare e?uata");
            }
        }

答案 2 :(得分:0)

如果cmd是一个字符串,cmd [0]将为您提供字符串中的第一个字符。我不认为这就是你想要的。你可能意味着vcmd [0],这意味着你不需要循环。

答案 3 :(得分:0)

史蒂夫的回答清楚地解释了代码中存在的所有问题。

执行此操作时:

 string[] vcmd = comanda.Split(' ');

你得到的行数就像string[] array

一样
 string[] vcmd = {"1213", "3", "2013-01-03", "2013-03-03" };

string[]下面的循环将为您提供cmd变量中的每个字符串:

 foreach (string cmd in vcmd)
 {
     //here cmd values on each iteration

     // first iteration = "1213"
     // second iteration = "3"
     // third iteration = "2013-01-03"
     // fourth iteration = "2013-03-03"
  }

更好的方法可以

  1. 一次性阅读所有文件行。
  2. 在方法开头创建SqlConnection
  3. 使用SqlCommand Parameters
  4. 使用using声明。
  5. 示例(未经测试)

    private void importComandăToolStripMenuItem_Click(object sender, EventArgs e)
    {
       string connstring = @"server=localhost; 
                             Trusted_Connection=yes; 
                             database=erp; connection timeout=30";
    
       string cale = GetFileName();
    
       if(cale != string.Empty)
       {
          IEnumerable<string> arrLines = File.ReadLines(cale);
          string sql = @"Insert into [erp].[dbo].[Comenzi] values 
                                                (@P1, @P2, @P3, @P4)";
          using (SqlConnection conn = new SqlConnection(connstring))
          {
              conn.Open();
              using (SqlCommand cmd = new SqlCommand(sql, conn))
              {
                  cmd.Parameters.AddWithValue("@P1", 0);
                  cmd.Parameters.AddWithValue("@P2", 0);
                  cmd.Parameters.AddWithValue("@P3", DateTime.MinValue);
                  cmd.Parameters.AddWithValue("@P4", DateTime.MinValue);
    
                  foreach (string sLine in arrLines)
                  {
                     string[] vcmd = sLine.Split(' ');
                     cmd.Parameters["@P1"].Value = Convert.ToInt32(vcmd[0]);
                     cmd.Parameters["@P2"].Value = Convert.ToInt32(vcmd[1]);
                     cmd.Parameters["@P3"].Value = Convert.ToDateTime(vcmd[2]);
                     cmd.Parameters["@P4"].Value = Convert.ToDateTime(vcmd[3]);
                     cmd.ExecuteNonQuery();
                  }
              }
           }
           //check can be added based on int returned by ExecuteNonQuery
           MessageBox.Show("Comanda inserată");
        }                
    }
    
    //method to show open file dialog return filename or empty
    private string GetFileName()
    {
        OpenFileDialog ofd = new OpenFileDialog();
    
        if (ofd.ShowDialog() == DialogResult.OK)
             return ofd.FileName;
        else
        {
             MessageBox.Show("Inserare eșuată");
             return string.Empty;
         }
    }