MW211 EXIT

devlog
VB.net/トランザクション処理の実装
2015年04月16日
(1) 「プロジェクト>プロパティ>参照」にて「System.Transactions」を追加
(2) 使用するソースコードの冒頭にて、
    上記をインクルードする「Imports System.Transactions」
(3) 以下のような感じで、Usingで囲えば、その範囲がトランザクション処理になる
    ┌──────────────────────────────────┐
    │Using トランザクション As New TransactionScope()                    │
    │    更新処理                                                        │
    │    トランザクション.Complete()     ' コミット                      │
    │End Using                                                           │
    └──────────────────────────────────┘
    コミット(.Complete())しないで、そこから出ると、自動でロールバックになる
分類:VB.net
MSSQL/共通テーブル式(CTE)
2015年04月12日
WITH句問い合わせのことを、共通テーブル式(CTE)という。
分類:MSSQL
SQL/COUNT()の勘違い
2015年04月11日
昔、「COUNT()」は、種類の件数をカウントするものだと勘違いしていた。

┌──────────────────────────────────────┐
│SELECT COUNT(*) FROM [表];                                                  │
└──────────────────────────────────────┘
つまり、上記みたいな場合いっぱい件数があっても、
下記みたいな場合、「2件」になるという勘違いだ。
┌──────────────────────────────────────┐
│SELECT COUNT([性別]) FROM [表];                                             │
└──────────────────────────────────────┘

これは、こうしたらそのように(「2件」)になる。
┌──────────────────────────────────────┐
│SELECT COUNT(DISTINCT [性別]) FROM [表];                                    │
└──────────────────────────────────────┘

つまり、「COUNT()」は、NULL以外の件数をカウントするものなのだ。

というわけで、以下はいずれも全件数を取得できるというわけだ。
┌──────────────────────────────────────┐
│SELECT COUNT(*) FROM [表];                                                  │
├──────────────────────────────────────┤
│SELECT COUNT([主キー]) FROM [表];                                           │
├──────────────────────────────────────┤
│SELECT COUNT([複合主キーの一部列]) FROM [表];                               │
├──────────────────────────────────────┤
│SELECT COUNT([非NULL項目]) FROM [表];                                       │
└──────────────────────────────────────┘
分類:SQL
MSSQL/入れ子とADOとストアドプロシージャ
2015年04月10日
ADODBの入れ子と、ストアドプロシージャの入れ子を合成させた場合
途中のロールバックがどういう影響を与えるかまとめてみた。
┌──────────────────────────────────────┐
│┌.BeginTrans                           │大抵の場合、DB側で                │
││┌.BeginTrans                         │入れ子をサポートしていないので、  │
│││  ├─────────→ 有効?     │二つ目の「.BeginTrans」で         │
││└.CommitTrans                        │「このセッションでは、これ以上の  │
││┌.BeginTrans                         │  トランザクションを              │
│││  ├─────────→ 無効       │  開始できません」エラーとなる    │
││└.RollbackTrans                      │                                  │
│└.CommitTrans          ─→ 問題なし? │なので、実態不明                  │
└──────────────────────────────────────┘
                                       +                                       
┌──────────────────────────────────────┐
│┌BEGIN TRANSACTION                                                         │
││┌BEGIN TRANSACTION                                                       │
│││  ├─────────→ 全滅(無効)                                     │
││└COMMIT TRANSACTION                                                      │
││┌BEGIN TRANSACTION                                                       │
│││  ├─────────→ 全滅(無効)                                     │
││└ROLLBACK TRANSACTION                                                    │
│└COMMIT TRANSACTION    ─→ 例外                                           │
└──────────────────────────────────────┘
                                       ||                                       
