- PR -

SQLについて

投稿者投稿内容
あかり
常連さん
会議室デビュー日: 2009/02/18
投稿数: 38
投稿日時: 2009-03-03 09:41
いつもお世話になっております。

現在キーをサイクリックして使用するテーブルを作成しています。

サイクリックは実現できたのですが、キー値が歯抜けになってしまう可能性を考慮しキーがは抜けになった場合、歯抜けになってしまっているキー値の位置にレコードを挿入する仕様を考えています。

そこでわからないのですが、SQLを使用しキーの歯抜け部分の値を取得することはできませんでしょうか?


Table_A
key =1,data=xxx
key =2,data=xxx
key =4,data=xxx
key =5,data=xxx
というテーブルから3を取得するSQLは作成できないのでしょうか?

使用しているRDBMSはSQL-Server2005です。
Transact-SQLを使用して解決できればと考えています。
現在は、レコード件数が管理数に満たない場合は、CLRストアドプロシージャを使用して、keyをすべてチェックし取得しています。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2009-03-03 09:55
引用:

あかりさんの書き込み (2009-03-03 09:41) より:
そこでわからないのですが、SQLを使用しキーの歯抜け部分の値を取得することはできませんでしょうか?


出来ません。

無効フラグフィールドを設けて、レコードの削除時にDELETEするのではなく、無効フラグを設定するようにするのが良いかと。レコードを追加する場合には無効フラグが立っているレコードをUPDATEします。

あるいはDELETE時に別テーブル(B)に削除したレコードのキーを格納しておき、追加するときには(B)テーブルからキーを取得して利用するとか。

引用:

Transact-SQLを使用して解決できればと考えています。
現在は、レコード件数が管理数に満たない場合は、CLRストアドプロシージャを使用して、keyをすべてチェックし取得しています。


↑もレコード数が少ないとか、パフォーマンス上の要求が緩いなら、十分有用な方法かと。
タコツボ
常連さん
会議室デビュー日: 2004/01/20
投稿数: 22
お住まい・勤務地: 京都・大阪
投稿日時: 2009-03-03 10:14
今手元に環境が無いので、SQLServerで使えるかどうかわかりませんが、ご参考まで。
【SQL】連番の歯抜けの検索
デューン
大ベテラン
会議室デビュー日: 2004/04/21
投稿数: 174
お住まい・勤務地: Tokyo
投稿日時: 2009-03-03 10:24
引用:
「【SQL】連番の歯抜けの検索」より
SELECT MIN(seq + 1) AS gap
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);



はseqが数値で、nullを含まない事が前提になります。
全部列挙したい場合はMINを外してください。


NULLを含むのであれば
select [key] + 1
FROM Table_A A
WHERE NOT EXISTS ( Select B.[key] FROM Table_A B where (A.[key] + 1) = B.[key]);

かな?

[ メッセージ編集済み 編集者: デューン 編集日時 2009-03-03 10:25 ]
忠犬
大ベテラン
会議室デビュー日: 2006/05/01
投稿数: 109
投稿日時: 2009-03-03 16:17
引用:

「【SQL】連番の歯抜けの検索」より
SELECT MIN(seq + 1) AS gap
FROM SeqTbl
WHERE (seq+ 1) NOT IN ( SELECT seq FROM SeqTbl);



上記のSQLの場合、最小値(あるいは最小値から連続する番号)が削除されていた場合、それを拾うことができません。
つまり、最小値が1なら、0の行が必要になります。

上記を踏まえ、改善してみました。

コード:
select min(seq+1) as gap
 from (select seq from seqtbl
       union 
       select 0 as seq from seqtbl) as x 
 where (seq+1) not in(select seq from seqtbl)

あかり
常連さん
会議室デビュー日: 2009/02/18
投稿数: 38
投稿日時: 2009-03-04 08:52
甕星様、タコツボ様、デューン様、忠犬様回答ありがとうございます。

大変勉強になりました、皆さん本当にありがとうございます。

SQLひとつでここまでできるのですね、感激しています。

今回はDBへのストアドを使用できるので、以下のようなストアドを作成しました。

同じような案件で、ストアドを使用できない場合はぜひ使用させていただきたいと思います、ありがとうございました。

ALTER PROCEDURE [dbo].[Get_Insert_Key]
@keyvalue integer OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @keyvalue = MIN(key + 1)
FROM Table_A
WHERE (key + 1) NOT IN ( SELECT key FROM Table_A);

IF @keyvalue IS NULL
BEGIN
SET @keyvalue = 1
END
END
よっしー
大ベテラン
会議室デビュー日: 2007/05/17
投稿数: 143
投稿日時: 2009-03-04 12:14
あかりさん、こんにちは。

引用:

あかりさんの書き込み (2009-03-04 08:52) より:
今回はDBへのストアドを使用できるので、以下のようなストアドを作成しました。



せっかくなので、スカラ値@keyvalueを返すストアドファンクションの方が便利ではないでしょうか?
あかり
常連さん
会議室デビュー日: 2009/02/18
投稿数: 38
投稿日時: 2009-03-04 14:35
よっしー様回答ありがとうございます。

>せっかくなので、スカラ値@keyvalueを返すストアドファンクションの方が便利ではないでしょうか?

とはどういうことでしょうか?

提示させていただいたようにした理由としましては、
あまりSQLを複雑にするとDBに負荷がかかる気がするという点。
ExecuteNonqueryでの実行がもっとも早いという程度の理由です。

もっとよい方法がありましたら、教えていただけたらありがたいです。

スキルアップ/キャリアアップ(JOB@IT)