MW211 EXIT

devlog
経営会計/セオリー
2015年02月17日
好き嫌いは別として、基本的なセオリーは以下の通り
────────────────────────────────────────
┌────────────────┐
│現金は手許に長い間あった方がよい│
└────────────────┘
  ・現金を受取るなら早い方がよい(金利分損する(さもないと割引現在価値))(*1)
    →返済日を早める
    →返済日が遅い場合には別途金利分を請求する

  ・現金を支払うなら遅い方がよい(上記の反対)
    →返済日を遅くする

  ・貯金(資産)と借金(負債)は相殺した方がよい(「貯金の利子<借金の利子」なので)
    →繰上返済

  *1:実際に貯金しなくとも、これにより他で借金しないで済めば
      その金利分を得することになる
────────────────────────────────────────
┌─────────────┐
│固定的な費用はない方がよい│
└─────────────┘
  ・無駄な在庫は抱え込まない(保管料がかかる)
    →生産調整(減産)
    →安売り

  ・無駄な設備は抱え込まない(減価償却費がかかる)(*2)
    →稼働率の向上(薄利多売)
    →設備の売却(使う必要がある場合にはリース化)

  ・無駄な人員は抱え込まない(固定労務費がかかる)(*2)
    →稼働率の向上(薄利多売)
    →内製化(外注廃止・派遣切り)
    →解雇(使う必要がある場合には非正規化)

  ・無駄な損失は抱え込まない(税金を早く払うことになる)
    →評価損・減損で適正に費用化

  *2:設備購入(減価償却費)は前払の固定費、
      社員の雇用(労働契約)は後払の固定費と見ることができる
────────────────────────────────────────
┌───────────┐
│身軽な方が優秀に見える│
└───────────┘
  ・無駄な内部留保は抱え込まない(資本回転率が鈍る)
    →配当
────────────────────────────────────────
┌─────────┐
│目立たない方がよい│
└─────────┘
  ・儲かっているように見えれば投資家は安心し、
    儲かっていないように見えれば国は税金をとらない
    →期間ごとに平準化できれば…でも粉飾決算は絶対ダメ
────────────────────────────────────────
分類:経営学
MSSQL/疑似カレンダマスタ
2015年02月16日
2015/01/01以降から今日までの疑似カレンダマスタは
以下のような感じで作成できる。
┌──────────────────────────────────────┐
│SELECT CONVERT(nvarchar,                                                    │
│               DATEADD(DAY, generate_series, getdate()),                    │
│               111) AS [日付]                                               │
│    FROM generate_series(DATEDIFF(DAY,                                      │
│                                  getdate(),                                │
│                                  CONVERT(DATETIME, '2015-01-01')),         │
│                         0,                                                 │
│                         1);                                                │
└──────────────────────────────────────┘

なお、「generate_series()」は、PostgreSQLの関数でMSSQLには存在しないので
自前のユーザ関数で代替(別途参照)。
分類:MSSQL
MSSQL/generate_series()
2015年02月15日
PostgreSQLには、自動で連番テーブルを作成してくれる「generate_series()」という
便利な関数があるが、MSSQLにはない。

