MW211 EXIT

devlog
MSSQL/括弧を含む列名の変更
2014年10月21日
┌──────────────────────────────────────┐
│SP_RENAME '[DB名].[dbo].[表名].[旧列名]', '新列名', 'COLUMN';               │
└──────────────────────────────────────┘
上記とすべきところ、うっかり下記のように変更後の名称にも「[]」をつけてしまった。
┌──────────────────────────────────────┐
│SP_RENAME '[DB名].[dbo].[表名].[旧列名]', '[新列名]', 'COLUMN';             │
└──────────────────────────────────────┘

さぁ大変とばかりに是正しようとして以下を行うも、エラーとなる。
┌──────────────────────────────────────┐
│SP_RENAME '[DB名].[dbo].[表名].[[新列名]]', '新列名', 'COLUMN';             │
└──────────────────────────────────────┘

特殊文字だから「\」とかつけてみて…もダメ。
┌──────────────────────────────────────┐
│SP_RENAME '[DB名].[dbo].[表名].[\[新列名\]]', '新列名', 'COLUMN';           │
└──────────────────────────────────────┘

答えは以下の通り、「""」で囲えばよい。
┌──────────────────────────────────────┐
│SP_RENAME '[DB名].[dbo].[表名]."[新列名]"', '新列名', 'COLUMN';             │
└──────────────────────────────────────┘

ま、途方に暮れたら「Management Studio」で手動で直すこともできるんだけどね。
分類:MSSQL
データベース/削除済みフラグと一意性制約
2014年10月20日
削除レコードを直接DELETEしたくない場合には、削除済みフラグなんかを設ける。
この時問題となるのが、自然キーの一意性制約を邪魔することだ。

例えば、会員№が自然キーでそれが「1」のレコードを削除した場合、
居座ってしまうので、再び会員№「1」のレコードを追加することはできない。

それじゃ、自然キーと削除済みフラグをまとめて一意性制約にするとする。
この場合、二回目以降の削除をすると、削除レコードが重複するので、
削除ができなくなる。

ということで、削除レコードは制約のない履歴テーブルへ移して…と考える訳だが
それをしなくても解決する方法がある。

(1) 部分インデックス(MSSQLやPostgreSQLの場合)
  条件に該当する中で一意性制約をつけるということができる。
  MSSQLではこんな感じ。
┌──────────────────────────────────────┐
│CREATE UNIQUE NONCLUSTERED INDEX [一意性制約]                               │
│    ON [dbo].[表] (                                                         │
│        [自然キー]          ASC                                             │
│    )                                                                       │
│    WHERE ([削除済フラグ] = 0);                                             │
└──────────────────────────────────────┘
  削除レコード(削除済フラグ=1)については、一意性制約が効かないので
  ちょうど、別履歴テーブルに移動したのと同じような感じになる。

(2) 一意性制約中のNULL特性(MySQLやOracleの場合)
  複合キーにNULLが混じっていると、一意性制約の範疇外となる特性を利用する。
  つまり制約を「自然キー+削除済みフラグ」にして、
  削除済みの場合は「TRUE」ではなく「NULL」としてしまうのだ。
  「自然キー+NULL」となれば一意性制約が効かないので、
  「自然キー」の部分が重複していてもいけてしまうというわけだ。
分類:SQL
PHP/パスワード管理(2)
2014年10月19日
パスワードを暗号化するのにハッシュ関数を使う。
以下は「md5()」を使った例。
┌──────────────────────────────────────┐
│$平文 = 'パスワード';                                                       │
│$暗号文 = md5($平文);                                                       │
├──────────────────────────────────────┤
│$入力文 = 'パスワード';                                                     │
│if (md5($入力文) == $暗号文) {                                              │
│    echo '合格';                                                            │
│} else {                                                                    │
│    echo '不合格';                                                          │
│}                                                                           │
└──────────────────────────────────────┘
これで、ほぼ十分なのだが、問題がある。
例えばよく使うパスワードの文字として「password」ってのがあるが
これは「5f4dcc3b5aa765d61d8327deb882cf99」に変換されるのだ。
(自分で変換してみればいい)
つまり「5f4dcc3b5aa765d61d8327deb882cf99」が流出すれば
元々「password」だったってことがわかってしまう。
この地道な作業を繰り返せば、機械的な変換表ができてしまう。

では、これにどう対策したらいいか。
つまりは、決まった変換が公になっているのが問題なのだ。

