【问题标题】:Why does CONVERT() allow me to use parameterized query in this case?为什么 CONVERT() 在这种情况下允许我使用参数化查询?
【发布时间】:2012-02-28 12:36:08
【问题描述】:

在开发 Windows 移动应用程序期间,我们使用了以下代码:

const string sqlString2 = 
   @"INSERT INTO WorkOrderComment
   (WOInstructionID,WorkOrderCommentID,ClientChange,Void,UserID,VoidTimestamp) 
   (SELECT WOInstructionID, WOInstructionID, 1, @VoidBit,@VoidUser ,@VoidTimeStamp 
    FROM WorkOrderInstruction 
    WHERE InstructionGroupQuestion = 0 AND InstructionGroupNumber = @insGroupNo AND WorkOrderID=@WoID)";
var sqlcom2 = new SqlCeCommand();
sqlcom2.CommandType = CommandType.Text;
sqlcom2.CommandText = sqlString2;
sqlcom2.Parameters.Add("@VoidBit", action);

sqlcom2.Parameters.Add("@VoidUser", DBNull.Value);
sqlcom2.Parameters.Add("@VoidTimeStamp", DBNull.Value);

sqlcom2.Parameters.Add("@WoID", workOrderID);
sqlcom2.Parameters.Add("@insGroupNo", instructionGroupNumber);
sqlcom2.ExecuteNonQuery();

在运行此程序时,我在 ExecuteNonQuery 上收到以下错误: 不支持转换。 [要转换的类型(如果知道)= int,要转换的类型(如果知道)= uniqueidentifier ]

即使我添加sqlcom2.Parameters["@VoidUser"].DbType = DbType.Guid;,我也会遇到同样的错误。过了一会儿,我发现使用CONVERT 可以帮助解决这个问题。 我将@VoidUser 更改为CONVERT(uniqueidentifier,@VoidUser)

这导致了以下错误:A parameter is not allowed in this location. Ensure that the '@' sign is in a valid location or that parameters are valid at all in this SQL statement.

在阅读了几个小时的文档和其他关于为什么我不能在这些地方使用变量的帖子之后,我只是尝试在任何地方输入CONVERT;将@VoidBit 更改为CONVERT(bit,@VoidBit)@VoidTimeStamp 更改为CONVERT(datetime,@VoidTimeStamp)

而且由于某种原因它起作用了。

使用以下命令创建表:

CREATE TABLE WorkOrderComment (  WorkOrderCommentID uniqueidentifier NOT NULL CONSTRAINT WorkOrderCommentPK Primary Key,
WOInstructionID uniqueidentifier NOT NULL,
WorkOrderID_Update uniqueidentifier NULL,
TextData NTEXT NULL,
Value float NULL,
Category nvarchar(50) NULL,
BarcodeScanned bit NULL,
Timestamp DateTime NULL,
Time float NULL,
UserID uniqueidentifier NULL,
Void bit NULL,
VoidTimeStamp DateTime NULL,
FaultComplaintID uniqueidentifier NULL,
ClientChange bit NOT NULL)

为什么我不允许使用“裸”参数?

为什么它首先在转换时抛出错误,而不是参数的使用?

【问题讨论】:

  • WorkOrderComment中字段的数据类型是什么
  • @FilipDeVos 添加了使用的方案/创建命令。

标签: c# sql-server-ce parameterized


【解决方案1】:

Parameters.Add() 方法采用 2 个参数:参数名称和数据类型。看来您对Parameters.AddWithValue() 感到困惑

此外,SQLCE 的类型转换似乎比 SQL Server 更难。所以最好是你特别提到参数的类型。 (它只对 uniqueidentifier 很重要)

我也会像这样稍微重写代码:

        using (var sqlConn = new SqlCeConnection(connStr))
        using (var sqlCmd = new SqlCeCommand(sqlString2, sqlConn))
        {
            sqlConn.Open();

            sqlCmd.Parameters.Add("@VoidBit", SqlDbType.Bit).Value = action;
            sqlCmd.Parameters.Add("@VoidUser", SqlDbType.UniqueIdentifier).Value = DBNull.Value;
            sqlCmd.Parameters.Add("@VoidTimeStamp", SqlDbType.DateTime).Value = DBNull.Value;
            sqlCmd.Parameters.Add("@WoID", SqlDbType.UniqueIdentifier).Value = workOrderID;
            sqlCmd.Parameters.Add("@insGroupNo", SqlDbType.Int).Value = instructionGroupNumber;

            sqlCmd.ExecuteNonQuery();
        }

请参阅https://gist.github.com/1932722 以获取完整的复制脚本

【讨论】:

  • SqlParameterCollection.Add 有两个函数重载,需要 2 个参数。一个带类型,一个带值。我正在调用具有价值的人:Parameters.Add(String, Object).
  • 刚刚注意到Parameters.Add(String, Object) 已过时,感谢您的提示!尝试使用Parameters.AddWithValue(String, Object) 并删除了@VoidBit@VoidTimeStamp 周围的CONVERT。报同样的错误:A parameter is not allowed in this location. Ensure that the '@' sign is in a valid location or that parameters are valid at all in this SQL statement..
  • 太棒了!稍后我将尝试设置一个更简单的示例。
  • 我猜到了 WoID 和 insGroupNo 字段的数据类型。在需要的地方进行调整。
  • 你猜对了!我会在下午检查这个并相应地标记答案。
猜你喜欢
  • 1970-01-01
  • 2021-12-02
  • 2014-09-18
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 2016-03-07
相关资源
最近更新 更多