aashish tyagi Ответов: 3

Мы устали получать ошибки SQL


--exec [usp_ExamMaster] 'ram',1,'3th',' English, hindi','1,2',' english poitry, english qartu, english part3, hindi topic1, hindi topic2','2,4,5,11,12','','0','25 May 2017','6:00 AM','8.00 AM',0,102,70,100,1,1,0,'100,100','70,70','','','',1,0,0,0,'','','',0          
          
Alter PROC [dbo].[usp_ExamMaster]                 
(                  
@TestName NVarchar(200)='',                  
@ClassID int=0,                  
@ClassName NVarchar(100)='',                 
@SubName NVarchar(400)='',                 
@SubId NVarchar(400)='',                    
@TopicName NVarchar(Max)='',                 
@TopicId NVarchar(500)='',                     
@BatchName NVarchar(100)='',                    
@BatchID NVarchar(100)='',                       
@TestDate DateTime='',                           
@TestTime1 NVarchar(100)='',                      
@TestTime2 NVarchar(100)='',                        
@TestTime1id int=0,                      
@TetsTime2id int =0,                       
@PassingMarks decimal(10,2)=50,                       
@TotalMarks Decimal(10,2)=100,                      
@Brid int=0,                          
@Status int=0,                    
@TestMid Varchar(50)='0',                    
@MaxMarks Varchar(200)='',                  
@MinMarks Varchar(200)='',                  
----New Parameter For New Task----                  
@DateOfExam Varchar(100)='',                    
@FromTimeId Varchar(100)='',            
@ToTimeId Varchar(100)='',              
@Scheduletype int=1,                  
----New Parameter For End Here----      
@TestId Int=0,                  
@IntResult int=0 Out,         
@IsRollNoExamWise Int=0,       
@RollNoInitials Varchar(100)='',     
@RollNoSequence Varchar(100)='',       
@ExamRollNoSequenceTill Varchar(100)='',     
@UserId Int=0     
)               
As  
begin           
begin Transaction   t1   
Set Nocount ON           
Declare @Fyid int,@INDEX int,@NowDate DateTime,@TID int,@SLICE Varchar(200),@SLICEB Varchar(100),@ret int,@SLICEID Varchar(200),@SLICESUBNAME Varchar(100),                  
@TempTestId Int=0,@TERNSISID Int=0,@SLICEAllDate NVarchar(Max)='',@SLICEAllStartTime NVarchar(Max)='',@SLICEEndTime NVarchar(Max)=''                                    
Select @NowDate=GETDATE()     
Declare @INDEX1 int,@INDEX2 int, @INDEX3 int,@INDEX4 int,@INDEX5 int,@SLICETID Varchar(200),@SLICEtn Varchar(200) ,    
@INDEX6 int,@INDEX8 int ,@SLICEMAX Varchar(100) ,@SLICEMIN Varchar(100),@INDEX9 int=0,@INDEX10 int=0,@INDEX11 int=0,@INDEX12 int=0     
Select @Fyid=FYID from Financial_Year Where IsActive=1 AND IsClosed=0       
Set @IntResult=1     
If(@ClassName ='')    
Select @ClassName=Classname From Class_Master Where Status=1 AND Id=@ClassID     
--Select @TestDate='N/A',@TestTime1='N/A',@TestTime2='N/A'            
    
Insert Into tbl_examMaster(TestDate,BatchName,BatchID,TestTime1,TesTime1Id,TestTime2,TesTime2Id,PassingMarks,Totalmarks,NowDate,Brid,Status1,Fyid,SubName,SubId,Topic,TopicId,     
ClassID,ClassName,TestName,TestMasterId,ScheduleType)     
--@BatchName,@SubName,@TopicName,@ClassName,@TestDate--     
values(Convert(Varchar(11),@TestDate,106),'',@BatchID,'N/A',@TestTime1id,'N/A', @TetsTime2id,@PassingMarks,@TotalMarks,@NowDate,@Brid,1,@Fyid,'',@SubId,    
'',@TopicId,@ClassID,'',@TestName,@TestMid,@Scheduletype)    
----Code For Manage Roll No Exam Wise Start Here---                   
               
