2012-04-04 3 views
0

Я новичок в SQL. Моя проблема: я не могу найти бесконечный цикл в коде ниже. Запрос просто продолжает выполняться, но я не знаю, почему. Может ли кто-нибудь указать на ошибку в моем коде?Застрял в бесконечной петле с помощью курсоров

Дополнительная информация: Я буду использовать этот запрос для 3500 записей. Я знаю, что мой запрос будет работать слишком медленно. Поэтому мне было бы интересно узнать о более быстрых методах.

Заранее спасибо.

DECLARE @intCounter INT,@strNo VARCHAR(8) 
DECLARE @strResult VARCHAR(12),@strResult1 VARCHAR(2),@strResult2 VARCHAR(2),@strResult3 VARCHAR(1),@strResult4 VARCHAR(1),@strResult5 VARCHAR(3),@strResult6 VARCHAR(2) 
DECLARE @intDecimalValueYear INT,@intDecimalValueMonth INT,@intDecimalValueDay INT,@intDecimalValueTimer1 INT,@intDecimalValueTimer2 INT,@intDecimalValueTimer3 DECIMAL(7,2),@intCounterTemp INT 
DECLARE @intRemainder DECIMAL(7,2),@intDividend bigint,@strBranchCode VARCHAR 
DECLARE @intWidth1 INT,@intWidth2 INT, @intWidth3 INT 
DECLARE @CharacterSet VARCHAR 
DECLARE C1 CURSOR FOR SELECT No FROM Pol 
WHERE No='0900001' 
OPEN C1 
    SET @CharacterSet='— :;[email protected][\]^ˆ_`{|}~¡¦¨¯´¸¿˜‘”<=>±×÷¢£¤¥§©¬®°µ¶·†‡•…‰€0¼½¾123456789AªÁÀÂÄÃÅÆBCÇDÐEÉÈÊËFƒGHIÍÌÎÏJKLMNÑOºÓÒÔÖÕØŒPQRSŠßTÞ™UÚÙÛÜVWXYÝŸZ' 
    SET @intCounter=0 
    SET @strResult2='' 
    SET @strResult3='' 
    SET @strResult4='' 
    SET @strResult5='' 
    SET @strResult6='' 
    FETCH NEXT FROM C1 INTO @strNo 
    WHILE @@FETCH_STATUS=0 
     BEGIN 
      SET @intCounter = @intCounter + 1 
      SET @intDecimalValueYear=YEAR(GETDATE()) 
      SET @intDecimalValueMonth=MONTH(GETDATE()) 
      SET @intDecimalValueDay=DAY(GETDATE()) 
      SET @intDecimalValueTimer1=(DATEPART(HH,CURRENT_TIMESTAMP) * 3600) + (DATEPART(MI,CURRENT_TIMESTAMP) * 60) + (DATEPART(SS,CURRENT_TIMESTAMP)) 
      SET @intDecimalValueTimer2=(DATEPART(MS,CURRENT_TIMESTAMP)) 
      SET @[email protected]+(@intDecimalValueTimer2/1000) 
      SET @[email protected] 
      SET @strResult1='HQ' 

      IF @intCounter > LEN(@CharacterSet) 
       BEGIN 
        SET @intCounter = 1 
       END 
      -------------- 
      WHILE @intDecimalValueYear > 0 
       BEGIN 
        SET @intRemainder = @intDecimalValueYear % LEN(@CharacterSet) 
        SET @intDecimalValueYear = @intDecimalValueYear/LEN(@CharacterSet) 
        SET @strResult2 = (RIGHT(LEFT(@CharacterSet, @intRemainder + 1),1)) + @strResult2 
       END 
      IF LEN(@strResult2)=1 
       BEGIN 
        SET @strResult2 = '—' 
       END 
      ELSE IF LEN(@strResult2)=0 
       BEGIN 
        SET @strResult2 = '——' + @strResult2 
       END 
      -------------- 
      WHILE @intDecimalValueMonth > 0 
       BEGIN 
        SET @intRemainder = @intDecimalValueMonth % LEN(@CharacterSet) 
        SET @intDecimalValueMonth = @intDecimalValueMonth/LEN(@CharacterSet) 
        SET @strResult3 = (RIGHT(LEFT(@CharacterSet, @intRemainder + 1),1)) + @strResult3 
       END 
      IF LEN(@strResult3)=0 
       BEGIN 
        SET @strResult3 = '—' 
       END 
      -------------- 
      WHILE @intDecimalValueDay > 0 
       BEGIN 
        SET @intRemainder = @intDecimalValueDay % LEN(@CharacterSet) 
        SET @intDecimalValueDay = @intDecimalValueDay/LEN(@CharacterSet) 
        SET @strResult4 = (RIGHT(LEFT(@CharacterSet, @intRemainder + 1),1)) + @strResult4 
       END 
      IF LEN(@strResult4)=0 
       BEGIN 
        SET @strResult4 = '—' 
       END 
      -------------- 
      WHILE @intDecimalValueTimer3 > 0 
       BEGIN 
        SET @intRemainder = @intDecimalValueTimer3 % LEN(@CharacterSet) 
        SET @intDecimalValueTimer3 = @intDecimalValueTimer3/LEN(@CharacterSet) 
        SET @strResult5 = (RIGHT(LEFT(@CharacterSet, @intRemainder + 1),1)) + @strResult5 
       END 
      IF LEN(@strResult5)=2 
       BEGIN 
        SET @strResult5 = '—' + @strResult5 
       END 
      IF LEN(@strResult5)=1 
       BEGIN 
        SET @strResult5 = '——' + @strResult5 
       END 
      IF LEN(@strResult5)=0 
       BEGIN 
        SET @strResult5 = '———' 
       END 
      ------------- 
      WHILE @intCounterTemp > 0 
       BEGIN 
        SET @intRemainder = @intCounterTemp % LEN(@CharacterSet) 
        SET @intCounterTemp = @intCounterTemp/LEN(@CharacterSet) 
        SET @strResult6 = (RIGHT(LEFT(@CharacterSet, @intRemainder + 1),1)) + @strResult6 
       END 
      IF LEN(@strResult6)=1 
       BEGIN 
        SET @strResult6 = '—' + @strResult6 
       END 
      ELSE IF LEN(@strResult6)=0 
       BEGIN 
        SET @strResult6 = '——' 
       END 
      ------------- 
      --SET @[email protected] + @strResult2 + @strResult3 + @strResult4 + @strResult5 + @strResult6 

      UPDATE POL 
      SET [email protected] + @strResult2 + @strResult3 + @strResult4 + @strResult5 + @strResult6 
      WHERE [email protected] 

      FETCH NEXT FROM C1 INTO @strNo 
    END 
