【问题标题】:Executing an SQL statement in C#?在 C# 中执行 SQL 语句?
【发布时间】:2009-04-23 19:58:16
【问题描述】:

大家好,我想执行我的 SQL 语句,但我遇到了语法问题,有人可以帮我理解我做错了什么吗?

谢谢,阿什。

public void AddToDatabase(string[] WordArray, int Good, int Bad, int Remove)
{

    for (int WordCount = 0; WordCount < WordArray.Length; WordCount++)
    {
        string sSQL = "INSERT INTO WordDef (Word, Good, Bad, Remove) VALUES (" + WordArray[WordCount] + ", " + Good + ", " + Bad + ", " + Remove + ")";

        Debug.Print(sSQL);

        //Private m_recordset As ADODB.Recordset
        //Private m_connection As ADODB.Connection
        ADODB.Recordset RS;
        ADODB.Connection CN ;


        CN = new ADODB.Connection();
        RS = new ADODB.Recordset();

        CN.CursorLocation = ADODB.CursorLocationEnum.adUseClient;

        CN.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=doom_calc_dict.mdb;jet OLEDB:database";
        CN.Open(CN.ConnectionString,"","",0);

        object dummy = Type.Missing;

        CN.Execute(sSQL,out dummy,0);

        RS.Close(); 
        CN.Close(); 

        //string sSQL = "SELECT Word FROM WordDef WHERE Word='" + WordArray[WordCount] + "'";
        DatabaseTools.LoadDataFromDatabase(sSQL);
        //DatabaseTools.LoadDataFromDatabase(sSQL);

    }
}

【问题讨论】:

  • 你的 Debug.Print(sSql) 结果如何?如果您在 CN.Execute 中进行调试,您的代码在哪里中断?还是打开sql连接的时候?
  • 请注意,我更新了我的答案以使用 VS 2005/.Net2.0。它依赖于 VS2008 功能。

标签: c# sql execute


【解决方案1】:

您需要解决的最重要的事情是使用查询参数而不是动态构建字符串。这将提高性能、维护和安全性。

此外,您还想使用较新的强类型 ADO.Net 对象。确保为System.Data.OleDb 添加 using 指令。

注意这段代码中的using 语句。当您完成连接后,他们会确保您的连接已关闭。这很重要,因为数据库连接是一种有限且不受管理的资源。

最后,您并没有真正在代码中使用数组。您真正关心的是遍历单词集合的能力,因此您希望接受IEnumerable&lt;string&gt; 而不是数组。不用担心:如果您需要传递它,此函数将接受一个数组作为参数。

public void AddToDatabase(IEnumerable<string> Words, int Good, int Bad, int Remove)
{
    string sql = "INSERT INTO WordDef (Word, Good, Bad, Remove) VALUES (@Word, @Good, @Bad, @Remove)";

    using (OleDbConnection cn = new OleDbConnection("connection string here") )
    using (OleDbCommand cmd = new OleDbCommand(sql, cn))
    {
        cmd.Parameters.Add("@Word", OleDbType.VarChar);
        cmd.Parameters.Add("@Good", OleDbType.Integer).Value = Good;
        cmd.Parameters.Add("@Bad", OleDbType.Integer).Value = Bad;
        cmd.Parameters.Add("@Remove", OleDbType.Integer.Value = Remove;

        cn.Open();

        foreach (string word in Words)
        {
            cmd.Parameters[0].Value = word;
            cmd.ExecuteNonQuery();
        }
    }
}

还有一点:在 OleDb 中使用查询参数时,确保按顺序添加它们很重要。

更新:已修复,可在 VS 2005 / .Net 2.0 上运行(依赖于 VS 2008 功能)。

【讨论】:

  • 这是最好的方法,因为准备好的语句总是比动态生成查询更安全。如果绝对没有来自用户的信息,我将动态生成它们,这是唯一一次。
  • 这是一种更好的方法,但 Pascal 案例方法参数让我暂时四处寻找您所指的类级属性。
  • 除了将类型改为IEnumerable外,我使用了OP的方法签名。
  • 太棒了,谢谢!只是一个问题,我已经包含了新库的 using 语句,但是函数内部的 using(var 没有重新调整。我错过了什么吗?
  • 什么版本的visual studio/.Net?
【解决方案2】:

一开始我会觉得我没有提供帮助。但事实上,我正在努力帮助你,所以请这样吧。您需要阅读thisthis STAT!完成后,这里有一些好的、干净的ADO.NET examples

【讨论】:

    【解决方案3】:

    试试这个(你应该尝试从应用程序外部运行 SQL):

    string sSQL = "INSERT INTO WordDef (Word, Good, Bad, Remove) VALUES ('" + WordArray[WordCount] + "', " + Good + ", " + Bad + ", " + Remove + ");";
    

    【讨论】:

    • 不要只是将您的 SQL 语句连接在一起 - 这是一种非常糟糕的做法,并且会使您的应用程序容易受到 SQL 注入攻击。改用参数化查询!简单、快速、安全。
    • 我不会以这种方式编写我的应用程序,我确实为最终被接受的答案投票。不会改变查询的技术正确性,这就是问题所在。
    【解决方案4】:

    您需要在 SQL 语句中的第一个参数周围添加单引号。

    string sSQL = "INSERT INTO WordDef (Word, Good, Bad, Remove) VALUES ('" + WordArray[WordCount] + "', " + Good + ", " + Bad + ", " + Remove + ")";
    

    字符和日期字段要求值用“单引号”括起来

    【讨论】:

    • 不要只是将您的 SQL 语句连接在一起 - 这是一种非常糟糕的做法,并且会使您的应用程序容易受到 SQL 注入攻击。改用参数化查询!简单、快速、安全。
    • 是的,但问题不在于如何防止 sql 注入攻击。这就是我收到此错误的原因。
    【解决方案5】:

    不,你需要这样:

    string query = "INSERT INTO Table_PersonInfo
    (PersonID,Surname
    ,[Family Name]
    ,AddsOnName
    ,Street,Number
    ,PostalCode
    ,[City of Birth]
    ,[Year of Birth]
    ,[Phone Number])
     VALUES
     ('"+@personID+"'
    , '"+ @surname + "' 
    , '"+@familyname+"'
    , '"+@nameExtension+"'
    , '"+@street+"'
    , '"+@houseNumber+"'
    , '"+ @postalCode+"'
    , '"+@yearofbirth+"'
    , '"+@placeofbirth+"'
    , '"+@phoneNumber+"')";
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多