Select @TempTestId=IDENT_CURRENT('tbl_examMaster')                  
          
Set @IntResult=@TempTestId                 
----Code For Manage Roll No Exam Wise End Here------     
Update tbl_examMaster Set isdeleted = 1 Where Tid=@TestId 
Update StudentExam_Master Set Status = 0 Where TestId=@TestId 
           
Select @TID=Max(TID) from tbl_examMaster                                      
Set @INDEX=1              
                  
Set @INDEX1=1                            
                  
Set @INDEX2=1                            
                  
Set @INDEX3=1                    
                  
Set @INDEX4=1                            
                  
Set @INDEX5=1                   
                  
Set @INDEX6=1                            
                  
Set @INDEX8=1                   
                  
Set @INDEX9=1                   
                  
Set @INDEX10=1                   
                  
Set @INDEX11=1                   
                  
while @INDEX4!=0 AND @INDEX5!=0 AND @INDEX6!=0 AND @INDEX8!=0 --AND @INDEX9!=0 AND @INDEX10!=0 AND @INDEX11!=0                                        
                  
Begin                                          
                  
SELECT @INDEX4 = CHARINDEX(',',@SubId)                                          
                  
SELECT @INDEX5 = CHARINDEX(',',@SubName)                   
                  
SELECT @INDEX6 = CHARINDEX(',',@MaxMarks)                                          
                  
SELECT @INDEX8 = CHARINDEX(',',@MinMarks)                   
                  
SELECT @INDEX9 = CHARINDEX(',',@DateOfExam)                  
                  
SELECT @INDEX10 = CHARINDEX(',',@FromTimeId)                  
                  
SELECT @INDEX11 = CHARINDEX(',',@ToTimeId)                     
                  
IF @INDEX4 !=0 AND @INDEX5!=0 AND @INDEX6!=0 AND @INDEX8!=0 --AND @INDEX9!=0 AND @INDEX10!=0 AND @INDEX11!=0                                             
                  
Begin                        
                  
SELECT @SLICEID = LEFT(@SubId,@INDEX4 - 1)                                       
                  
Select @SLICESUBNAME=LEFT(@SubName,@INDEX5 - 1)                    
                  
SELECT @SLICEMAX = LEFT(@MaxMarks,@INDEX6 - 1)                                       
                  
Select @SLICEMIN=LEFT(@MinMarks,@INDEX8 - 1)                   
                  
End                                    
                  
ELSE                                                    
                  
Begin                                    
                  
SELECT @SLICEID = @SubId                                    
                  
Select @SLICESUBNAME=@SubName                      
                  
SELECT @SLICEMAX = @MaxMarks                                    
                  
Select @SLICEMIN=@MinMarks                    
                  
End                  
                  
IF @INDEX9 !=0 AND @INDEX10!=0 AND @INDEX11!=0                  
                  
Begin                  
                  
Select @SLICEAllDate=LEFT(@DateOfExam,@INDEX9 - 1)                  
                  
Select @SLICEAllStartTime=LEFT(@FromTimeId,@INDEX10 - 1)                  
                  
Select @SLICEEndTime=LEFT(@ToTimeId,@INDEX11 - 1)                  
                  
End                  
                  
else                  
                  
Begin                  
                  
Select @SLICEAllDate=@DateOfExam                  
                  
Select @SLICEAllStartTime=@FromTimeId                  
                  
Select @SLICEEndTime=@ToTimeId                  
                  
End                  
                  
IF @TestId !=0                  
                  
BEGIN                    
                  
Update Exam_SubjectMaster Set Status = 0 Where TestId=@TestId                     
                  
END                       
                  
--@SLICESUBNAME--                     
                  
If(@Scheduletype=1)                  
                  
Begin                  
                  
