MW211 EXIT

devlog
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
ZoomIt
2015年03月30日
ZoomItという便利なプレゼン用ツールがある

以下のサイトで入手できる。
【Windows Sysinternals】
  https://technet.microsoft.com/ja-jp/sysinternals

基本操作をまとめてみた。
┌────────┐
│ZoomItの基本操作│
└────────┘
【起動】
  Ctrl+1              :画面を拡大して起動
  Ctrl+2              :画面を拡大せず起動
【画面設定】
  マウス移動           :画面の移動
  ホイール↑           :画面の拡大(↑キーでも可)
  ホイール↓           :画面の縮小(↓キーでも可)
【描画開始】
  左クリック           :開始
  Ctrl+ホイール↑     :線幅の拡大
  Ctrl+ホイール↓     :線幅の縮小
  r                    :線色変更(赤)
  g                    :線色変更(緑)
  b                    :線色変更(青)
  o                    :線色変更(橙)
  p                    :線色変更(桃)
  y                    :線色変更(黄)
【描画】
  ドラッグ             :線
  Shift+ドラッグ      :直線
  Ctrl+ドラッグ       :四角形
  Ctrl+Shift+ドラッグ:矢印線
  Tab+ドラッグ        :円
  t                    :文字入力モード(半角英数のみ)
  e                    :線全削除
  Ctrl+z              :やり直し(なお「Ctrl+y」はなし)
【終了】
  Ctrl+c              :画面キャプチャ
  Ctrl+s              :ファイルに保存
  右クリック           :終了
  Esc                  :終了
【その他】
  Ctrl+3              :カウントダウン(シンキングタイムとかで利用)
  Ctrl+4              :LiveZoom(他は静止画扱い)
分類:IT全般
MSSQL/INSERT FROM SELECTの排他
2015年03月29日
「INSERT FROM SELECT」中は、更新側および参照側の排他状態は
どのようになっているのか?
確かめてみた。

  (1) 非トランザクション下での挙動
    (1-1) 実行中時
            更新側:排他ロック
            参照側:共有ロック

  (2) トランザクション下での挙動
    (2-1) 実行中時
            更新側:排他ロック
            参照側:共有ロック
    (2-2) 実行後コミット前
            更新側:排他ロック
            参照側:ロックなし

参照側は読込の為、共有ロックがかかるが
それはトランザクションの有無に関わらず実行中の間のみ。

