我有一个存储过程'Class_set',当用户尝试将类添加到数据库时会触发该过程。存储过程检查数据库中是否存在任何冲突,如果不存在冲突,则将该类插入数据库。
目前,如果存在冲突,则会抛出51000错误,但我希望使用标签或面板在前端显示错误以显示相应的消息。我尝试使用try catch但是没有成功。
我的存储过程:
CREATE procedure dbo.Class_set (
@moduledata int
, @startdatedata datetime
, @enddatedata datetime
, @classtypedata int
, @roomcodedata int
, @starttimedata int
, @endtimedata int
, @recurrencedata int
, @daydata int
) as
begin;
set nocount, xact_abort on;
/* temp table */
select
DayId = @daydata
, ModuleId =@moduledata
, ClassTypeId = @classtypedata
, ClassScheduleStartTimeId = @starttimedata
, ClassScheduleEndTimeId = @endtimedata
, RoomCodeId = @roomcodedata
, StartTime= convert(datetime,c.Date) + s.StartTime
, EndTime = convert(datetime,c.Date) + e.EndTime
, RecurrenceId = @recurrencedata
into #temp_class
from Calendar c
cross apply (
select StartTime = convert(datetime,ClassTime)
from ClassSchedule
where ClassScheduleId = @starttimedata
) as s
cross apply (
select EndTime = convert(datetime,ClassTime)
from ClassSchedule
where ClassScheduleId = @endtimedata
) as e
where c.Date >= @startdatedata
and c.Date <= @enddatedata
and c.isWeekDay = 1
and ( @recurrencedata != 2
or (@recurrencedata = 2 and c.DayOfWeek = @daydata)
);
/* check for conflicts */
if exists(
select 1
from dbo.[Class] c
inner join #temp_class t
on c.RoomCodeId = t.RoomCodeId
and t.EndTime > c.StartTime
and c.EndTime > t.StartTime
)
begin;
throw 51000, 'Room conflict exists',1;
return -1;
end;
/* insert */
insert into dbo.[Class] (DayId, ModuleId, ClassTypeId
, ClassScheduleStartTimeId, ClassScheduleEndTimeId
, RoomCodeId, StartTime, EndTime, RecurrenceId )
select DayId, ModuleId, ClassTypeId
, ClassScheduleStartTimeId, ClassScheduleEndTimeId
, RoomCodeId, StartTime, EndTime, RecurrenceId
from #temp_class
end;
go
调用存储过程的方法:
internal void insert_days( int daydata, int moduledata, int? recurrencedata, DateTime startdatedata, DateTime enddatedata, int classtypedata, int roomcodedata, int starttimedata, int endtimedata, string totalday)
{
{
string connectionString = WebConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("Class_set", myConnection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@daydata", daydata);
cmd.Parameters.AddWithValue("@moduledata", moduledata);
cmd.Parameters.AddWithValue("@classtypedata", classtypedata);
cmd.Parameters.AddWithValue("@startdatedata", startdatedata);
cmd.Parameters.AddWithValue("@enddatedata", enddatedata);
cmd.Parameters.AddWithValue("@roomcodedata", roomcodedata);
cmd.Parameters.AddWithValue("@starttimedata", starttimedata);
cmd.Parameters.AddWithValue("@endtimedata", endtimedata);
cmd.Parameters.AddWithValue("@recurrencedata", recurrencedata);
myConnection.Open();
cmd.ExecuteNonQuery();
}
}
}
}
我尝试捕获:
internal void insert_days(int daydata, int moduledata, int? recurrencedata, DateTime startdatedata, DateTime enddatedata, int classtypedata, int roomcodedata, int starttimedata, int endtimedata, string totalday)
{
{
try
{
string connectionString = WebConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
SqlConnection myConnection = new SqlConnection(connectionString);
using (SqlCommand cmd = new SqlCommand("Class_set", myConnection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@daydata", daydata);
cmd.Parameters.AddWithValue("@moduledata", moduledata);
cmd.Parameters.AddWithValue("@classtypedata", classtypedata);
cmd.Parameters.AddWithValue("@startdatedata", startdatedata);
cmd.Parameters.AddWithValue("@enddatedata", enddatedata);
cmd.Parameters.AddWithValue("@roomcodedata", roomcodedata);
cmd.Parameters.AddWithValue("@starttimedata", starttimedata);
cmd.Parameters.AddWithValue("@endtimedata", endtimedata);
cmd.Parameters.AddWithValue("@recurrencedata", recurrencedata);
myConnection.Open();
cmd.ExecuteNonQuery();
}
}
catch (SqlException ex)
{
switch (ex.Number)
{
case 51000:
Console.WriteLine("Error: Clashes exist with your current Room selection");
break;
default:
Console.WriteLine("Success: No clashes exist with your current Room selection");
}
}
}
}
答案 0 :(得分:2)
将SQL包装在try catch中。
CREATE PROCEDURE dbo.Class_set (
@moduledata int
, @startdatedata datetime
, @enddatedata datetime
, @classtypedata int
, @roomcodedata int
, @starttimedata int
, @endtimedata int
, @recurrencedata int
, @daydata int
) AS
BEGIN
set nocount, xact_abort on;
/* temp table */
BEGIN TRY
select
DayId = @daydata
, ModuleId =@moduledata
, ClassTypeId = @classtypedata
, ClassScheduleStartTimeId = @starttimedata
, ClassScheduleEndTimeId = @endtimedata
, RoomCodeId = @roomcodedata
, StartTime= convert(datetime,c.Date) + s.StartTime
, EndTime = convert(datetime,c.Date) + e.EndTime
, RecurrenceId = @recurrencedata
into
#temp_class
from
Calendar c
cross apply (
select StartTime = convert(datetime,ClassTime)
from ClassSchedule
where ClassScheduleId = @starttimedata
) as s
cross apply (
select EndTime = convert(datetime,ClassTime)
from ClassSchedule
where ClassScheduleId = @endtimedata
) as e
where
c.Date >= @startdatedata
and c.Date <= @enddatedata
and c.isWeekDay = 1
and ( @recurrencedata != 2
or (@recurrencedata = 2 and c.DayOfWeek = @daydata)
);
/* insert */
insert into dbo.[Class] (DayId, ModuleId, ClassTypeId
, ClassScheduleStartTimeId, ClassScheduleEndTimeId
, RoomCodeId, StartTime, EndTime, RecurrenceId )
select DayId, ModuleId, ClassTypeId
, ClassScheduleStartTimeId, ClassScheduleEndTimeId
, RoomCodeId, StartTime, EndTime, RecurrenceId
from #temp_class
END TRY
BEGIN CATCH
THROW
END CATCH;
END
GO
添加标量函数以进行验证:
CREATE FUNCTION dbo.RoomConflict
(
@RoomCode INT,
@StartTime TIME(7),
@EndTime TIME(7)
)
RETURNS INT
AS
BEGIN
RETURN (
SELECT
COUNT(*)
FROM
dbo.Class A
WHERE
A.RoomCodeId = @RoomCode AND @EndTime > A.StartTime AND A.EndTime > @StartTime)
END
GO
然后在dbo.Class表中添加一个约束:
ALTER TABLE [dbo].[Class] WITH NOCHECK ADD CONSTRAINT [CK_NoRoomConflict] CHECK (
[dbo].[RoomConflict]([RoomCodeId],[StartTime],[EndTime]) = 0
)
GO
ALTER TABLE [dbo].[Class] CHECK CONSTRAINT [CK_NoRoomConflict]
GO
答案 1 :(得分:0)
我能够编辑Web.Config文件以添加customErrors,将用户重定向到我已解释问题的网站上的新页面。它并不理想,因为我希望在他们当前所在的页面上显示某些内容,但这是我目前唯一能找到的解决方案。
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="ErrorPage.aspx?handler=customErrors%20section%20-%20Web.config">
<error statusCode="510" redirect="ErrorPage.aspx?msg=404&handler=customErrors%20section%20-%20Web.config"/>
</customErrors>
</system.web>
</configuration>