Insert Into Exam_SubjectMaster(TestId,SubjecTID,Subjectname,Status,Brid,MaxMarks,MinMarks,ExaminationDate,FromTimeId,ToTimeId)                  
                  
values(@TID,@SLICEID,'',1,@Brid,@SLICEMAX,@SLICEMIN,@TestDate,@TestTime1,@TestTime2)                  
         
End                  
                  
Else                  
                  
Begin                  
                  
Insert Into Exam_SubjectMaster(TestId,SubjecTID,Subjectname,Status,Brid,MaxMarks,MinMarks,ExaminationDate,FromTimeId,ToTimeId)                  
                  
values(@TID,@SLICEID,'',1,@Brid,@SLICEMAX,@SLICEMIN,@SLICEAllDate,@SLICEAllStartTime,@SLICEEndTime)                     
End                         
                  
If(@@ERROR<>0)                                                      
                  
Begin                                                      
                 
Set @IntResult=0                                                      
                  
Rollback Transaction                                                      
      
Return                                                      
                 
End                                     
SELECT @SubId = RIGHT(@SubId,LEN(@SubId) - @INDEX4)                                    
                  
SELECT @SubName= RIGHT(@SubName,LEN(@SubName) - @INDEX5)                   
                  
SELECT @MaxMarks = RIGHT(@MaxMarks,LEN(@MaxMarks) - @INDEX6)                                    
                  
SELECT @MinMarks= RIGHT(@MinMarks,LEN(@MinMarks) - @INDEX8)    
SELECT @DateOfExam= RIGHT(@DateOfExam,LEN(@DateOfExam) - @INDEX9)                   
                  
SELECT @FromTimeId= RIGHT(@FromTimeId,LEN(@FromTimeId) - @INDEX10)                   
                  
SELECT @ToTimeId= RIGHT(@ToTimeId,LEN(@ToTimeId) - @INDEX11)                                                           
  IF LEN(@SubId) = 0                                     
                  
If LEN(@SubName)=0                   
                  
IF LEN(@MaxMarks) = 0                                     
                  
If LEN(@MinMarks)=0                   
                  
--If LEN(@DateOfExam)=0                    
            
--If LEN(@FromTimeId)=0                    
                  
--If LEN(@ToTimeId)=0                          
                  
BREAK                                                  
                  
End                    
                  
While @INDEX!=0 AND @INDEX1!=0      
while @INDEX2!=0 AND @INDEX3!=0     
begin           
SELECT @INDEX2 = CHARINDEX(',',@TopicId)    
SELECT @INDEX3 = CHARINDEX(',',@TopicName)    
IF @INDEX2!=0 AND @INDEX3!=0      
begin           
SELECT @SLICETID = LEFT(@TopicId,@INDEX2 - 1)  
Select @slicetn=LEFT(@TopicName,@INDEX3 - 1)  
End               
ELSE             
Begin           
SELECT @SLICETID =@TopicId   
Select @slicetn=@TopicName    
End                      
If(@TestId=0)              
begin           
--ISNULL(@slicetn,'N/A')--   
Insert Into Exam_TopicMaster(TestId,Topicid,TopicName,Status,Brid)values(@TID,ISNULL(@SLICETID,0),'',1,@Brid)                            
       
END              
Else              
BEGIN            
--ISNULL(@slicetn,'N/A')--    
Update Exam_TopicMaster Set Status = 0 Where TestId = @TestId   
Insert Into Exam_TopicMaster(TestId,Topicid,TopicName,Status,Brid)values(@TID,ISNULL(@SLICETID,0),'',1,@Brid)  

END                  
If(@@ERROR<>0)                
Begin 
Set @IntResult=0              
Rollback Transaction  t1
Return                    
End            
SELECT @TopicId = RIGHT(@TopicId,LEN(@TopicId) - @INDEX2)  
SELECT @TopicName= RIGHT(@TopicName,LEN(@TopicName) - @INDEX3)  
If (LEN(@TopicId)=0)    
BREAK 
End         
Set @Ret=0   
--Exec [Usp_StuInExam] @TERNSISID,@TID,@Ret output
If(@Ret=1)                          
Begin                 
Rollback Transaction t1       
Return                          
end                    
Set Nocount Off              
Commit Transaction t1
return
end


