【问题标题】:How to insert null values to a Uniqueidentifier Column如何将空值插入到唯一标识符列
【发布时间】:2013-06-04 06:53:35
【问题描述】:

在我的 C# 项目中,我需要在 UniqueIdentifier 列中插入一些空值。

对于城市 Guid、州 Guid 字段我应该能够插入空值 如果没有可用的值(唯一标识符)。 我收到以下错误

“从字符串转换为唯一标识符时转换失败。”

这是我的代码。

   string Query = @"INSERT INTO mytable
                            (table_GUID,
                            Date,
                            city_GUID,
                            state_GUID,                            
                            ) 

                        VALUES
                        ('" + tableGUID + @"', 
                        '" + Date + @"',  
                        '" + cityGUID + @"',
                        '" + stateGUID + @"'
                    )                       

 string insert = sql.executeNonQuery(Query);

【问题讨论】:

标签: c# .net


【解决方案1】:

您不应提供这样的值。创建一个 SqlCommand 并将值作为参数提供。要插入空值,请使用DBNull.Value

    var command = new SqlCommand(
        @"INSERT INTO mytable (table_GUID, Date, city_GUID, state_GUID)                      
          VALUES (@TableGuid, @Date, @CityGuid, @StateGuid)", sqlConnection);
    command.Parameters.AddWithValue("TableGuid", tableGUID ?? DBNull.Value);
    command.Parameters.AddWithValue("Date", Date);
    command.Parameters.AddWithValue("CityGuid", cityGUID ?? DBNull.Value);
    command.Parameters.AddWithValue("StateGuid", stateGUID ?? DBNull.Value);
    command.ExecuteNonQuery();

另一种方法是提供 NULL 作为值。见how do you insert null values into sql server

您还可以定义一个辅助函数来返回用引号括起来的值或 NULL 字符串。

private string GetQuotedParameterThing(Guid? value)
{
    return value == null ? "NULL" : "\"+ value + \"";
}

然后只需将GetQuotedParameterThing(tableGUID) 提供给您的命令字符串。

【讨论】:

  • 问题是这些并不总是空的。如果没有值,那么我应该插入 null。如果有一个值,那么我应该用单引号插入 Guid。如何在上述方法中插入不带单引号的 null?单引号引起了这里的问题
  • 查看我的编辑。如果参数为 null,您可以使用 null-coalescing 运算符提供 DBNull.Value。
  • 感谢您的回复,但我无法访问 sqlCommand。 sqlCommand 在另一个类中。您能以我使用的格式显示您的示例吗?感谢您的帮助
  • @Henry 你应该使用SqlCommand,否则你很容易被sql注入。简而言之,您正在编写糟糕的代码。不要这样做。如果您无权访问它,则需要访问它。重构代码。就这么简单。
  • "那么我应该用单引号插入 Guid" - 不,你不应该。 uniqueidentifiers 不是字符串 - 将它们视为字符串可能是这里问题的很大一部分。 Malvin 建议将它们作为 ADO.NET 参数传递是完全正确的 - 并且 ADO.NET 参数可以通过 DBNull.Value 表达 null
【解决方案2】:

已存在一个答案,显示如何使用 ADO.NET 参数执行此操作,这是此问题的完全正确答案。如果必须使用原始 TSQL,则需要区分空值/非空值;非空值需要引号,但空值需要作为null 发送 - 没有引号。 null 是一个完全有效的可空唯一标识符 - 但 'null' 不是

但是,在您的示例中,我怀疑真正的技巧是将您的 sql.executeNonQuery 方法更改为 接受参数。如果您不这样做:那么我向您保证,您当前的系统从根本上损坏了。现在。有危险。一个问题。有风险。

但这很容易解决;在你的情况下,可笑很容易;例如,这可能是:

const string Query = @"
INSERT INTO mytable (table_GUID, Date, city_GUID, state_GUID) 
VALUES (@tableGUID, @Date, @cityGUID, @stateGUID)";

string insert = sql.executeNonQuery(
    Query, new { tableGUID, Date, cityGUID, stateGUID });
              ^^^ hot damn! who knew parameterization could be that easy!?

如果您只是简单地将现有的 executeNonQuery 方法设置为:

void executeNonQuery(string query, object args = null) {
    //... not shown: your code that gets a connection
    connection.Execute(query, args);
    //... not shown: your code that cleans up
}

只需添加对dapper 的引用;简单地说,dapper 使正确的参数化变得轻而易举;上述更改可以在不影响任何现有代码的情况下进行,除非允许将来对其进行参数化。

【讨论】:

    【解决方案3】:

    我认为问题可能在于您的代码允许“空字符串”通过。也许你可以检查 string.Empty 然后传入 Guid.Empty 或 NULL 代替。

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 2021-03-29
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 2012-06-23
      相关资源
      最近更新 更多