MW211 EXIT

devlog
MSSQL/対等外部結合
2015年04月22日
外部結合をつかって、二つの表を対等外部結合してみた。
┌──────────────────────────────────────┐
│SELECT ISNULL([表A].[キー],[表B].[キー]) AS [キー],                       │
│       [表A].[項目A],                                                     │
│       [表B].[項目B]                                                      │
│    FROM [表A]                                                             │
│        FULL JOIN [表B]                                                    │
│          ON [表B].[キー] = [表A].[キー]                                  │
└──────────────────────────────────────┘
結果は上々で、以下三パターンのレコードとなった(もちろんキーの重複はなし)。
┌──┬───┬───┐
│キー│項目A│項目B│
├──┼───┼───┤
│キー│項目A│  -  │
├──┼───┼───┤
│キー│  -  │項目B│
└──┴───┴───┘

これに気を良くして、三つの表でこれを試みた。
┌──────────────────────────────────────┐
│SELECT ISNULL([表A].[キー],ISNULL([表B].[キー],[表C].[キー])) AS [キー], │
│       [表A].[項目A],                                                     │
│       [表B].[項目B],                                                     │
│       [表C].[項目C]                                                      │
│    FROM [表A]                                                             │
│        FULL JOIN [表B]                                                    │
│          ON [表B].[キー] = [表A].[キー]                                  │
│        FULL JOIN [表C]                                                    │
│          ON [表C].[キー] = [表A].[キー]                                  │
└──────────────────────────────────────┘
すると基幹となる表がない場合、二つに分裂してしまった。
┌──┬───┬───┬───┐
│キー│項目A│項目B│項目C│
├──┼───┼───┼───┤
│キー│項目A│項目B│  -  │
├──┼───┼───┼───┤
│キー│項目A│  -  │項目C│
├──┼───┼───┼───┤
│キー│項目A│  -  │  -  │
├──┼───┼───┼───┤
│キー│  -  │項目B│項目C│
├──┼───┼───┼───┤
│キー│  -  │項目B│  -  │←二件レコードができてしまう
│キー│  -  │  -  │項目C│
└──┴───┴───┴───┘

なので、トーナメントの二段階選抜的な形にしなければならない。
┌──────────────────────────────────────┐
│SELECT ISNULL([連合D].[キー],[表C].[キー]) AS [キー],                     │
│       [連合D].[項目A],                                                   │
│       [連合D].[項目B],                                                   │
│       [表C].[項目C]                                                      │
│    FROM (                                                                  │
│        SELECT ISNULL([表A].[キー],[表B].[キー]) AS [キー],               │
│               [表A].[項目A],                                             │
│               [表B].[項目B]                                              │
│            FROM [表A]                                                     │
│                FULL JOIN [表B]                                            │
│                  ON [表B].[キー] = [表A].[キー]                          │
│    )AS [連合D]                                                            │
│        FULL JOIN [表C]                                                    │
│          ON [表C].[キー] = [連合D].[キー]                                │
└──────────────────────────────────────┘

でも、これだと四つ以上になった時に複雑度が増していきそうなので
(でもそれこそトーナメント式(B木)で書けたりして(でもいずれにせよ煩雑になりそう))
以下の様に、基準データをあらかじめ決めてから、
そこに左外部結合していくのがいいかも。
┌──────────────────────────────────────┐
│SELECT [基準D].[キー],                                                     │
│       [表A].[項目A],                                                     │
│       [表B].[項目B],                                                     │
│       [表C].[項目C]                                                      │
│    FROM (                                                                  │
│        SELECT [キー] FROM [表A]                                           │
│        UNION                                                               │
│        SELECT [キー] FROM [表B]                                           │
│        UNION                                                               │
│        SELECT [キー] FROM [表C]                                           │
│    ) AS [基準D]                                                           │
│        LEFT JOIN [表A]                                                    │
│          ON [表A].[キー] = [基準D].[キー]                                │
│        LEFT JOIN [表B]                                                    │
│          ON [表B].[キー] = [基準D].[キー]                                │
│        LEFT JOIN [表C]                                                    │
│          ON [表C].[キー] = [基準D].[キー]                                │
└──────────────────────────────────────┘
分類:MSSQL
ExcelVBA/CopyFromRecordsetは便利だが
2015年04月21日
「.CopyFromRecordset」だとあらかじめ設定していた書式が効かない。

仕方がないので、別途以下みたいな感じで値の貼り付けを行う必要がある。
┌──────────────────────────────────────┐
│With .Columns(1)                                                            │
│    .Value = .Value                                                         │
│    .AutoFit                                                                │
│End With                                                                    │
└──────────────────────────────────────┘