это мой прок

Что я уже пробовал:

когда мы выполняем proc, это ошибка show time out через некоторое время ,и мы закрываем sql server this is show "
Есть незафиксированные транзакции. Хотите ли вы совершить эти транзакции до закрытия окна?
"
но у нас есть проверка всех begin tran и commit tran мы не получили никаких проблем пожалуйста исправьте мою проблему и верните меня

3 Ответов

Рейтинг:
1

Christian Luketa Kanyinda

Попробуйте изменить свой способ написания сценария транзакции следующим образом :

Начать транзакцию MyTransact
НАЧИНАЙТЕ ПРОБОВАТЬ
// Ваш сценарий тела хранимой процедуры здесь
КОНЕЦ ПОПЫТКИ
НАЧИНАЙ ЛОВИТЬ
ВЕРНУТЬ
ОТМЕНА
КОНЦЕВАЯ ЗАЩЕЛКА
Совершить транзакцию MyTransact


CHill60

Хороший совет, но у меня не было бы коммита после улова

Рейтинг:
0

Maciej Los

Мы не можем. Есть масса причин, но одна из них самая важная: у нас нет доступа к вашим данным. Таким образом, мы не можем исправить ваш sql-оператор.

Я бы предложил использовать Отладчик Transact-SQL[^]
Запуск отладчика Transact-SQL[^]


CHill60

5D для ссылок

Maciej Los

Спасибо, Кэролайн.

0x01AA

В 5

Maciej Los

Спасибо, Бруно.

Рейтинг:
0

CHill60

Далее к решению 1-SQL основан на множествах, но у вас есть 3 WHILE петли. Почти наверняка вам не нужны никакие петли. Скорее всего, у вас здесь бесконечный цикл, либо потому, что вы неправильно проверяете один из 11 (?!) INDEX переменные или потому, что вы не увеличили одну из них в маршруте через код.

Мой совет был бы вернуться к чертежной доске с этим - то есть начать все сначала

[Править] - еще один совет ... Сделайте отступ в своем коде! Я собирался попытаться удалить хотя бы одну из петель WHILE для вас, но это действительно слишком много усилий, чтобы привести ее в порядок до такой степени, чтобы она была читабельной.

ОБНОВЛЕНИЕ
Я остаюсь при своем совете переписать это. Пара пунктов, которые помогут вам упростить хранимую процедуру (и, надеюсь, избежать бесконечного цикла).

1. Ваш первый цикл, по-видимому, разбивает входные переменные, разделенные запятыми. Подумайте о том, чтобы сделать все "расщепление" заранее, используя функцию табличных значений для разделения строк на запятые - в интернете есть много примеров, я случайно использую тот, который нашел здесь - Как разбить строку на символ с разделителями в SQL Server.............. - SQLServerCentral[^] Вы получите кучу временных таблиц, к которым затем сможете присоединиться для выполнения вставок и обновлений.

2. Вы, кажется, храните некоторые даты и время в nvarchar переменные. Никогда не храните даты или время в типах столбцов NVarchar, Varchar, NChar, Char или Text. Воспользуйся Date, Time или DateTime тип столбца. Это значительно облегчает жизнь при проведении сравнений и т. д. и занимает меньше места в базе данных. Вы также не столкнетесь с проблемами с форматами дат, если будете использовать правильные типы.

3. Вы должны помнить, что SQL основан на множествах. По возможности отойдите от циклов, а также от сценариев типа IF-ELSE. Например, этот код:

If(@Scheduletype=1)
Begin
    Insert Into Exam_SubjectMaster(TestId,SubjecTID,Subjectname,[Status],Brid,MaxMarks,MinMarks,ExaminationDate,FromTimeId,ToTimeId)
    values(@TID,@SLICEID,'',1,@Brid,@SLICEMAX,@SLICEMIN,@TestDate,@TestTime1,@TestTime2)