┌──────────────────────────────────────┐
│┌.BeginTrans                                                               │
││┌BEGIN TRANSACTION                                                       │
│││  ├─────────→ 全滅(無効)                                     │
││└COMMIT TRANSACTION                                                      │
││┌BEGIN TRANSACTION                                                       │
│││  ├─────────→ 全滅(無効)                                     │
││└ROLLBACK TRANSACTION                                                    │
│└.CommitTrans          ─→ 問題なし                                       │
└──────────────────────────────────────┘
ADODBの入れ子が実態がよくわからないのだが
実験した範囲では、全ロールバック(全滅)するってのが基本のようだ。
トランザクションが終わっているのに「COMMIT TRANSACTION」は蛇足だろうと
例外になるものの、「.CommitTrans」は大目にみてくれる(?)ようだ。
もちろん「.BeginTrans」と辻褄が合わないとエラーとなるけど。
分類:MSSQL
MSSQL/トランザクション入れ子(3)実際の動き
2015年04月09日
トランザクションに入れ子があり、その途中で例外が発生した場合
どのように動くかを確認してみると…
┌──────────────────────────────────────┐
│BEGIN TRY                           ■                                      │
│    BEGIN TRANSACTION;              ■                                      │
│    -- ----------------------       ■                                      │
│    BEGIN TRY                       ■                                      │
│        BEGIN TRANSACTION;          ■                                      │
│        SELECT 1/0;  --例外発生     ★─┐◎例外発生                        │
│        COMMIT TRANSACTION;         □  │                                  │
│    END TRY                         □  │                                  │
│    BEGIN CATCH                     ■←┘                                  │
│        ROLLBACK TRANSACTION;       ■    ①外側のトランザクションも終了    │
│    END CATCH;                      ■                                      │
│    -- ----------------------       ■                                      │
│    COMMIT TRANSACTION;             ★─┐②終了済みのため例外              │
│END TRY                             □  │                                  │
│BEGIN CATCH                         ■←┘                                  │
│    ROLLBACK TRANSACTION;           ★─→③終了済みのため例外              │
│END CATCH;                          ■     (TRY-CATCH外のためメッセージ出力)│
└──────────────────────────────────────┘
入れ子の階層をさらに一つ足した場合は…
┌──────────────────────────────────────┐
│BEGIN TRY                           ■                                      │
│    BEGIN TRANSACTION;              ■                                      │
│    -- -------------------------    ■                                      │
│    BEGIN TRY                       ■                                      │
│        BEGIN TRANSACTION;          ■                                      │
│        -- ----------------------   ■                                      │
│        BEGIN TRY                   ■                                      │
│            BEGIN TRANSACTION;      ■                                      │
│            SELECT 1/0;  --例外発生 ★─┐◎例外発生                        │
│            COMMIT TRANSACTION;     □  │                                  │
│        END TRY                     □  │                                  │
│        BEGIN CATCH                 ■←┘                                  │
│            ROLLBACK TRANSACTION;   ■    ①外側のトランザクションも終了    │
│        END CATCH;                  ■                                      │
│        -- ----------------------   ■                                      │
│        COMMIT TRANSACTION;         ★─┐②終了済みのため例外              │
│    END TRY                         □  │                                  │
│    BEGIN CATCH                     ■←┘                                  │
│        ROLLBACK TRANSACTION;       ★─┐③終了済みのため例外              │
│    END CATCH;                      □  │                                  │
│    -- --------------------------   □  │                                  │
│    COMMIT TRANSACTION;             □  │                                  │
│END TRY                             □  │                                  │
│BEGIN CATCH                         ■←┘                                  │
│    ROLLBACK TRANSACTION;           ★─→④終了済みのため例外              │
│END CATCH;                          ■     (TRY-CATCH外のためメッセージ出力)│
└──────────────────────────────────────┘

ちなみ、トランザクションが終了済みのため例外が発生した場合の
エラーメッセージは以下の通りである
┌──────────────────────────────────────┐
│メッセージ 3903、レベル 16、状態 1                                          │
│ROLLBACK TRANSACTION 要求に対応する BEGIN TRANSACTION がありません。        │
├──────────────────────────────────────┤
│メッセージ 3902、レベル 16、状態 1                                          │
│COMMIT TRANSACTION 要求に対応する BEGIN TRANSACTION がありません。          │
└──────────────────────────────────────┘
TRY-CATCHで捕捉された場合は、エラーメッセージは抑止されるので
出力されるのは最後の一回だけとなる

見てのとおり、字面上ては「BEGIN」と「COMMIT(ROLLBACK)」が対になっていても
実際は、思いっきり破綻してしまうのだ。

なお、「PRINT @@TRANCOUNT;」で「BEGIN」の階層数が確認できるのだが、
これを見ていると、「BEGIN」の都度、順調にカウントアップしていくのだが、
最初の「ROLLBACK」で一気に「0」になってしまうのがわかる。
分類:MSSQL
MSSQL/トランザクション入れ子(2)コミットとロールバック
2015年04月08日
入れ子における、内側と外側(大外)の相互関係は以下の通り
┌─────────┬───────────────┐
│                  │          外側(大外)          │
│                  ├───────┬───────┤
│                  │●コミット    │○ロールバック│
├─┬───────┼───────┼───────┤
│内│●コミット    │●コミット    │○ロールバック│
│  ├───────┼───────┼───────┤
│側│○ロールバック│☆ロールバック│×(例外)      │
└─┴───────┴───────┴───────┘
  ・内側のコミットは意味をなさない(事実上無視)
    →外側(大外)がコミットならコミット、
      外側(大外)がロールバックならロールバック
  ・内側のロールバックは外側(大外)のロールバックを行う
    よって、さらに外側でロールバックを行うと
    ロールバック済みなので例外(エラー)となる

