Я пытаюсь вызвать хранимую процедуру (на сервере SQL 2005) из C #, .NET 2.0, используя DateTime
в качестве значения SqlParameter
. Тип SQL в хранимой процедуре - datetime.
Выполнение sproc из SQL Management Studio работает нормально. Но каждый раз, когда я звоню из C #, я получаю сообщение об ошибке в формате даты.
Когда я запускаю SQL Profiler для просмотра вызовов, я затем копирую и вставляю вызов exec
, чтобы посмотреть, что происходит. Вот мои наблюдения и заметки о том, что я пытался:
1) Если я передам DateTime
непосредственно как DateTime
или преобразую в SqlDateTime
, поле будет окружено парой одинарных кавычек, например
@Date_Of_Birth=N''1/8/2009 8:06:17 PM''
2) Если я передам DateTime
в виде строки, я получу только одинарные кавычки
3) Использование SqlDateTime.ToSqlString()
не приводит к строке даты и времени в формате UTC (даже после преобразования в универсальное время)
4) Использование DateTime.ToString()
не приводит к строке даты и времени в формате UTC.
5) Ручная установка DbType
для SqlParameter
на DateTime
не меняет вышеприведенные наблюдения.
Итак, мои вопросы: как же я могу заставить C # передавать правильно отформатированное время в SqlParameter
? Конечно, это распространенный случай, почему так трудно начать работать? Я не могу преобразовать DateTime
в строку, совместимую с SQL (например, '2009-01-08T08: 22: 45')
EDIT
RE: BFree, код для фактического выполнения sproc выглядит следующим образом:
using (SqlCommand sprocCommand = new SqlCommand(sprocName))
{
sprocCommand.Connection = transaction.Connection;
sprocCommand.Transaction = transaction;
sprocCommand.CommandType = System.Data.CommandType.StoredProcedure;
sprocCommand.Parameters.AddRange(parameters.ToArray());
sprocCommand.ExecuteNonQuery();
}
Более подробно о том, что я пробовал:
parameters.Add(new SqlParameter("@Date_Of_Birth", DOB));
parameters.Add(new SqlParameter("@Date_Of_Birth", DOB.ToUniversalTime()));
parameters.Add(new SqlParameter("@Date_Of_Birth",
DOB.ToUniversalTime().ToString()));
SqlParameter param = new SqlParameter("@Date_Of_Birth",
System.Data.SqlDbType.DateTime);
param.Value = DOB.ToUniversalTime();
parameters.Add(param);
SqlParameter param = new SqlParameter("@Date_Of_Birth",
SqlDbType.DateTime);
param.Value = new SqlDateTime(DOB.ToUniversalTime());
parameters.Add(param);
parameters.Add(new SqlParameter("@Date_Of_Birth",
new SqlDateTime(DOB.ToUniversalTime()).ToSqlString()));
Дополнительная редакция
Тот, который я думал, скорее всего, сработает:
SqlParameter param = new SqlParameter("@Date_Of_Birth",
System.Data.SqlDbType.DateTime);
param.Value = DOB;
Результат этого значения в вызове exec, как видно в SQL Profiler
@Date_Of_Birth=''2009-01-08 15:08:21:813''
Если я изменю это на:
@Date_Of_Birth='2009-01-08T15:08:21'
Работает, но не анализирует пару одинарных кавычек и не будет правильно преобразовывать в DateTime
с пробелом между датой и временем и миллисекундами в конце.
Обновление и успех
Я скопировал / вставил код выше после запроса снизу. Я обрезал вещи здесь и там, чтобы быть кратким. Оказывается, моя проблема была в коде, который я пропустил, и я уверен, что любой из вас мог бы его заметить в одно мгновение. Я завернул свои вызовы sproc внутри транзакции. Оказывается, я просто не делал transaction.Commit()
!!!!! Мне стыдно это говорить, но вот оно у тебя.
Я до сих пор не знаю, что происходит с синтаксисом, который я получаю от профилировщика. Сотрудник наблюдал со своим собственным экземпляром профилировщика со своего компьютера, и он вернул правильный синтаксис. Наблюдение за тем же самым исполнением от моего профилировщика показало неправильный синтаксис. Он действовал как «красная сельдь», заставляя меня поверить, что была проблема с синтаксисом запроса вместо гораздо более простого и верного ответа, а именно, что мне нужно было совершить транзакцию!
Я пометил приведенный ниже ответ как правильный и добавил некоторые положительные голоса за других, потому что они, в конце концов, ответили на вопрос, даже если они не устранили мою конкретную проблему (ошибка мозга).