none
Sql Server2012 の シーケンスについて RRS feed

  • 質問

  • 現在 Java5 + SQL Server2012 で開発をしています。

    シーケンスは以下のHPの CREATE SEQUENCE とほぼ同じで、キャッシュなしで作成しています。

    http://msdn.microsoft.com/ja-jp/library/hh272694(v=vs.103).aspx

    問題となっているのは、JavaからJDBC経由でシーケンス番号を取得すると、増分が余計に加算されて取得されることです。
    上記HPのシーケンスで現在値10 とした場合に、シーケンス番号を「SELECT NEXT VALUE FOR dbo.Seq1 AS SEQ」のSQLで
    取得する値と、"11"が返却されるのではなく、"12"が返却されます。

    SQL Server Management Studio や JDBCを使用してDBアクセスするツール「dbvisualizer」などから、上述のSQLを実行すると、
    Javaのように余分に加算されず、+1された値が取得できます。

    jdbcの設定では、特別なプロパティで値を指定していません。

    何かご存知の方がいましたら、教えてください。

    よろしくお願いいたします。

    ※確認に使用したサンプルソースを添付します。

    import java.sql.Connection;
    import java.sql.Driver;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Properties;
    
    public class SqlserverConnTest {
          public static void main(String[] args) {
            try {
                  Driver d = (Driver) Class.forName(
                    "com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
                  String connUrl =
                    "jdbc:sqlserver://localhost:1433;DatabaseName=soil;ProgramName=geds;SelectMethod=cursor;"
                      + "integratedSecurity=false;user=****;password=****";
                  Connection con = d.connect(connUrl, new Properties());
    
                  String SQL = "SELECT NEXT VALUE FOR dbo.Seq1 AS seq_no";
                  Statement stmt = con.createStatement();
                  ResultSet rs = stmt.executeQuery(SQL);
    
                  while (rs.next()) {
                    System.out.println(
                      rs.getString("seq_no"));
                  }
    
                  rs.close();
                  stmt.close();
                }
                catch (Exception e) {
                  e.printStackTrace();
                }
          }
    }
    

    2013年1月9日 23:40

回答

  • 以下、ご参考までに連携します。

     

    個人的に、ResultSetで取得して、next()関数が1回かまされることで、「SELECT NEXT VALUE FOR」がもう一度評価されてしまっているからでは、、と思いました。

    ※ 私の環境にはSQLServer 2012が入っていないため、実際に動かしてみたわけではないのですが。。

     

    上記の仮定を検証するため、以下のような操作を実施するのはいかがでしょうか。

    【前提】

    Seq1シーケンスの現在値が「10」

    【実施操作】

    上記プログラムのwhile文をコメントアウトし、実行。

    【確認内容】

    Seq1シーケンスの現在値が「11」(前提の値+1)になっているか、確認。

     

    ※ シーケンスのカレント値の確認

    参考サイト:CREATE SEQUENCE (Transact-SQL)

    SELECT current_value 
    FROM sys.sequences
    WHERE name = 'Seq1' ;

    • 編集済み kyk_nk 2013年2月1日 4:44 修正
    • 回答の候補に設定 佐伯玲 2013年2月4日 0:16
    • 回答としてマーク 佐伯玲 2013年3月4日 1:21
    2013年2月1日 4:43
  • 少し時間が空いてしまいましたが、以下補足させていただきます。

     

    やはり、「ResultSet rs = stmt.executeQuery(SQL);」を実行した時点と、「while (rs.next()) {」の両方でシーケンスがインクリメントされていたためであることがわかりました。

    シーケンスのインクリメントした値を取得したい場合は、

    SELECT NEXT VALUE FOR dbo.Seq1 AS seq_no

    を実行した後に、

    SELECT current_value FROM sys.sequences s WHERE s.name = 'Seq1'

    というかたちで、カレント値を別途取得するなどの対応がよいかと思います。

     

    SQLServer 2012をインストールできるPCに変更したため、せっかくなので検証させていただきました。

    シーケンスは、インクリメントが正常に動くことが機能の根幹ですから、きちんと解決しておきたいと思ったためです。

    • 回答としてマーク 佐伯玲 2013年3月4日 1:21
    2013年3月2日 12:31

すべての返信

  • 以下、ご参考までに連携します。

     

    個人的に、ResultSetで取得して、next()関数が1回かまされることで、「SELECT NEXT VALUE FOR」がもう一度評価されてしまっているからでは、、と思いました。

    ※ 私の環境にはSQLServer 2012が入っていないため、実際に動かしてみたわけではないのですが。。

     

    上記の仮定を検証するため、以下のような操作を実施するのはいかがでしょうか。

    【前提】

    Seq1シーケンスの現在値が「10」

    【実施操作】

    上記プログラムのwhile文をコメントアウトし、実行。

    【確認内容】

    Seq1シーケンスの現在値が「11」(前提の値+1)になっているか、確認。

     

    ※ シーケンスのカレント値の確認

    参考サイト:CREATE SEQUENCE (Transact-SQL)

    SELECT current_value 
    FROM sys.sequences
    WHERE name = 'Seq1' ;

    • 編集済み kyk_nk 2013年2月1日 4:44 修正
    • 回答の候補に設定 佐伯玲 2013年2月4日 0:16
    • 回答としてマーク 佐伯玲 2013年3月4日 1:21
    2013年2月1日 4:43
  • 少し時間が空いてしまいましたが、以下補足させていただきます。

     

    やはり、「ResultSet rs = stmt.executeQuery(SQL);」を実行した時点と、「while (rs.next()) {」の両方でシーケンスがインクリメントされていたためであることがわかりました。

    シーケンスのインクリメントした値を取得したい場合は、

    SELECT NEXT VALUE FOR dbo.Seq1 AS seq_no

    を実行した後に、

    SELECT current_value FROM sys.sequences s WHERE s.name = 'Seq1'

    というかたちで、カレント値を別途取得するなどの対応がよいかと思います。

     

    SQLServer 2012をインストールできるPCに変更したため、せっかくなので検証させていただきました。

    シーケンスは、インクリメントが正常に動くことが機能の根幹ですから、きちんと解決しておきたいと思ったためです。

    • 回答としてマーク 佐伯玲 2013年3月4日 1:21
    2013年3月2日 12:31
  • こんにちは、T.Ka さん
    フォーラムオペレータの佐伯 玲 です。

    ご投稿いただいてから少し時間がたってしまいましたがその後の状況はいかがでしょうか?
    kyk_nk さんから参考になると思われる情報が寄せられておりましたので、勝手ながら私のほうで「回答としてマーク」とさせて頂きました。

    ご確認、お試しいただいた状況やわからなかった点などこちらのスレッドでご返信いただけましたらと思います。

    宜しくお願いいたします。
    __________________________
    日本マイクロソフト株式会社 フォーラム オペレータ 佐伯 玲

    2013年3月4日 1:21