【问题标题】:How can I resolve this error an c#如何解决这个错误 c#
【发布时间】:2012-12-12 09:02:08
【问题描述】:

我想往数据库表中插入数据:

myCommand.CommandText = "INSERT INTO Selectionner (IdPrestation,
   IdPhrase, DegreUrgence,RisqueConcerne,rowguid,Cotation) " +                                                               
   "VALUES   ('" +new Guid(emp.IdPrestation) + 
   "', '" +new Guid(emp.IdPhrase)+ "', '" +
   emp.DegreUrgence + "','" + emp.RisqueConcerne + "','" + 
   new Guid(emp.rowguid) + "','" + emp.Cotation + "')";

但这会返回错误:

Guid 应包含 32 位数字和 4 个破折号
(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。

我该如何解决这个错误?

【问题讨论】:

  • 不要连接 sql 字符串,而是使用参数来避免 sql 注入和解析错误。我们需要以下变量的值来回答您的问题:emp.IdPrestation,emp.IdPhrase,emp.rowguid。您正在使用它们来初始化 GUIDs,它必须包含 32 位数字和 4 个破折号(错误是不言自明的,不是吗?)。
  • 您能否给出一些 emp.IdPrestation、emp.IdPhrase 和 emp.rowguid 的示例值?

标签: c# sql sql-server sql-server-2008


【解决方案1】:

你的一个或多个

emp.IdPrestation //Or 
emp.IdPhrase //Or 
emp.rowguid //Check them before creating 

是/不是GUID这就是它抛出错误的原因。

编辑:开始

如何使用Guid.TryParse(),如果解析成功则返回true;否则为假。

//How to parse safely
Guid IdPrestation;
Guid IdPhrase;
Guid rowguid;

if(Guid.TryParse(emp.IdPrestation, out IdPrestation) &&
   Guid.TryParse(emp.IdPhrase, out IdPhrase) &&
   Guid.TryParse(emp.rowguid, out rowguid) )
{
   //all variables have been parse successfully
   //Execute the sql query as follows using parameters
}

编辑:结束

此外,使用内联 sql 将参数作为直接字符串传递是 unsafe bad practice。而是use a parameterised query

myCommand.CommandText = "INSERT INTO yourTableName (c1, c2, ...)
VALUES (@p1, @p2,...)";
myCommand.Parameters.Add(new SqlParameter("p1", valueforCol1));
myCommand.Parameters.Add(new SqlParameter("p2", valueforCol2));
...

【讨论】:

    【解决方案2】:

    尝试使用参数化查询作为第一个改进。

    然后,尝试使用Guid.Parse(string s) 而不是new Guid(string s)。这样一来,我希望对于不合规的字符串会引发异常。

    构造函数可能有点宽松,在这种情况下,您可能希望快速失败,以便知道哪个字段给您带来麻烦。

    【讨论】:

    • 但是,错误是由于解析无法完成吗?还是 Parse 成功但实际的 Insert 正在生成异常?
    • 是的,是的。我从其他数据库 sqlite 中恢复数据,其中 IdPrestation 的类型不是 Guid 而是 int。现在我正在寻找如何在 sqlite 数据库 Guid 上插入
    • sqlite 不支持 GUID,你可以做的是作为字符串插入并在你的数据层中公开一个属性 guid,它会自动处理 get 和 set 的转换。
    【解决方案3】:

    您不能简单地从字符串创建 GUID,该字符串需要符合 guid

    Guid originalGuid = Guid.NewGuid();
    originalGuid.ToString("B")  gets converted to {81a130d2-502f-4cf1-a376-63edeb000e9f}
    

    同样

    "N" - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (32 digits)
    "D" - xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (32 digits separated by hyphens)
    "B" - {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} (same as "D" with addition of braces)
    "P" - (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) (same as "D" with addition of parentheses)
    "X" - {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00.0x00}}
    

    guid 本身没有格式。它只是一个值。请注意,您可以使用 NewGuid 或使用 guid 的构造函数创建 guid。使用 NewGuid,您无法控制 guid 的值。使用 guid 的构造函数,您可以控制该值。如果您已经有一个 guid 的字符串表示形式(也许您从数据库中读取它),或者如果您希望在开发过程中更容易解释一个 guid,那么使用构造函数很有用。您还可以使用ParseParseExactTryParseTryParseExact 方法。

    因此,您可以像这样创建 guid:

    Guid g1 = Guid.NewGuid(); //Get a Guid without any control over the contents
    Guid g2 = new Guid(new string('A',32)); //Get a Guid where all digits == 'A'
    Guid g3 = Guid.Parse(g1.ToString());
    Guid g4 = Guid.ParseExact(g1.ToString("D"),"D");
    Guid g5;
    bool b1 = Guid.TryParse(g1.ToString(), out g5);
    Guid g6;
    bool b2 = Guid.TryParseExact(g1.ToString("D"),"D", out g6);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      相关资源
      最近更新 更多