CLOSE C1 
DEALLOCATE C1 
+2

Самый простой способ - поставить инструкцию печати в каждый цикл while и посмотреть, какой из них продолжается вечно. Вероятно, это скажет вам, где проблема намного быстрее, чем кто-то другой, просматривающий код. – kemiller2002

+0

Также можно установить точки останова и отладить код в студии управления – Magnus

+0

Я не знал, что могу отлаживать в sql. узнает это сейчас. спасибо за идею. :) –

ответ

2

Я согласен со Стивом, что вы должны установить VARCHAR на некоторую длину. Тем не менее, я думаю, что это на самом деле потому, что @CharacterSet никогда не меняется, что вы застряли в бесконечном цикле.

Каждое утверждение, как это сделает вас через бесконечный цикл:

SET @intDecimalValueYear = @intDecimalValueYear/LEN(@CharacterSet) 
SET @intDecimalValueMonth = @intDecimalValueMonth/LEN(@CharacterSet) 
SET @intDecimalValueDay = @intDecimalValueDay/LEN(@CharacterSet) 
-- etc... 

Это как если разделить любое число на 2 снова и снова. Он никогда не достигнет 0, но приблизиться.

+0

Если вы делаете целочисленное деление (которое здесь делает Викрам), деление на 2 снова и снова приведет вас к нулю. –

+0

Привет, Стив, ты совершенно прав. Я этого даже не осознавал. После некоторого дополнительного тестирования я вижу, что ваш ответ правильный (VARCHAR - это 1, а не LEN («куча символов»)) :) +1 к вам –

3

Вот проблема (игнорируя тот факт, что код кажется совершенно странным):

DECLARE @CharacterSet VARCHAR 

Объявляет @CharacterSet как VARCHAR (1), так что деление на LEN (@CharacterSet) никогда не делает значение меньше, и ваш код остается в первом цикле WHILE. Назначение @CharacterSet усекается до одного символа.

+0

благодарит много брата. очень любезно с вами, чтобы посмотреть этот странный код, помогите мне. :) –

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