2012-04-04 35 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循環中放一個print語句,看看哪一個永遠持續下去。它可能會告訴你問題比其他人查看代碼的速度快很多。 – kemiller2002 2012-04-04 17:34:24

+0

也可以設置斷點和調試管理工作室中的代碼 – Magnus 2012-04-04 17:35:38

+0

我不知道我可以在sql中調試。現在將學習。感謝這個想法。 :) – 2012-04-04 17:52:50

回答

2

我同意史蒂夫,你應該設置VARCHAR到一定的長度。不過,我認爲它實際上是因爲@CharacterSet永遠不會改變,因此你陷入了無限循環。

這樣的每一個表態,將設置你通過一個無限循環:

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

這是當您通過2一遍又一遍劃分任意數量等。它永遠不會達到0,但會接近。

+0

如果你正在做整數除法(Vikram在這裏做的),除以2會得到零。 – 2012-04-05 01:05:41

+0

史蒂夫,你說的沒錯。我甚至沒有意識到這一點。經過一些進一步的測試後,我發現你的答案是正確的(VARCHAR是1而不是LEN('字符串')):)給你+1 – 2012-04-06 13:21:10

3

這裏的(忽略代碼似乎完全離奇的事實)的問題:

DECLARE @CharacterSet VARCHAR 

這聲明@CharacterSet爲VARCHAR(1),因此通過LEN(@CharacterSet)將永遠不會讓值更小,並且您的代碼保留在第一個WHILE循環中。對@CharacterSet的分配被截斷爲一個字符。

+0

非常感謝兄弟。非常友好的你通過這個奇怪的代碼來幫助我。 :) – 2012-04-04 17:49:58