ということで、いたずらで私的な文字列を追加してあげればよい。
ハッシュ関数なのでちょっとした違いだけで、結果が大きく変わる。
こんな感じ。(「$適当な文字」には「1」とか「A」だけでもよい)
┌──────────────────────────────────────┐
│$平文 = 'パスワード';                                                       │
│$暗号文 = md5($平文 . $適当な文字);                                         │
├──────────────────────────────────────┤
│$入力文 = 'パスワード';                                                     │
│if (md5($入力文 . $適当な文字) == $暗号文) {                                │
│    echo '合格';                                                            │
│} else {                                                                    │
│    echo '不合格';                                                          │
│}                                                                           │
└──────────────────────────────────────┘
でも、問題がある。「$適当な文字」の管理が煩雑だ。
忘れると照合できなくなる一方、流出の恐れもある。
また、何をつかえばよいかも悩みどころだ。

ということで、これを簡単に実現してくれるのが「crypt()」だ。
┌──────────────────────────────────────┐
│$平文 = 'パスワード';                                                       │
│$暗号文 = crypt($平文);                                                     │
├──────────────────────────────────────┤
│$入力文 = 'パスワード';                                                     │
│if (crypt($入力文, $暗号文) == $暗号文) {                                   │
│    echo '合格';                                                            │
│} else {                                                                    │
│    echo '不合格';                                                          │
│}                                                                           │
└──────────────────────────────────────┘
「$適当な文字」的なところを、暗号文自身に付加してあげる感じ。
「crypt()」では、その「$適当な文字」的なところを抜き出して、
これを使って暗号化してくれるという仕組みだ。

なによりも「crypt($平文)」の部分は、実行する度に結果が変わる。
ハッシュを二重にかけているような感じだ。

ちなみに「crypt()」の「salt」は種別によって以下のような感じとなる。
┌───────┬──────────────────────────────┐
│CRYPT_STD_DES │xx                                                          │
├───────┼──────────────────────────────┤
│CRYPT_EXT_DES │_0000xxxx                                                   │
├───────┼──────────────────────────────┤
│CRYPT_MD5     │$1$xxxxxxxx$                                                │
├───────┼──────────────────────────────┤
│CRYPT_BLOWFISH│$2a$00$xxxxxxxxxxxxxxxxxxxxx                                │
│              │$2x$00$xxxxxxxxxxxxxxxxxxxxx                                │
│              │$2y$00$xxxxxxxxxxxxxxxxxxxxx                                │
├───────┼──────────────────────────────┤
│CRYPT_SHA256  │$5$xxxxxxxxxxxxxxxx                                         │
│              │$5$rounds=5000$xxxxxxxxxxxxxxxx                             │
├───────┼──────────────────────────────┤
│CRYPT_SHA512  │$6$xxxxxxxxxxxxxxxx                                         │
│              │$6$rounds=5000$xxxxxxxxxxxxxxxx                             │
└───────┴──────────────────────────────┘
分類:PHP
PHP/パスワード管理(1)
2014年10月18日
設定パスワードは平文で管理していては流出した時にすぐばれてしまうので
復号化できない暗号文の状態で保存しておくのが鉄則。

パスワード照合の場面では、入力された平文のパスワードを同様に暗号化、
お互い暗号文の状態として、そこで一致すれば、合格ということになる。

もし、暗号化された設定パスワードを流出し、誰かの手に渡っても
パスワード入力の場面で、それをそのまま使うとさらに暗号化されてしまい
別な文字になるので、照合できなくなる。

つまり、暗号化せずに照合するか、平文に戻して入力するかの
いずれかの方法をとらねば照合できないわけだ。
ところが、前者はもちろんシステムの問題だから手が出せない(*1)。
一方、後者は復号化できない暗号化がなされているので、無理ということになる(*2)。
  *1:但し、そういう機能が存在した場合には、そのルートをみつけだせばよい。
      よって、パスワード照合機能を実装する場合には注意が必要だ。
  *2:従って、元々のパスワードがなんだったかの問い合わせには回答できない。
      よって、パスワードを忘れた場合には、再発行ということになる。

ということで、復号化できない暗号化により、パスワードは強固なものになる。
で、その実現方法。
ハッシュ関数を使う。
まさにこれにうってつけの関数なのだ。

まず、バラバラに暗号化される。つまり、隣の文字(例えば「1」と「2」)でも
まったく関係のない文字に変換される。つまり、類推が難しい。

そして、復号化できない。
大雑把にいえば、例えば、どんな文字でも、必ず「松」「竹」「梅」に変換されるとして
「松」は元々何という文字だったか?というような仕組みだ。
もちろん、「鶴」と入力しても「亀」と入力しても「松」では、
パスワードとして不安を感じるが、この衝突が起こらない程度に大きな範囲で
変換されるのがハッシュ関数といえる。
#理論的には衝突が起きる可能性があることが復号化できないことにつながるが
  事実上は衝突が起きないという感じか。