ということで、自前で作ると以下のような感じとなる。
┌──────────────────────────────────────┐
│CREATE FUNCTION [dbo].[generate_series] (                                   │
│    @引数開始               int,                                            │
│    @引数終了               int,                                            │
│    @引数増分               int = 1                                         │
│) RETURNS @結果 table (                                                     │
│    [generate_series]       int                                             │
│)                                                                           │
│AS                                                                          │
│BEGIN                                                                       │
│    DECLARE @値             int;                                            │
│    DECLARE @増分           int;                                            │
│    SET @値   = CASE                                                        │
│                  WHEN @引数開始 IS NULL THEN 1                             │
│                  ELSE                        @引数開始                     │
│                END;                                                        │
│    SET @増分 = CASE                                                        │
│                  WHEN @引数増分 IS NULL OR @引数増分 = 0 THEN 1            │
│                  ELSE                                         @引数増分    │
│                END;                                                        │
│    IF SIGN(@増分) =  1 AND @引数開始 > @引数終了                           │
│        RETURN;                                                             │
│    IF SIGN(@増分) = -1 AND @引数開始 < @引数終了                           │
│        RETURN;                                                             │
│    WHILE (1 = 1)                                                           │
│    BEGIN                                                                   │
│        INSERT INTO @結果([generate_series]) VALUES (@値);                  │
│        SET @値 = @値 + @増分;                                              │
│        IF SIGN(@増分) =  1 AND @値 > @引数終了                             │
│            BREAK;                                                          │
│        IF SIGN(@増分) = -1 AND @値 < @引数終了                             │
│            BREAK;                                                          │
│    END;                                                                    │
│    RETURN;                                                                 │
│END;                                                                        │
└──────────────────────────────────────┘
分類:MSSQL
MSSQL/横棒グラフ
2015年02月14日
┌──────────────────────────────────────┐
│SELECT [キー],                                                              │
│       [値],                                                                │
│       REPLICATE('■', [値]) AS [グラフ]                                    │
│    FROM [表];                                                              │
└──────────────────────────────────────┘
「REPLICATE()」は同じ文字を繰り返す。
分類:MSSQL
MSSQL/sysobjects.xtype
2015年02月10日
「sysobjects.xtype」(「SELECT xtype FROM sysobjects;」)の値は以下の通り。
┌─┬────────────────────────────────────┐
│U │テーブル(ユーザテーブル)                                                │
├─┼────────────────────────────────────┤
│V │ビュー                                                                  │
├─┼────────────────────────────────────┤
│P │ストアドプロシージャ                                                    │
│X │拡張ストアドプロシージャ                                                │
│RF│ストアドプロシージャ/レプリケーションフィルタ                          │
├─┼────────────────────────────────────┤
│FN│ストアドファンクション[スカラー型]                                      │
│TF│ストアドファンクション[テーブル型]                                      │
│IF│ストアドファンクション[インラインテーブル型]                            │
├─┼────────────────────────────────────┤
│TR│トリガ                                                                  │
├─┼────────────────────────────────────┤
│PK│主キー制約                                                              │
│UQ│一意制約                                                                │
│F │外部キー制約                                                            │
│C │チェック制約                                                            │
│D │既定値制約                                                              │
├─┼────────────────────────────────────┤
│S │システムテーブル                                                        │
│IT│内部テーブル                                                            │
│SQ│サービスキュー                                                          │
├─┼────────────────────────────────────┤
│PC│ストアドプロシージャ/アセンブリ(CLR)                                   │
│FS│ストアドファンクション[スカラー型]/アセンブリ(CLR)                     │
│FT│ストアドファンクション[テーブル型]/アセンブリ(CLR)                     │
│TA│トリガ/アセンブリ(CLR)                                                 │
│AF│集計関数(CLR)                                                           │
├─┼────────────────────────────────────┤
│L │ログ                                                                    │
│SN│シノニム                                                                │
│TT│テーブルの種類                                                          │
└─┴────────────────────────────────────┘
分類:MSSQL
MSSQL/日時変換
2015年02月09日
「datetime」型を変換する代表例。
┌──────────────────────────────────────┐
│CONVERT(nvarchar, [日時], 108) → hh:mm:ss                                  │
│CONVERT(nvarchar, [日時],  11) → yy/mm/dd                                  │
│CONVERT(nvarchar, [日時], 111) → yyyy/mm/dd                                │
│CONVERT(nvarchar, [日時],  12) → yymmdd                                    │
│CONVERT(nvarchar, [日時], 112) → yyyymmdd                                  │
└──────────────────────────────────────┘

例えば、日時で絞る場合、現在時刻より前で絞ると以下のようになる。
┌──────────────────────────────────────┐
│WHERE [日時] < getdate()                                                    │
└──────────────────────────────────────┘
当然ながら、現在時刻より前であれば本日分も抽出される。

これを前日以前で比較するには以下のような感じに互いに変換してしまえばよい。
┌──────────────────────────────────────┐
│WHERE CONVERT(nvarchar, [日時], 112) < CONVERT(nvarchar, getdate(), 112)    │
└──────────────────────────────────────┘
分類:MSSQL
Windows/WINSとは?
2015年02月08日
「Windows Internet Naming Service」の略。

