Я пытаюсь вызвать хранимую процедуру (на сервере SQL 2005) из С#,.NET 2.0, используя DateTime
как значение для SqlParameter
. Тип SQL в хранимой процедуре - это "datetime".
Выполнение sproc из SQL Management Studio отлично работает. Но каждый раз, когда я вызываю его из С#, я получаю сообщение об ошибке формата даты.
Когда я запускаю SQL Profiler для просмотра вызовов, я затем копирую вставьте вызов exec
, чтобы узнать, что происходит. Это мои наблюдения и заметки о том, что я пытался:
1) Если я передаю DateTime
непосредственно как DateTime
или преобразован в SqlDateTime
, поле окружает PAIR одинарных кавычек, например
@Date_Of_Birth=N''1/8/2009 8:06:17 PM''
2) Если я передаю DateTime
в качестве строки, я получаю только одиночные кавычки
3) Использование SqlDateTime.ToSqlString()
не приводит к форматированной в формате UTC строке даты (даже после преобразования в универсальное время)
4) Использование DateTime.ToString()
не приводит к строкой datetime в формате UTC.
5) Ввод вручную DbType
для SqlParameter
в DateTime
не изменит приведенные выше наблюдения.
Итак, теперь мои вопросы: каким образом я получаю С#, чтобы передать правильно отформатированное время в SqlParameter
? Конечно, это распространенный случай использования, почему так сложно работать? Я не могу преобразовать DateTime
в строку, совместимую с SQL (например, "2009-01-08T08: 22: 45 ')
ИЗМЕНИТЬ
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()));
Дополнительный EDIT
Тот, который, как я думал, скорее всего будет работать:
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
с промежутком между датой и временем и с миллисекундами в конце.
Обновление и успех
У меня был экземпляр/вставил код выше после запроса снизу. Я урезал вещи здесь и там, чтобы быть кратким. Оказывается, моя проблема была в коде, который я забыл, и я уверен, что кто-то из вас заметил бы в одно мгновение. Я заключил свои звонки в транзакции. Оказывается, я просто не делал transaction.Commit()
!!!!! Мне стыдно это сказать, но там у вас есть.
Я до сих пор не знаю, что происходит с синтаксисом, который я получаю от профилировщика. Сотрудник наблюдал со своим экземпляром профилировщика со своего компьютера, и он возвращал правильный синтаксис. Наблюдение за самыми САМАМИ исполнениями из моего профилировщика показало неправильный синтаксис. Он действовал как красная селедка, заставляя меня поверить, что была проблема синтаксиса запроса, а не намного более простой и верный ответ, который заключался в том, что мне нужно совершить транзакцию!
Я отметил ответ ниже как правильный и бросил несколько голосов на других, потому что они, в конце концов, ответили на вопрос, даже если они не исправили мою конкретную проблему (провал мозга).