分類:PHP
HTTP/チャンク形式
2014年10月17日
応答HTTPヘッダにて以下の形式が選択される(併存は不可)
┌──────┬─────────────┬──────────┬──────┐
│内容長形式  │Content-Length    :xxxx   │全サイズがわかる    │            │
├──────┼─────────────┼──────────┼──────┤
│チャンク形式│Transfer-Encoding :chunked│全サイズがわからない│大容量向け  │
└──────┴─────────────┴──────────┴──────┘
分類:Apache
DOSコマンド/年月日時分秒
2014年10月15日
年月日を「YYYYMMDD」形式で取得する方法。
┌──────────────────────────────────────┐
│set YMD=%date:~-10,4%%date:~-5,2%%date:~-2,2%                               │
│echo %YMD%                                                                  │
├──────────────────────────────────────┤
│set YMD=%date:/=%                                                           │
│echo %YMD%                                                                  │
└──────────────────────────────────────┘

時分秒を「HHIISS」形式で取得する方法。
┌──────────────────────────────────────┐
│set HIS=%time:~-11,2%%time:~-8,2%%time:~-5,2%                               │
│set HIS=%HIS: =0%                                                           │
│echo %HIS%                                                                  │
├──────────────────────────────────────┤
│set HIS=%time:~0,8%                                                         │
│set HIS=%HIS::=%                                                            │
│set HIS=%HIS: =0%                                                           │
│echo %HIS%                                                                  │
└──────────────────────────────────────┘
時(HH)がゼロパディングされないので、自前で行う必要がある。

バックアップファイルのファイル名などに利用できる。
分類:Windows
ExcelVBA/With句で自分を指したい場合
2014年10月14日
Q.With句で、パスにおける「.」みたいに自分を指す記号的なものはないか?
A.「.Offset(0, 0)」。
    以下は同じとなる。
┌──────────────────────────────────────┐
│With Selection.Cells(1, 1)                                                  │
│    .Offset(0, 0).Value = "値"                                              │
│End With                                                                    │
├──────────────────────────────────────┤
│With Selection.Cells(1, 1)                                                  │
│    .Value = "値"                                                           │
│End With                                                                    │
└──────────────────────────────────────┘
分類:ExcelVBA
DOSコマンド/ファイルがあるか?
2014年10月13日
複雑なツリー構造の残骸が残った場合、不要だから削除したいんだけど、
本当にその中にファイルが混じってないか不安な時がある。

そういう時にファイルを検索するコマンド。
┌──────────────────────────────────────┐
│>dir /b/s/a-d                                                               │
│ファイルが見つかりません                                                    │
└──────────────────────────────────────┘
分類:Windows
SQL/一意性制約とNULL
2014年10月12日
主キー(PRIMARY KEY)制約は、非ヌル(NOT NULL)制約と一意性(UNIQUE)制約を
組み合わせたもので、普段はこれを使っているかあまり意識しないかもしれないが
一意性制約のみの場合、NULLの扱いはどうなるのか?という話。

実はRDBMSにより違ってくる

(1) NULLは一意性制約の対象外とみなす方式(MySQL、PostgreSQLなど)
→NULL以外が重複しなければNULLはいくらでも重複できる

(2) NULLも一意性制約の対象内とみなす方式(MSSQLなど)
→NULLは認めるが、一つしか認めない(複数あれば重複とみなす)

NULLはNULLと一致しない(「= NULL」ではなく「IS NULL」で判定)ものの
重複という点では見解が異なるようだ

ちなみに(1)で複合キーの場合、NULLが含まれていれば全体的にNULLとみなされるので
重複が可能となる点にも注意。(例えば「1,NULL」と「1,NULL」は重複できる)
分類:SQL
Excel/セル番号非表示
2014年10月11日
Excel特有の上と左に表示される行列番号の表示をなくす方法。

Excel2010にて

Excelのオプション→詳細設定
┌──────────────────────────────────────┐
│次のシートで作業するときの表示設定  [シート名]                              │
│□行列番号を表示する                                                        │
└──────────────────────────────────────┘

Excelのオプションって、Excel共通化とおもったけど、
シート毎の設定もできるんだ。

これでExcelシートっぽさを消せてしまう。
というか、そういうのをつかまされた時の防衛策として覚えておいた方がよいかも。

ちなみにVBAマクロだとこんな感じになる。
┌──────────────────────────────────────┐
│ActiveWindow.DisplayHeadings = False                                        │
└──────────────────────────────────────┘
分類:Excel
前へ 1 2 3 次へ