【 SQLの窓1.5(改)でTransact-SQLを学ぶ 】

1. ADOとTransact-SQL
2. カーソルを使ったループ処理
3. フェッチループ内での更新

プログラミングとしてのTransact-SQL
  • Transact-SQLは、最終的には CREATE PROCEDURE でサーバ側に
    登録できる記述方法ですが、文そのものは使い方を注意すればADO を
    使って他のSQL文を実行するのと同じように使用する事ができます


  • DECLARE
    	@DISP1	varchar(255),
    	@DISP2	int
    select @DISP1 = 商品名,@DISP2 = 単価 from 商品マスタ where コード = '0001'
    select @DISP1,@DISP2
    


  • 上記コードをSQLの窓1.5(改)で実行すると以下のようになります

  • No.
    1パソコン 100600 


  • osql で使用するのならば、select @DISP1,@DISP2 の代わりに print を使用するところですが、ADO では
    その結果を得る事ができません
  • DECLARE
    	@DISP1	varchar(255),
    	@DISP2	int
    select @DISP1 = 商品名,@DISP2 = 単価 from 商品マスタ where コード = '0001'
    print @DISP1
    print @DISP2
    
  • また、変数を使用した select 構文はデータを戻しませんし、変数に値を代入する SELECT ステートメントを、
    データ検索操作と組み合わせることはできません。

  • DECLARE
    	@DISP1	varchar(255),
    	@DISP2	int
    select @DISP1 = 商品名,単価 from 商品マスタ where コード = '0001'
    これはエラー
     
    DECLARE
    	@DISP1	varchar(255),
    	@DISP2	int
    select @DISP1 = 商品名,@DISP2 = 単価 from 商品マスタ where コード = '0001'
    なにも戻さない
    


    注意点
  • print を使用しない
  • select でデータを戻す


  • 以下は、FETCH ループの骨格です

  • /******************
     定義
    ******************/
    DECLARE
    	@列A データ型,
    	@列B データ型,
    	@列C データ型,
    	@LOOP int
     
    /******************
     初期処理
    ******************/
    set @LOOP = 1
     
    /******************
     前処理
    ******************/
    DECLARE CURSOR_FETCH cursor for
    select 
    	列A,
    	列B,
    	列C
    	from テーブル名
     
    open CURSOR_FETCH
     
    /******************
     ループ
    ******************/
    While(@LOOP = 1)
    Begin
    	Fetch CURSOR_FETCH
    		into
    			@列A,
    			@列B,
    			@列C
    	if (@@FETCH_STATUS != 0)
    		Begin
    		break
    	End
     
    	処理
     
    End
     
    /******************
     後処理
    ******************/
    close CURSOR_FETCH
    DEALLOCATE CURSOR_FETCH
    


    注意点
  • Begin 〜 End ブロックの使用方法がポイントとなります

  • While や if 〜 else 等の制御構文自身はブロックを作成できないので、
    Begin 〜 End ブロックの助けを借ります

  • 特に if 構文をブロックとして見立てる為に Begin の End を if の終端に見せる
    ように記述しています


  • 以下に実行できるサンプルを示します

  • /******************
     定義
    ******************/
    DECLARE
    	@コード	varchar(4),
    	@商品名	varchar(50),
    	@単価	int,
    	@LOOP	int
     
    /******************
     初期処理
    ******************/
    set @LOOP = 1
     
    /******************
     前処理
    ******************/
    DECLARE CURSOR_FETCH cursor for
    select 
    	コード,
    	商品名,
    	単価
    	from 商品マスタ
     
    open CURSOR_FETCH
     
    /******************
     ループ
    ******************/
    While(@LOOP = 1)
    Begin
    	Fetch CURSOR_FETCH
    		into
    			@コード,
    			@商品名,
    			@単価
    	if (@@FETCH_STATUS != 0)
    		Begin
    		break
    	End
     
    	select
    		@コード as コード,
    		@商品名 as 商品名,
    		@単価 as 単価
     
    End
     
    /******************
     後処理
    ******************/
    close CURSOR_FETCH
    DEALLOCATE CURSOR_FETCH
    


  • 上記コードをSQLの窓1.5(改)で実行すると以下のようになります

  • No.コード商品名単価
    10001 パソコン 100600 
    No.コード商品名単価
    10002 テレビ 50600 


  • ストアードプシージャとしては複雑な更新手段を提供するこちらが本来の目的となります

  • /******************
     定義
    ******************/
    DECLARE
    	@コード	varchar(4),
    	@商品名	varchar(50),
    	@単価	int,
    	@新単価	int,
    	@LOOP	int
     
    /******************
     初期処理
    ******************/
    set @LOOP = 1
     
    /******************
     前処理
    ******************/
    DECLARE CURSOR_FETCH cursor for
    select 
    	コード,
    	商品名,
    	単価
    	from 商品マスタ
     
    open CURSOR_FETCH
     
    /******************
     ループ
    ******************/
    While(@LOOP = 1)
    Begin
    	Fetch CURSOR_FETCH
    		into
    			@コード,
    			@商品名,
    			@単価
    	if (@@FETCH_STATUS != 0)
    		Begin
    		break
    	End
     
    	select @新単価 = 在庫評価単価 from 在庫マスタ
    		where 商品コード = @コード
     
    	IF @@ROWCOUNT <> 0
    		Begin
    		update 商品マスタ set 単価 = @新単価
    			where current of CURSOR_FETCH
    		select @単価 as 更新前単価,@新単価 as 更新後単価
    	End
     
    End
     
    /******************
     後処理
    ******************/
    close CURSOR_FETCH
    DEALLOCATE CURSOR_FETCH
    


  • 上記コードをSQLの窓1.5(改)で実行すると以下のようになります

  • No.更新前単価更新後単価
    1100600 110000 
    No.更新前単価更新後単価
    150600 40000 


  • @@ROWCOUNT は、直前の SQLステートメントに影響を受けた行数を示します

  • where current of CURSOR_FETCH は、「カーソルが現在処理している行」という条件です