Windowsネットワークのコンピュータ名をIPアドレスに変換する。

WINSサーバが必要となる。
#Windows版のDNSサーバみたいなもの

WINSサーバは、Windows NTサーバもしくはSambaとなる。
分類:Windows
ExcelVBA/Continue文
2015年02月07日
ExcelVBAではContinue文がない。

純粋構造化プログラムの原則に従ってIf文で対処となるが、
とはいえ、Continue文は便利だ。

で、これは禁断のGoTo文で代替するのが最善のようだ。
┌──────────────────────────────────────┐
│For文                                                                       │
│    If 条件 Then                                                            │
│        GoTo Continue                                                       │
│    End If                                                                  │
│    処理                                                                    │
│Continue:                                                                   │
│Next                                                                        │
└──────────────────────────────────────┘

純粋に処理の流れ通りなら、「Continue:」ラベルは前の方がよいかもしれない。
┌──────────────────────────────────────┐
│For文                                                                       │
│Continue:                                                                   │
│    If 条件 Then                                                            │
│        GoTo Continue                                                       │
│    End If                                                                  │
│    処理                                                                    │
│Next                                                                        │
└──────────────────────────────────────┘
しかし、前方へのGoTo文を許すのは、Continue文代替に限ってとしても、
それこそ禁断中の禁断ともいえる(後方ならまだスパゲティコードは避けられる)

よって、前出の対応の方がよいのではないだろうか。
分類:ExcelVBA
MSSQL/エラーログにSQL発行状況を出力
2015年02月04日
SQLの発行状況をリアルタイムでエラーログに出力する方法。

まず、稼働中のインスタンス名を調べる。
「サービス」の「プロパティ」を参照すると
「サービス名」にインスタンス名が表示されている
→例えば「MSSQL$■」

次に、エラーログの位置を調べる。
例えば以下の辺り。
┌──────────────────────────────────────┐
│C:\Program Files\Microsoft SQL Server\MSSQL12.■\MSSQL\Log\ERRORLOG         │
└──────────────────────────────────────┘

準備が出来たら、調査開始。

MSSQLの以下のフラグをONに設定する。
・T3605=トレース結果をエラーログ出力
・T4032=コマンド(SQL文)をトレースする
「T3605」は設定済みなので「T4032」だけ設定し直す

コマンドプロンプト(管理者権限)で、以下の様に停止し再起動する。
┌──────────────────────────────────────┐
│>net stop MSSQL$■                                                          │
│SQL Server (■) サービスを停止中です.                                       │
│SQL Server (■) サービスは正常に停止されました。                            │
│                                                                            │
│>net start MSSQL$■ /T4032                                                  │
│SQL Server (■) サービスを開始します..                                      │
│SQL Server (■) サービスは正常に開始されました。                            │
└──────────────────────────────────────┘

次に「SQL Server Management Studio」以下のコマンドを実行する。
┌──────────────────────────────────────┐
│dbcc traceon(3605, -1)                                                      │
└──────────────────────────────────────┘

これで、ログにコマンド(SQL文)がエラーログにリアルタイムで出力される。

終了するには以下のコマンドを実行する。
┌──────────────────────────────────────┐
│dbcc traceoff(3605, -1)                                                     │
└──────────────────────────────────────┘
フラグも元に戻したい場合には、MSSQL再起動(サーバ再起動)など
分類:MSSQL
MSSQL/FROM句によるUPDATE文
2015年02月03日
  まず、「UPDATE」文による更新先(出力表)と、「FROM」句による更新元(入力表)は
  以下の様に条件式で結合してあげないと、何を何で更新するのか
  訳が分からなくなり正しく動作しない。