気になっていたのが、トランザクション完了待ちで
更新側が排他ロックから抜け出せなかった場合(2-2)
参照側はどうなるのかという点。
こちらは、用が済んだので共有ロックは解除されるのだ。
分類:MSSQL
MSSQL/利用状況モニターのプロセス
2015年03月28日
利用状況モニターのプロセスを出力するSQL文。
┌──────────────────────────────────────┐
│SELECT s.[session_id]                        AS [セッションID],             │
│       CONVERT(char(1), s.[is_user_process]) AS [ユーザープロセス],         │
│       s.[login_name]                        AS [ログイン],                 │
│       CASE                                                                 │
│         WHEN p.[dbid] = 0 THEN N''                                         │
│         ELSE                   ISNULL(DB_NAME(p.[dbid]), N'')              │
│       END AS [データベース],                                               │
│       ISNULL(t.[task_state], N'')           AS [タスクの状態],             │
│       ISNULL(r.[command], N'')              AS [コマンド],                 │
│       ISNULL(s.[program_name], N'')         AS [アプリケーション],         │
│       ISNULL(w.[wait_duration_ms], 0)       AS [待機時間(ミリ秒)],         │
│       ISNULL(w.[wait_type], N'')            AS [待機の種類],               │
│       ISNULL(w.[resource_description], N'') AS [待機リソース],             │
│       ISNULL(CONVERT(varchar, w.[blocking_session_id]), '')                │
│           AS [ブロック元],                                                 │
│       CASE                                                                 │
│         WHEN r2.[session_id] IS NOT NULL                                   │
│          AND (r.[blocking_session_id] = 0 OR r.[session_id] IS NULL) THEN  │
│           '1'                                                              │
│         ELSE                                                               │
│           ''                                                               │
│       END AS [先頭ブロック],                                               │
│       s.[cpu_time]                          AS [Total CPU(ms)] ,           │
│       (s.[reads] + s.[writes]) * 8 / 1024   AS [Total Physical I/O(MB)],   │
│       s.[memory_usage] * (8192 / 1024)      AS [メモリ使用量(KB)],         │
│       ISNULL(r.[open_transaction_count], 0) AS [Open Transactions],        │
│       s.[login_time]                        AS [Login Time],               │
│       s.[last_request_start_time]           AS [Last Request Start Time],  │
│       ISNULL(s.[host_name], N'')            AS [ホスト名],                 │
│       ISNULL(c.[client_net_address], N'')   AS [Net Address],              │
│       ISNULL(t.[exec_context_id], 0)        AS [Execution Context ID],     │
│       ISNULL(r.[request_id], 0)             AS [Request ID],               │
│       ISNULL(g.[name], N'')                 AS [Workload Group]            │
│    FROM [sys].[dm_exec_sessions] AS s                                      │
│        LEFT JOIN [sys].[dm_exec_connections] AS c                          │
│          ON s.[session_id] = c.[session_id]                                │
│        LEFT JOIN [sys].[dm_exec_requests] AS r                             │
│          ON s.[session_id] = r.[session_id]                                │
│        LEFT JOIN [sys].[dm_os_tasks] AS t                                  │
│          ON  r.[session_id] = t.[session_id]                               │
│          AND r.[request_id] = t.[request_id]                               │
│        LEFT JOIN (                                                         │
│            SELECT *,                                                       │
│                   ROW_NUMBER() OVER (PARTITION BY [waiting_task_address]   │
│                                      ORDER BY [wait_duration_ms] DESC      │
│                   ) AS [row_num]                                           │
│                FROM [sys].[dm_os_waiting_tasks]                            │
│        ) AS w                                                              │
│          ON  t.[task_address] = w.[waiting_task_address]                   │
│          AND w.[row_num]      = 1                                          │
│       LEFT JOIN [sys].[dm_exec_requests] AS r2                             │
│         ON s.[session_id] = r2.[blocking_session_id]                       │
│       LEFT JOIN [sys].[dm_resource_governor_workload_groups] AS g          │
│         ON g.[group_id] = s.[group_id]                                     │
│       LEFT JOIN [sys].[sysprocesses] AS p                                  │
│         ON s.[session_id] = p.[spid]                                       │
│    WHERE s.[is_user_process] = 1                                           │
│    ORDER BY s.[session_id];                                                │
└──────────────────────────────────────┘
分類:MSSQL
MSSQL/非クラスタ化インデックスと付加列インデックス
2015年03月27日
┌──────────────────────────────────────┐
│CREATE NONCLUSTERED INDEX [非クラスタ化インデックス] ON [DB].[dbo].[表] (   │
│    [列]                                                                    │
│) INCLUDE (                                                                 │
│    [付加列]                                                                │
│);                                                                          │
└──────────────────────────────────────┘
【非クラスタ化インデックス】
  ・「CREATE NONCLUSTERED INDEX」で生成
  ・主キー(クラスタ化インデックス)や一意キー(後述)とは逆に、
    一意性よりもヒット率が高い列を指定すると効果あり
    #なお、これとは別に「CREATE UNIQUE NONCLUSTERED INDEX」で
      一意キーとしても使える
【付加列インデックス】
  ・「INCLUDE()」で生成
  ・通常のキー(検索キー)とは違い、
    本体(テーブル)に参照しにいくのがめんどくさい列を付加するためのもの
    #カバリングインデックスの改良版

…という解釈でいいの?
(非クラスタ化インデックスが一意性よりもヒット率重視ってとこが特に)
分類:MSSQL
前へ 1 … 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 … 156 次へ