【问题标题】:C# checking if record exists in SQL errorC#检查SQL错误中是否存在记录
【发布时间】:2011-07-14 14:02:56
【问题描述】:

我正在使用此代码检查“guid”表中是否已存在值 (guid1):

string selectString = "SELECT guid" + "FROM trafficScotland" + "WHERE guid = " + guid1;

SqlCommand myCommand = new SqlCommand(selectString, myConnection);
String strResult = String.Empty;
strResult = (String)myCommand.ExecuteScalar();

 if (strResult.Length == 0)

但是在

 strResult = (String)myCommand.ExecuteScalar();

行,我得到 sqlException 错误

“guid”附近的语法不正确

请告诉我这里出了什么问题?

【问题讨论】:

    标签: c# sql .net


    【解决方案1】:
    "SELECT guid" + "FROM trafficScotland" + "WHERE guid ="
    

    那是:

    SELECT guidFROM trafficScotlandWHERE guid =
    

    无论如何,将其分解为单独的字符串是没有意义的,但是您在单词之间缺少空格:)

    string resultGuidAsString = null;
    
    // build command object
    string cmdQuery = "SELECT guid FROM trafficScotland WHERE guid=@guid";
    SqlCommand myCmd = new SqlCommand(cmdQuery, myConnection);
    
    // safely pass in GUID parameter value
    myCmd.Parameters.AddWithValue("@guid", guid1);
    
    // read result, check for nulls in DB
    object result = myCmd.ExecuteScalar();
    if (result != DBNull.Value && result != null)
    {
        resultGuidAsString = result.ToString();
    }
    

    ^^ 这是一个改进的版本。如果可以,请提出几点批评:

    • 您的查询没有使用任何参数:仅构建一个字符串。安全性、可读性和可维护性风险
    • 大概您正在检查是否有带有该 guid 的条目,暗示可能没有,但您没有检查 DBNull.Value 以防万一
    • 有点混乱 - 您返回的是 string,但处理的是 Guids。奇怪。

    【讨论】:

    • 不仅“没有意义”,而且还强制连接,减慢例程,因为字符串是不可变的。 ;-)
    • 完全正确,另外您可能需要考虑使用参数化查询来防止 sql 注入。
    • @Gregory:将字符串文字与+ 连接不会不会减慢例程的速度。 C# 编译器将在编译时进行连接。因此,您可以在源代码中使用+ 将长字符串文字拆分为多行。
    • @Stephan:感谢您的指正。我想是时候去喝杯咖啡了。 :-0
    • @Kieren 您的示例帮助我 immensley 学习了有关如何识别 SQL 记录是否不存在以便代码可以适当地处理这种情况的 C# 最佳实践。谢谢!
    【解决方案2】:

    改为这样做:

    var selectString = "SELECT 1 FROM trafficScotland WHERE guid = @guid"
    var myCommand = new SqlCommand(selectString, myConnection);
    myCommand.Parameters.AddWithValue("@guid", guid1);
    
    var itExists = (Int32)myCommand.ExecuteScalar() > 0;
    if (itExists) {
        // do stuff...
    }
    

    【讨论】:

      【解决方案3】:

      selectString = "SELECT guid " + "FROM trafficScotland" + " WHERE guid = '" + guid1 +"'";

      guid 后面的注意空格

      【讨论】:

      • -1 同样,您永远不应该以这种方式将参数传递给查询。只是没有充分的理由
      • 这很容易发生SQL注入。我更喜欢其他答案中提出的具有参数的解决方案。
      【解决方案4】:

      每个人都告诉你问题是什么。是的,你的查询不正确。但是你未来的查询呢?你想看看他们是否正确?

      我强烈建议您使用 SQL Server Profiler。 Profiler 位于您的应用程序和数据库引擎之间,并掌握传递给数据库引擎的每个命令和查询。因此,您可以查看传递给 SQL Server 的内容,抓取它,然后尝试在 SQL Server Management Studio 中执行它以对其进行调试。

      【讨论】:

        【解决方案5】:

        理想情况下,您应该使用参数来防止 SQL 注入。他们还将处理诸如引用需要引用的值(如 GUID)之类的事情:

        var selectString =  "SELECT guid FROM trafficScotland WHERE guid = @guid";
        var myCommand = new SqlCommand(selectString, myConnection);
        myCommand.Parameters.AddWithValue("@guid", guid1);
        strResult = (String)myCommand.ExecuteScalar();
        

        【讨论】:

          【解决方案6】:

          首先你必须修正你的间距,你将查询的一部分连接在一起,你在重要的 sql server 关键字之间缺少空格。

          SELECT guidFROM trafficScotlandWHERE guid

          其次,您应该使用命名参数。这将有助于避免 sql 注入,并让您不必考虑是否需要单引号围绕您的 sql 变量。

          var query = "SELECT guid FROM trafficScotland WHERE guid = @guid";
          using(var command = new SqlCommand(query, connection))
          {
              command.Parameters.AddWithValue("@guid", guid1);
          
              var result = command.ExecuteScalar();
          
              // Compare guid1 to result
          }
          

          【讨论】:

            【解决方案7】:

            正如所写,因为您忘记了一些空格,所以您正在运行以下查询

            SELECT guidFROM trafficScotlandWHERE guid = {guid here}
            

            适当的间距是首先要解决的问题。

            【讨论】:

              【解决方案8】:

              试试这个:

              string selectString = "SELECT guid FROM trafficScotland WHERE guid = '" + guid1 + "'";
              

              【讨论】:

              • 感谢您的 -1!我认为这个解决方案并不完美但没有错!你不知道他是否使用 Guid.Parse 来检查 sql 注入!
              • 我的个人政策是让任何存在安全风险的选项和不良/懒惰的编程实践得分较低。仅仅因为它是最简单、最懒惰的路线并不意味着它是“正确的”。这是我书中的错误答案
              • 你打算只对我的答案投反对票吗?在这个主题中还有其他树答案,比如我的,为什么不投反对票呢?我不想点燃火焰,但你的表演对我来说听起来很奇怪!
              【解决方案9】:

              正如其他人提到的那样,空格 + 用“'”括住 guid。您还应该将GUIDs 存储为UNIQUEIDENTIFIERs(假设为MSSQL)

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-04-02
                • 1970-01-01
                • 1970-01-01
                • 2011-02-20
                相关资源
                最近更新 更多