2016-07-20 6 views
-1

Я пытаюсь вставить мои данные в базу данных с помощью хранимой процедуры, но я получаю ошибку.Ошибка при вводе даты в базе данных

Мой код для хранения данных, как это:

public string InsertJobData(JobDTO jobdata) 
    { 
     try 
     { 
      DbManager.OpenConnection(); 
      DbManager.AddParameter("JobId", jobdata.JobType, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("JobTypeId", jobdata.JobTypeId, StoredProcedureParameterDirection.Input); 

      if (jobdata.JobRefence != null) 
      { 
       DbManager.AddParameter("JobRefence", jobdata.JobRefence, StoredProcedureParameterDirection.Input); 
      } 

      else 
      { 
       DbManager.AddParameter("JobRefence", DBNull.Value, StoredProcedureParameterDirection.Input); 
      } 

      DbManager.AddParameter("JobName", jobdata.JobName, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("CustomerName", jobdata.CustomerName, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("Quantity", jobdata.Quantity, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("JobDescription", jobdata.JobDescription, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("CreatedOn", jobdata.CreatedOn, StoredProcedureParameterDirection.Input); 

      if (jobdata.CompleteOn != null) 
      { 
       DbManager.AddParameter("CompleteOn", jobdata.CompleteOn, StoredProcedureParameterDirection.Input); 
      } 

      else 
      { 
       DbManager.AddParameter("CompleteOn", DBNull.Value, StoredProcedureParameterDirection.Input); 
      } 

      DbManager.AddParameter("Department", jobdata.Department, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("DepartmentId", jobdata.DepartmentId, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("Status", jobdata.Status, StoredProcedureParameterDirection.Input); 

      if (jobdata.AreaOfPCB != null) 
      { 
       DbManager.AddParameter("AreaOfPCB", jobdata.AreaOfPCB, StoredProcedureParameterDirection.Input); 
      } 

      else 
      { 
       DbManager.AddParameter("AreaOfPCB", DBNull.Value, StoredProcedureParameterDirection.Input); 
      } 


      if (jobdata.NumberOfJoints != null) 
      { 
       DbManager.AddParameter("NumberOfJoints", jobdata.NumberOfJoints, StoredProcedureParameterDirection.Input); 
      } 

      else 
      { 
       DbManager.AddParameter("NumberOfJoints", DBNull.Value, StoredProcedureParameterDirection.Input); 
      } 

      DbManager.AddParameter("TaskStatus", jobdata.Tasktypeid, StoredProcedureParameterDirection.Input); 
      DbManager.AddParameter("Id", StoredProcedureParameterDirection.Output); 
      DbManager.ExecuteNonQuery("spInsertJobData", System.Data.CommandType.StoredProcedure); 
      jobdata.Id = (int)DbManager.GetParameter("Id"); 

      jobdata.NewJobId = jobdata.JobType + "_" + jobdata.Id; 

      //dbManager.AddParameter("JobId", jobdata.JobType, StoredProcedureParameterDirection.Input); 
      //dbManager.ExecuteNonQuery("spUpdateJobByJobId", System.Data.CommandType.StoredProcedure); 

     } 

     catch 
     { 

     } 

     finally 
     { 
      DbManager.CloseConnection(); 
     } 

     return jobdata.NewJobId; 
    } 

Мой класс proprty как это:

public int Id { get; set; } 
    public string JobId { get; set; } 
    public int JobTypeId { get; set; } 
    public string JobRefence { get; set; } 
    public string JobName { get; set; } 
    public string CustomerName { get; set; } 
    public int Quantity { get; set; } 
    public string JobDescription { get; set; } 
    public DateTime CreatedOn { get; set; } 
    public DateTime? CompleteOn { get; set; } 
    public string Department { get; set; } 
    public int DepartmentId { get; set; } 
    public bool Status { get; set; } 
    public string JobType { get; set; } 
    public string NewJobId { get; set; } 
    public float? AreaOfPCB { get; set; } 
    public int? NumberOfJoints { get; set; } 
    public int? Tasktypeid { get; set; } 

Моя хранимая процедура выглядит так:

`

CREATE procedure [dbo].[spInsertJobData] 
@JobId nvarchar(50), 
@JobTypeId int, 
@JobRefence nvarchar(50), 
@JobName nvarchar(50), 
@CustomerName nvarchar(50), 
@Quantity bigint, 
@JobDescription nvarchar(MAX), 
@CreatedOn datetime, 
@CompleteOn datetime, 
@Department nvarchar(50), 
@DepartmentId int, 
@Status bit, 
@AreaOfPCB int, 
@NumberOfJoints bigint, 
@TaskStatus int, 
@Id int OUTPUT 
As 
BEGIN 
INSERT INTO oms.JobId_Table (JobId,JobTypeId,JobRefence,JobName,CustomerName,Quantity,JobDescription,CreatedOn,CompleteOn,Department,DepartmentId,Status,AreaOfPCB,NumberOfJoints,TaskStatus) 
VALUES (@JobId,@JobTypeId,@JobRefence,@JobName,@CustomerName,@Quantity,@JobDescription,@CreatedOn,@CompleteOn,@Department,@DepartmentId,@Status,@AreaOfPCB,@NumberOfJoints,@TaskStatus) 
UPDATE oms.JobId_Table 
SET JobId = 'oms.' + Convert(varchar,@JobId) +'_'+ Convert(varchar,oms.JobId_Table.Id) 
WHERE JobId = @JobId 
SET @Id = SCOPE_IDENTITY() 
RETURN @Id 
END` 

Когда я выполняю код , это исключает следующее:
enter image description here

Помогите пожалуйста. Спасибо заранее.

Подробнее об исключении: `

System.Data.SqlClient.SqlException was caught 
    HResult=-2146232060 
    Message=Error converting data type nvarchar to datetime. 
    Source=.Net SqlClient Data Provider 
    ErrorCode=-2146232060 
    Class=16 
    LineNumber=0 
    Number=8114 
    Procedure=spInsertJobData 
    Server=JITENDERSINGH\JITENDER 
    State=5 
    StackTrace: 
     at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
     at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
     at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
     at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
     at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 
     at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) 
     at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) 
     at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) 
     at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
     at Company.Project.Entities.Entities.DatabaseHelper.ExecuteNonQuery(String query, CommandType commandtype, DatabaseConnectionState connectionstate) in e:\SGS_MVC_APP\SGS_PROJECT\Company.Project.Entities\Entities\DBHelper.cs:line 258 
     at Company.Project.Entities.Entities.DatabaseHelper.ExecuteNonQuery(String query, CommandType commandtype) in e:\SGS_MVC_APP\SGS_PROJECT\Company.Project.Entities\Entities\DBHelper.cs:line 221 
     at Company.Project.Entities.Entities.DBManager.ExecuteNonQuery(String query, CommandType commandtype) in e:\SGS_MVC_APP\SGS_PROJECT\Company.Project.Entities\Entities\DBManagerBase.cs:line 131 
     at Company.Project.DataAccess.BiddingFirstStepDAC.InsertJobData(JobDTO jobdata) in e:\SGS_MVC_APP\SGS_PROJECT\Company.Project.DataAccess\BiddingFirstStepDAC.cs:line 163 
    InnerException: 

`

+0

Вы можете разместить детали исключения? –

+0

Можете ли вы проверить, являются ли какие-либо другие значения, такие как 'JobId' и т. Д.' Null '?Это может вызвать различные проблемы, так как они не настраиваются на 'DbNull.Value' –

+0

Примечание:' SET @Id = SCOPE_IDENTITY() 'должно идеально ** немедленно ** следовать за' INSERT'. Это не вызовет этой проблемы. –

ответ

-1

Как вы используете общий уровень доступа к данным, DbManger, Dbhelper и другие классы, которые обрабатывают тип параметра, плюс хранимая процедура обработки много строк столбцов , чтобы быстро решить эту проблему, мой совет:

  • Просмотрите инструкцию sql, отправленную на сервер из DAL с использованием sql-профилятора. это ваш инструмент для друзей.
  • Просмотрите сведения об исключении и номер строки источника трассировки, чтобы узнать источник ошибки.
  • Очень важно: DAL должен обрабатывать исключение, чтобы регистрировать ошибки в файле журнала, с подробным описанием исключения и именем/значением/типом параметров, чтобы помочь устранить проблемы. Недостаточно поймать генерическое исключение, отправленное с сервера.
  • DAl должен преобразовать строку (столбцов DateTime) в DateTime на основе формата DateTime сервера. Для безопасности YYYYMMDD является независимым, независимо от формата регионального дата-времени в клиенте.
  • Вы должны выполнить единичный тест. И обновите свои тесты, когда появятся новые ошибки/ошибки.

Edit:

От типа данных хранимой процедуры, только @CreatedOn и @CompleteOn являются DateTime типа, поэтому они могут быть источником ошибок.

Я предполагаю: формат datetime этих столбцов не соответствует формату даты и времени сервера Пусть профайлер sql сообщит нам, что происходит.

Изменить 2:

DbManager.AddParameter не па типа данных SQL параметра, который страховать преобразование данных правильно ставку клиента и сервера. Оно должно быть:

param.SqlDbType = SqlDbType.DateTime; 

Как доказательство концепции, я запустить хранимую процедуру с именем «[Продажи года]» в базе данных Northwind в C# ado.net приложения и передавать параметры.

Мой SQL Server (SQL 2012) Формат даты и времени является: MDY

получить: запустить команду

dbcc useroptions 

вы получите (в моем случае)

dateformat mdy 

если прошло даты и времени в mdy или ymd (универсальный формат), он принимается сервером с ошибками.

если прошло datatime в формате ДМГ (который отличается от сервера), это вызовет ошибку:

Error converting data type nvarchar to datetime. 

Я изменил формат DATETIME из Ending_Date и запускать различные случаи, следующим образом:

// var date2= DateTime.Today.ToString("MMMM dd, yyyy"); //ok match server 
//var date2 = DateTime.Today.ToString("dd-MM-yy"); //error don't match server format 
var date2 = DateTime.Today.ToString("dd-MM-yyyy"); //error don't match server 
var date2 = DateTime.Today.ToString("yyyyMMdd"); //ok universal datetime format 

, когда я просмотреть результат SQL Profiler (с первого взгляда, я могу поймать SQL и исправить ошибку), я нашел:

Выход SQL Profiler:

действует

exec [dbo].[Sales by Year] @Beginning_Date=N'1970/1/1',@Ending_Date=N'July 20, 2016' 
exec [dbo].[Sales by Year] @Beginning_Date=N'1970/1/1',@Ending_Date=N'7/20/2016 12:00:00 AM' 
exec [dbo].[Sales by Year] @Beginning_Date=N'1970/1/1',@Ending_Date='2016-07-20 00:00:00' 
exec [dbo].[Sales by Year] @Beginning_Date=N'1970/1/1',@Ending_Date=N'20160720' 

Invalid с ошибкой:

exec [dbo].[Sales by Year] @Beginning_Date=N'1970/1/1',@Ending_Date=N'20-07-2016' 

Вывод:

Установить переменные DateTime в формате типичных для сервера или в универсальном формате YMD

Итак, измените свой код как:

DbManager.AddParameter("CreatedOn", jobdata.CreatedOn.ToString("yyyyMMdd"), StoredProcedureParameterDirection.Input); 

DbManager.AddParameter("CompleteOn", jobdata.CompleteOn.ToString("yyyyMMdd"), StoredProcedureParameterDirection.Input); 

Я надеюсь, что помощь в решении вашей проблемы

Редактировать 3: Обработка нулевых значений

Вы уже обрабатывают, в вашем коде, нулевые значения для jobdata.CompleteOn, так делать то же самое для jobdata.CreatedOn

if (jobdata.CreatedOn != null) 
     { 
      DbManager.AddParameter("CreatedOn", jobdata.CreatedOn.ToString("yyyyMMdd"), StoredProcedureParameterDirection.Input); 
     } 
     else 
     { 
      DbManager.AddParameter("CreatedOn", DBNull.Value, StoredProcedureParameterDirection.Input); 
     } 

Примечание:

1) Как jobdata.CreatedOn может быть null, Лучше объявить jobdata.CreatedOn как nullable, используя DateTime?

public DateTime? CreatedOn { get; set; } 

2) другой способ форматирования DateTime:

var createon= string.Format("{0:yyyyMMdd}",jobdata.CreatedOn)); 
+0

Это дает мне ошибку, поскольку у меня есть nullable datetime fullon. Если я сделаю его недействительным, то ваше решение работает, но с нулевым значением оно не работает. –

+0

Итак, мое предположение нацелено на проблему с корнем :), я отредактирую свое сообщение, чтобы обрабатывать случаи с возможностью Nable-времени. –

+0

ok..thanks..i пометьте это как ответ, потому что он решил мою половинную ошибку. –

Смежные вопросы