End
Else
Begin
    Insert Into Exam_SubjectMaster(TestId,SubjecTID,Subjectname,[Status],Brid,MaxMarks,MinMarks,ExaminationDate,FromTimeId,ToTimeId)
    values(@TID,@SLICEID,'',1,@Brid,@SLICEMAX,@SLICEMIN,@SLICEAllDate,@SLICEAllStartTime,@SLICEEndTime)
End
Может быть переписан как
Insert Into Exam_SubjectMaster
    select  @TID AS TestId,@SLICEID AS SubjecTID,'' AS Subjectname,1 AS [Status],
    @Brid AS Brid,@SLICEMAX AS MaxMarks,@SLICEMIN AS MinMarks,
    CASE WHEN @Scheduletype=1 THEN @TestDate ELSE @SLICEAllDate END AS ExaminationDate,
    CASE WHEN @Scheduletype=1 THEN @TestTime1 ELSE @SLICEAllStartTime END AS FromTimeId,
    CASE WHEN @Scheduletype=1 THEN @tESTtIME2 ELSE @SLICEEndTime END AS ToTimeId
Более того, когда вы вводите свои временные таблицы для @SLICEMAX, @SLICEMIN гораздо проще будет объединить эти таблицы, чтобы взаимодействовать с этой вставкой. Смотрите мою статью Циклы обработки в SQL Server[^] для некоторых идей.

4. Если вы поставите точку останова на
While @INDEX!=0 AND @INDEX1!=0
while @INDEX2!=0 AND @INDEX3!=0
(или закомментируйте оставшийся код с помощью /* ... */ и запустите свою процедуру с данными, которые, как известно, вызывают ошибку тайм-аута... если ошибка возникает, то вы знаете, что проблема связана с этим первым циклом, если ошибка не возникает, то вы знаете, что проблема находится во второй половине SP. Этот метод полезен при работе с тайм-аутами и бесконечными циклами, когда пошаговое выполнение кода до тех пор, пока проблема не возникнет, не является жизнеспособным.

5. У вас есть входное значение @TestId это не похоже на запятую. Вы используете его в двух местах, оба внутри циклов, вот так:
If(@TestId=0) 
     Update Exam_SubjectMaster Set Status = 0 Where TestId=@TestId
Это не обязательно должно быть в цикле и может быть сделано только один раз. Более того, вам не нужно IF утверждение, оно может быть просто
Update Exam_SubjectMaster Set Status = 0 Where TestId=@TestId AND @TestId != 0

6. Вы чрезмерно увлекались IF заявления. Видеть
If(@TestId=0)
begin
    Insert Into Exam_TopicMaster(TestId,Topicid,TopicName,[Status],Brid)values(@TID,ISNULL(@SLICETID,0),'',1,@Brid)
END
Else
BEGIN
    Update Exam_TopicMaster Set [Status] = 0 Where TestId = @TestId
    Insert Into Exam_TopicMaster(TestId,Topicid,TopicName,[Status],Brid)values(@TID,ISNULL(@SLICETID,0),'',1,@Brid)
END
Это тождественно
Update Exam_TopicMaster Set [Status] = 0 Where TestId = @TestId and @TestId !=0
Insert Into Exam_TopicMaster(TestId,Topicid,TopicName,[Status],Brid)values(@TID,ISNULL(@SLICETID,0),'',1,@Brid)                            
7. У вас есть линия
While @INDEX!=0 AND @INDEX1!=0      
while @INDEX2!=0 AND @INDEX3!=0 
Вы всегда должны использовать BEGIN ... END для определения WHILE петли (Если вам действительно нужно их использовать, чего вы не делаете). Это делает более ясным, какие операторы на самом деле будут выполняться, и может помочь избежать бесконечных циклов.


Maciej Los

Хорошо объяснил. 5ед!

CHill60

Спасибо!