ただ、根本的に解決するには、以下の様に一件ずつ読み込む方式に
変更してしまうのがいいだろう。
┌──────────────────────────────────────┐
│Dim テーブル As New ADODB.Recordset                                         │
├──────────────────────────────────────┤
│Cells(2, 1).CopyFromRecordset テーブル                                      │
└──────────────────────────────────────┘
  ↓
┌──────────────────────────────────────┐
│Dim テーブル As New ADODB.Recordset                                         │
├──────────────────────────────────────┤
│y = 2                                                                       │
│Do Until テーブル.EOF                                                       │
│    For x = 1 To テーブル.Fields.Count                                      │
│        Cells(y, x).Value = テーブル.Fields(x - 1).Value                    │
│    Next x                                                                  │
│    y = y + 1                                                               │
│    テーブル.MoveNext                                                       │
│Loop                                                                        │
└──────────────────────────────────────┘
分類:ExcelVBA
ExcelVBA/ファイル(ブック)の保存
2015年04月20日
作業中のブックを保存するのは以下のような感じ。
┌──────────────────────────────────────┐
│ActiveWorkbook.SaveAs fileName:="出力ファイル.xls", _                       │
│                      FileFormat:=XlFileFormat.xlExcel8                     │
├──────────────────────────────────────┤
│ActiveWorkbook.SaveAs fileName:="出力ファイル.xlsx", _                      │
│                      FileFormat:=XlFileFormat.xlOpenXMLWorkbook            │
└──────────────────────────────────────┘
#上段が「.xls」形式、下段が「.xlsx」形式

保存ダイアログを出してブックを保存するのは以下のような感じ。
┌──────────────────────────────────────┐
│Application.Dialogs(xlDialogSaveAs).Show arg1:="出力ファイル.xls", _        │
│                                         arg2:=XlFileFormat.xlExcel8        │
├──────────────────────────────────────┤
│Application.Dialogs(xlDialogSaveAs).Show arg1:="出力ファイル.xlsx", _       │
│                                         arg2:=XlFileFormat.xlOpenXMLWorkbook
└──────────────────────────────────────┘
#上段が「.xls」形式、下段が「.xlsx」形式

いずれも、最後に保存しないで閉じるとかを組み合わせるだろう。
┌──────────────────────────────────────┐
│ActiveWorkbook.Close SaveChanges:=False                                     │
└──────────────────────────────────────┘
分類:ExcelVBA
MSSQL/年月で集計
2015年04月19日
日付データ(日時データ)を月毎に集計する方法。
┌──────────────────────────────────────┐
│SELECT LEFT(CONVERT(varchar, [日時], 111), 7) AS [年月],                    │
│       SUM([値])                              AS [合計]                     │
│    FROM [表]                                                               │
│    GROUP BY LEFT(CONVERT(varchar, [製造完了日時], 111), 7);                │
└──────────────────────────────────────┘
「YYYY/MM/DD」の形式にして、「YYYY/MM」だけ見て集計する。
分類:MSSQL
MSSQL/四捨五入
2015年04月18日
小数第二位までで四捨五入する場合は、以下のような感じ。
┌──────────────────────────────────────┐
│ROUND([値], 2)                                                              │
└──────────────────────────────────────┘
でもこれだと「1.230000」後ろに「0」が並ぶので、
これが嫌ならキャストしてあげる。
┌──────────────────────────────────────┐
│CONVERT(decimal(8, 2), ROUND([値], 2))                                      │
└──────────────────────────────────────┘
「1.23」になる。
分類:MSSQL
Thunderbird/メールの文字が変わる場合
2015年04月17日
先方からもらったメールの文字フォントが違うと
返信してもフォントが変わったままになる場合がある。

この原因は「charset」の設定の違いによるもの
・「Content-Type: text/plain; charset="iso-2022-jp"」
・「Content-Type: text/plain; charset="UTF-8"」

後者で文字が変わる場合、以下のように設定を行うと、解消できる。

「ツール」→「オプション」→「表示」→「書式」→「詳細設定」で以下の設定をする。
┌──────────────────────────────────────┐
│フォントと文字エンコーディング                                              │
├──────────────────────────────────────┤
│┌文字エンコーディング──────────────────────────┐│
││メッセージの送受信に使用する既定の文字エンコーディングを設定します。    ││
││              ┌──────────┬─┐                              ││
││送信メッセージ│日本語(ISO-2022-JP) │▼│                              ││
││              ├──────────┼─┤                              ││
││受信メッセージ│日本語(ISO-2022-JP) │▼│                              ││
││              └──────────┴─┘                              ││
││■可能であれば返信メッセージに既定の文字エンコーディングを使用する      ││
│└────────────────────────────────────┘│
└──────────────────────────────────────┘
但し、UTF-8依存文字が混じっていると、変換できずUTF-8のままとなる。
分類:Thunderbir
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
前へ 1 … 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 … 156 次へ