Почему CONVERT () позволяет мне использовать параметризованный запрос в этом случае? - PullRequest
3 голосов
/ 28 февраля 2012

При разработке приложения для Windows Mobile мы использовали следующий код:

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)

Почему мне не разрешено использовать "голые" параметры?

Почему в первую очередь выдается ошибка при преобразовании, а не при использовании параметра?

1 Ответ

3 голосов
/ 28 февраля 2012

Метод 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 для полного сценария воспроизведения

...