2011-12-28 4 views
3

私はそれで30000から50000は(自動インクリメント)における欠損値のシーケンス

に及ぶことになっています「ポート」INT列を、持っているの検出、私は(ストアドプロシージャの挿入値を持つポートがありませんヌル)。だから、私はそのフィールドに格納されている値を '手動で'選択する必要があります。問題は、私がインクリメンタルに(30000,30001,30002 ....)ある特定のポイントでいくつかのエントリが削除される(それは30000,30002,30004などのように)削除されることができるということです。

これらの穴に合うように私のSPに配置する必要があります(例では30001,30003 ...です)。私の問題は、特定の値が既に 'ocuppied'であるかどうか、SP内でチェックする方法です。

私はMySQLのLOOPを使っていると思いました。

CREATE PROCEDURE teste() 
BEGIN 
DECLARE p INT; 
DECLARE aux INT; 
SET p = 30000; 

    label1: LOOP 

    SELECT Port FROM Reg WHERE Port = p INTO aux; 

    IF p = 50000 THEN 
    LEAVE label1; 
    END IF; 


    IF aux IS NULL THEN -- aux-1 is not null, so I can verify the "next miminum available position" 
     aux = aux - 1; 
     LEAVE label1; 

    ELSE 
     SET p = p + 1; 
     ITERATE label1; 


    END IF; 

    END LOOP label1; 

RETURN aux; 

END $$ 

私の問題は結果値を取得しています。そのRETURNステートメントを置くと、FUNCTIONでのみ許可されている情報が得られます。また、ループを終了すると、SELECTの結果は常にnullになります。

どうすればよいですか?

+1

だから、質問は:どのように私は、シーケンスから欠損値を検出していますか? –

+0

@SergeiTulentsevはい!私は次のエントリのためにそれを使用することができるように、最小欠損値が必要です。 – Tiago

+0

私の答えを見てください。 –

答えて

2
SELECT IFNULL(MIN(r1.Port) + 1, 30000) as minport 
FROM Reg r1 
LEFT JOIN Reg r2 ON r1.Port + 1 = r2.Port 
WHERE r2.Port IS NULL: 
+0

パーフェクト!どうもありがとうございました。 – Tiago

0

30000から50000までのすべての値をINSERTしてください(フィールドに一意のキーがあると仮定します)。値が存在するかどうかを検出するには、DB自体よりも速いものはありません。

5

シーケンス内に見つからない値を見つける方法は次のとおりです。

SELECT a.id+1 AS start, MIN(b.id) - 1 AS end 
    FROM seq AS a, seq AS b 
    WHERE a.id < b.id 
    GROUP BY a.id 
    HAVING start < MIN(b.id) 

出力例:

+-------+------+ 
    | start | end | 
    +-------+------+ 
    |  4 | 4 | 
    |  7 | 9 | 
    +-------+------+ 

これは7から(包括的)9にidのシーケンス値4が欠落していることを意味し、また数字。

対応する名前を置き換えて、このコードを必要に応じて変更してください。

1

このようなことはできますか?

SELECT 
    MIN(Port + 1) 
FROM 
    Reg 
WHERE 
    Port + 1 NOT IN (
     SELECT Port FROM Reg WHERE Port > 0 
    ) 
ORDER BY 
    Port ASC 
+0

はい、それでも動作します;) – Tiago

関連する問題