┌──────────────────────────────────────┐
│UPDATE [出力表]                                                             │
│    SET [列] = [入力表].[列]                                                │
│    FROM [入力表]                                                           │
│    WHERE [入力表].[キー] = [出力表].[キー];                                │
└──────────────────────────────────────┘
    以下だと更新されたが意図した更新はできない。
  ┌────────────────────────────────────┐
  │UPDATE [出力表]                                                         │
  │    SET [列] = [入力表].[列]                                            │
  │    FROM [入力表]                                                       │
  └────────────────────────────────────┘
    どうも[入力表]の一件目ですべてを更新したりしているようだが(たまたまか)。
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  但し、更新先と更新元が同じ場合は、同じ表を操作することになるので結合条件不要。
┌──────────────────────────────────────┐
│UPDATE [出力表]                                                             │
│    SET [列] = [出力表].[列]                                                │
│    FROM [出力表]                                                           │
│    WHERE [出力表].[キー] = [出力表].[キー];                                │
├──────────────────────────────────────┤
│UPDATE [出力表]                                                             │
│    SET [列] = [出力表].[列]                                                │
│    FROM [出力表];                                                          │
└──────────────────────────────────────┘
  (これだと更新により値が変わらないので意味がないが、原則として覚えておく)

  なお、「FROM」句の表が一つであれば、別名をつけることもできる。
┌──────────────────────────────────────┐
│UPDATE [出力表]                                                             │
│    SET [列] = [別名].[列]                                                  │
│    FROM [出力表] AS [別名];                                                │
└──────────────────────────────────────┘
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  自己結合で「FROM」句に複数の更新先(出力表)が出現する場合は
  そのうちどれが「UPDATE」文の更新先(出力表)と一致するのか明示する必要があり
  「UPDATE」文は「AS」で別名をつけられない経緯からして
  「FROM」句側もどれか一つ別名をつけないものを用意する必要がある。
┌──────────────────────────────────────┐
│UPDATE [出力表]                                                             │
│    SET [列] = [別名].[列]                                                  │
│    FROM [出力表],                                                          │
│         [出力表] AS [別名]                                                 │
│    WHERE [別名].[キー] = [出力表].[キー];                                  │
└──────────────────────────────────────┘

  上記はOKだが、以下はお互いに譲り合ってる(別名を名乗ってる)のでNG。
┌──────────────────────────────────────┐
│UPDATE [出力表]                                                             │
│    SET [列] = [別名2].[列]                                                 │
│    FROM [出力表] AS [別名1],                                               │
│         [出力表] AS [別名2]                                                │
│    WHERE [別名2].[キー] = [別名1].[キー];                                  │
├──────────────────────────────────────┤
│UPDATE [出力表]                                                             │
│    SET [列] = [別名2].[列]                                                 │
│    FROM [出力表] AS [別名1]                                                │
│        INNER JOIN [出力表] AS [別名2]                                      │
│          ON [別名2].[キー] = [別名1].[キー];                               │
└──────────────────────────────────────┘
  「INNER JOIN」なら回避できるかと思ったが、やっぱりそれもNG。

  但し、「UPDATE」文で別名を(定義するのではなく)使用するという荒業もある。
┌──────────────────────────────────────┐
│UPDATE [別名1]                                                              │
│    SET [列] = [別名2].[列]                                                 │
│    FROM [出力表] AS [別名1],                                               │
│         [出力表] AS [別名2]                                                │
│    WHERE [別名2].[キー] = [別名1].[キー];                                  │
└──────────────────────────────────────┘
 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  従ってまとめると、一件以下の「WHERE」句が必要な気がしないでもないが
  [別名]と[出力表]は(実体として)同じ表なので、必要ないということになる。
┌──────────────────────────────────────┐
│UPDATE [出力表]                                                             │
│    SET [列] = [入力表].[列]                                                │
│    FROM [出力表] AS [別名]                                                 │
│        INNER JOIN [入力表]                                                 │
│          ON [入力表].[キー] = [別名].[キー]                                │
│    WHERE [別名].[キー] = [出力表].[キー];                                  │
├──────────────────────────────────────┤
│UPDATE [出力表]                                                             │
│    SET [列] = [入力表].[列]                                                │
│    FROM [出力表] AS [別名]                                                 │
│        INNER JOIN [入力表]                                                 │
│          ON [入力表].[キー] = [別名].[キー];                               │
└──────────────────────────────────────┘
分類:MSSQL
前へ 1 2 3 次へ