我正在尝试使用存储过程将数据插入数据库,但是我收到错误。
我存储数据的代码是这样的:
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;
}
我的自豪阶级是这样的:
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`
请帮忙。 在此先感谢。
有关例外的更多细节:`
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 :(得分:-1)
当你使用通用数据访问层,DbManger,Dbhelper和其他处理参数类型的类,加上存储过程处理许多字符串列时,我很快就解决了这个问题,我的建议是:
修改强>
从存储过程的数据类型来看,只有@CreatedOn和@CompleteOn是日期时间类型,因此它们可能是错误的来源。
我猜:这些列的日期时间格式与服务器日期时间格式不匹配 让sql profiler告诉我们发生了什么。
编辑2:
DbManager.AddParameter不会传递参数的sql数据类型,这样可以确保客户端和服务器正确地进行数据转换。 它应该是:
param.SqlDbType = SqlDbType.DateTime;
作为概念验证,我在c#ado.net应用程序的northwind数据库中运行名为“[按年份销售]”的存储过程并传递参数。
我的SQL Server(sql 2012)日期时间格式为:mdy
获取:运行命令
dbcc useroptions
你得到(在我的情况下)
dateformat mdy
如果以mdy或ymd(通用格式)传递日期时间,则服务器会接受该错误。
如果以dmy格式(与服务器不同)传递datatime,则会引发错误:
Error converting data type nvarchar to 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'
错误无效:
exec [dbo].[Sales by Year] @Beginning_Date=N'1970/1/1',@Ending_Date=N'20-07-2016'
<强>结论:强>
以服务器的典型格式或通用格式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,最好使用DateTime将jobdata.CreatedOn声明为可为空?
public DateTime? CreatedOn { get; set; }
2)格式化DateTime的其他方法:
var createon= string.Format("{0:yyyyMMdd}",jobdata.CreatedOn));