2012-04-04 36 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

+0

また、ブレークポイントを設定し、管理スタジオ – Magnus

+0

でコードをデバッグすることは可能ですが、私はSQLでデバッグできることを知りませんでした。今それを学ぶでしょう。アイデアをありがとう。 :) –

答えて

2

私はSteveとVARCHARをある程度長めに設定することに同意します。しかし、実際には@CharacterSetはあなたが無限ループに陥っていることを決して変更しないためだと思います。

このようなすべての文が無限ループを通してあなたを設定します:

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

それはあなたが何度も何度も2により、任意の数を分割するときのようなものです。それは決して0に達することはありませんが、近づきます。

+0

整数除算(Vikramがここでやっている)を行っているなら、2で何度も繰り返し割るとゼロになります。 –

+0

こんにちはスティーブ、あなたは絶対に正しいです。私はそれを実感していませんでした。さらにテストした後、あなたの答えが正しいことがわかります(VARCHARは1であり、LEN(文字の束))ではありません):) +1 –

3

ここで(コードが完全に奇妙なようであるという事実を無視して)問題です:

DECLARE @CharacterSet VARCHAR 

これには、LEN(@CharacterSet)で割る、VARCHARとして@CharacterSet(1)を宣言していますことはありません値が小さくなり、コードは最初のWHILEループにとどまります。 @CharacterSetへの代入は1文字に切り捨てられます。

+0

おかげです。この奇妙なコードを見て、あなたを非常に親切にしてください。 :) –

関連する問題