┌──────────────────────────────────────┐
│内側のロールバックは、外側に影響与え過ぎなので控えたとして                  │
│内側のコミットは役立たずだし(はっきりいって意味がない)                      │
│なんか、入れ子にしても意味がなさそう                                        │
└──────────────────────────────────────┘
分類:MSSQL
MSSQL/トランザクション入れ子(1)対
2015年04月07日
┌──────────────────────────────────────┐
│Q.「BEGIN TRANSACTION」と                                                 │
│    「COMMIT TRANSACTION」(もしくは「ROLLBACK TRANSACTION」)は              │
│    必ず一対でなければならない?                                            │
└──────────────────────────────────────┘
  A.必ず一対でなければならない
     但し、ストアドプロシージャの記述は一対でなくても定義は可能
     (実行時にエラーが発生)
     また逆に、対に記述したつもりでも、入れ子のロールバックで
     想定していた対が崩壊すると、実行時にエラーとなってしまう
分類:MSSQL
MSSQL/トランザクションの片方だけ
2015年04月06日
┌──────────────────────────────────────┐
│CREATE PROCEDURE [dbo].[トランザクション開始]                               │
│AS                                                                          │
│BEGIN                                                                       │
│    BEGIN TRANSACTION;                                                      │
│END;                                                                        │
├──────────────────────────────────────┤
│CREATE PROCEDURE [dbo].[トランザクション終了]                               │
│AS                                                                          │
│BEGIN                                                                       │
│    COMMIT TRANSACTION;                                                     │
│END;                                                                        │
└──────────────────────────────────────┘
トランザクション開始と終了をそれぞれに分けて
ストアドプロシージャに定義することができる。

できる…のだが。
いたるところで怒られまくる。
┌──────────────────────────────────────┐
│EXECUTE [dbo].[トランザクション終了];                                       │
└──────────────────────────────────────┘
  メッセージ 3902、レベル 16、状態 1、プロシージャ トランザクション終了
  COMMIT TRANSACTION 要求に対応する BEGIN TRANSACTION がありません。

┌──────────────────────────────────────┐
│EXECUTE [dbo].[トランザクション開始];                                       │
└──────────────────────────────────────┘
  メッセージ 266、レベル 16、状態 2、プロシージャ トランザクション開始
  EXECUTE 後のトランザクション数は、BEGIN ステートメントと
   COMMIT ステートメントの数が一致していないことを示しています。
  以前の数 = 0、現在の数 = 1。

┌──────────────────────────────────────┐
│EXECUTE [dbo].[トランザクション終了];                                       │
└──────────────────────────────────────┘
  メッセージ 266、レベル 16、状態 2、プロシージャ トランザクション終了
  EXECUTE 後のトランザクション数は、BEGIN ステートメントと
   COMMIT ステートメントの数が一致していないことを示しています。
  以前の数 = 1、現在の数 = 0。
  ★→これはさすがによくないかい?不一致が解消されたんだから

┌──────────────────────────────────────┐
│EXECUTE [dbo].[トランザクション終了];                                       │
└──────────────────────────────────────┘
  メッセージ 3902、レベル 16、状態 1、プロシージャ トランザクション終了
  COMMIT TRANSACTION 要求に対応する BEGIN TRANSACTION がありません。
  ★→「現在の数」がマイナスに突入すると本メッセージになる
分類:MSSQL
MSSQL/今日は渋谷で5時
2015年04月05日
┌──────────────────────────────────────┐
│SELECT DATEADD(hour, 17, CONVERT(datetime, CONVERT(date, GETDATE())));      │
└──────────────────────────────────────┘
「GETDATE()」で現在日どころか、現在時刻まで取得できてしまうので、
一旦「date型」に変換することにより、時刻をクリアしてしまう。
さらに「DATEADD(hour,」で時刻を加算すれば、お望みの時刻にできるというもの。

ちなみに、「GETDATE()」を「int型」に変換することにより、
実は小数部にあたる時刻をクリアするという方法もあるらしいが、
世界標準時と日本時間の関係でおかしくなる場合があるので注意。
分類:MSSQL
MSSQL/ORDER BYの別列名
2015年04月04日
ORDER BYには別列名(AS列名)を指定できる。

以下の場合、「[表].[列2]」で並び替えが行われる。
┌──────────────────────────────────────┐
│SELECT [列1] AS [列2],                                                      │
│       [列2] AS [列1]                                                       │
│    FROM [表]                                                               │
│    ORDER BY [列1] ASC;                                                     │
└──────────────────────────────────────┘

表を直接してすれば、別列名ではなくそれで並び替えが行われる。
┌──────────────────────────────────────┐
│SELECT [列1] AS [列2],                                                      │
│       [列2] AS [列1]                                                       │
│    FROM [表]                                                               │
│    ORDER BY [表].[列1] ASC;                                                │
└──────────────────────────────────────┘
上記の場合は、「[表].[列1]」で並び替えが行われる。

基本的な以下(「[表].[列1]」で並び替えが行われる)と混同しないように注意したい。
┌──────────────────────────────────────┐
│SELECT [列1],                                                               │
│       [列2]                                                                │
│    FROM [表]                                                               │
│    ORDER BY [列1] ASC;                                                     │
└──────────────────────────────────────┘
いろいろ編集しているとやらかしそうなところだ。
分類:MSSQL
前へ 1 … 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 … 156 次へ