MW211 EXIT

devlog
JavaScript/日時入力
2013年01月05日
まずは日付チェック。「年、入力値が「YYYY-MM-DD HH:II」形式の文字列で、
日時型のデータとして取り込みたい場合は。
┌──────────────────────────────────────┐
│var ymdhi = 入力値.split(/-| |:/, 5);                                       │
│if (ymdhi.length == 5) {                                                    │
│    if ((isYmd(ymdhi[0], ymdhi[1], ymdhi[2]))                               │
│     && (isHis(ymdhi[3], ymdhi[4], 0)))                                     │
│    {                                                                       │
│        出力値 = new Date(ymdhi[0],                                         │
│                          ymdhi[1] - 1,                                     │
│                          ymdhi[2],                                         │
│                          ymdhi[3],                                         │
│                          ymdhi[4],                                         │
│                          0);                                               │
│    }                                                                       │
│}                                                                           │
└──────────────────────────────────────┘
「isYmd()」と「isHis()」は先日作成したユーザ関数なので、なくてもよいかも。
ま、「new Date()」のような感じになるってことですな。
月を「0~11」で指定しなきゃならない以外は、違和感はないかも。
分類:JavaScript
JavaScript/日時チェック
2013年01月04日
まずは日付チェック。「年、月、日」を引数に指定すればtrue/falseを返却。
月はJavaScriptの世界の「0~11」ではなく現実世界の「1~12」で対応。
┌──────────────────────────────────────┐
│function isYmd(yyyy, mm, dd)                                                │
│{                                                                           │
│    var dt = new Date(yyyy, mm - 1, dd);                                    │
│    if (isNaN(dt))                   {return false;}                        │
│    if (dt.getFullYear() != yyyy   ) {return false;}                        │
│    if (dt.getMonth()    != mm  - 1) {return false;}                        │
│    if (dt.getDate()     != dd     ) {return false;}                        │
│    return true;                                                            │
│}                                                                           │
└──────────────────────────────────────┘
例)isYmd(2012,2,29)  →  true
    isYmd(2013,2,29)  →  false

続いては時刻チェック。ベタです。
「時、分、秒」を引数に指定すればtrue/falseを返却。
ま、見てのとおり24時というのはアウトです。
┌──────────────────────────────────────┐
│function isHis(hh, ii, ss)                                                  │
│{                                                                           │
│    if (isNaN(hh) || (hh < 0) || (hh > 23)) {return false;}                 │
│    if (isNaN(ii) || (ii < 0) || (ii > 59)) {return false;}                 │
│    if (isNaN(ss) || (ss < 0) || (ss > 59)) {return false;}                 │
│    return true;                                                            │
│}                                                                           │
└──────────────────────────────────────┘

そんなわけで、実はここまでもってくるのが本当は大変なのです。
ま、屏風から虎を出してくれりゃ簡単に退治できますよって話で。

さ、次は馬を川まで連れて来なければ。
分類:JavaScript
JavaScript/日時いろいろ
2013年01月03日
現在日時を求める。
┌──────────────────────────────────────┐
│変数 = new Date();                                                          │
└──────────────────────────────────────┘
そいつを「YYYY-MM-DD HH:II:SS」形式の文字列にする。
┌──────────────────────────────────────┐
│  変数.getFullYear()                                                        │
│+ "-" + ("0" + (変数.getMonth() + 1)).slice(-2)                             │
│+ "-" + ("0" + 変数.getDate()       ).slice(-2)                             │
│+ " " + ("0" + 変数.getHours()      ).slice(-2)                             │
│+ ":" + ("0" + 変数.getMinutes()    ).slice(-2)                             │
│+ ":" + ("0" + 変数.getSeconds()    ).slice(-2)                             │
└──────────────────────────────────────┘
前後にずらすのまとめ。
┌──────┬───────────────────────────────┐
│一年前にする│変数.setFullYear(変数.getFullYear() - 1);                     │
│一年後にする│変数.setFullYear(変数.getFullYear() + 1);                     │
├──────┼───────────────────────────────┤
│一月前にする│変数.setMonth(変数.getMonth() - 1);                           │
│一月後にする│変数.setMonth(変数.getMonth() + 1);                           │
├──────┼───────────────────────────────┤
│一日前にする│変数.setDate(変数.getDate() - 1);                             │
│一日後にする│変数.setDate(変数.getDate() + 1);                             │
├──────┼───────────────────────────────┤
│一時前にする│変数.setHours(変数.getHours() - 1);                           │
│一時後にする│変数.setHours(変数.getHours() + 1);                           │
├──────┼───────────────────────────────┤
│一分前にする│変数.setMinutes(変数.getMinutes() - 1);                       │
│一分後にする│変数.setMinutes(変数.getMinutes() + 1);                       │
├──────┼───────────────────────────────┤
│一秒前にする│変数.setSeconds(変数.getSeconds() - 1);                       │
│一秒後にする│変数.setSeconds(変数.getSeconds() + 1);                       │
└──────┴───────────────────────────────┘
分類:JavaScript
PostgreSQL/制約とかのまとめ
2013年01月02日
制約とかをまとめてみた。
┌──────┬──────┬──────┬─┬─┬─────────────┐
│    分類    │            │ キーワード │表│列│         関連事項         │
├──────┼──────┼──────┼─┼─┼─────────────┤
│既定値      │既定値      │DEFAULT     │-│○│                          │
├──────┼──────┼──────┼─┼─┼─────────────┤
│            │検査制約    │CHECK       │○│△│                          │
│            ├──────┼──────┼─┼─┼─────────────┤
│制約        │非NULL制約  │NOT NULL    │-│○│PRIMARY KEY               │
│            ├──────┼──────┼─┼─┼─────────────┤
│            │一意性制約  │UNIQUE      │○│△│PRIMARY KEY、UNIQUE INDEX │
├──────┼──────┼──────┼─┼─┼─────────────┤
│            │主キー制約  │PRIMARY KEY │○│-│                          │
│キー        ├──────┼──────┼─┼─┼─────────────┤
│            │外部キー制約│FOREIGN KEY │○│-│                          │
├──────┼──────┼──────┼─┼─┼─────────────┤
│インデックス│インデックス│INDEX       │○│-│PRIMARY KEY、UNIQUE INDEX │
└──────┴──────┴──────┴─┴─┴─────────────┘
分類:PostgreSQL
PostgreSQL/一意性制約列の値振り直し
2012年12月21日
一意制約およびNOT NULL制約がある列に値が入っているとして、
その値を全体的に再編成したい場合がある。

でも、一つ一つ更新していたら、昔の値と重複エラーとなってしまったりして
めんどくさい。
NOT NULL制約がなければ一旦NULLにするって方法があるのだが。

んなわけで、一旦、ありえない値に更新してから、新しい値を更新する方法を考える。
例えば「1~99」の値を再編成する場合、
一旦「100~」とかの値に振り直してから、再度「1~99」の値を更新すれば、
昔の値に影響されることなく(重複エラーが発生することなく)
更新ができるというわけだ。

まず考えたのは、最大値に+1していけばいいんじゃないかという案。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│   SET 列 = (SELECT MAX(列) FROM 表) + 1;                                   │
└──────────────────────────────────────┘
しかし、これは都度最大値を計算してくれるわけではなく、
最初の一回しか計算してくれないから例えば全件「100」とかになって
うまくいかない(更新できない)。

これを実現するにはこんなSQL文となる。
┌──────────────────────────────────────┐
│WITH 一時表(キー,                                                           │
│            列) AS (                                                        │
│         SELECT キー,                                                       │
│                (SELECT max(列) FROM 表) + 100                  --最大+100  │
│              + row_number() OVER()                             --連番になる│
│             FROM 表                                                        │
│     )                                                                      │
│UPDATE 表                                                                   │
│    SET 列 = 一時表.列                                                      │
│    FROM 一時表                                                             │
│    WHERE 一時表.キー = 表.キー;                                            │
└──────────────────────────────────────┘
これなら確実だけど、やや複雑だ。

いっそのこと、乱数に頼った方がシンプルかも。
┌──────────────────────────────────────┐
│UPDATE 表                                                                   │
│   SET 列 = 100 + ROUND((RANDOM() * 1000)::numeric, 0);                     │
└──────────────────────────────────────┘
稀に、重複するかもしれないが、その場合は、再度実行するか、
RANDOM()に掛ける値を広げるとよい。
分類:PostgreSQL
PostgreSQL/空欄のソート(3)
2012年12月14日
空欄もNULLも見た目が一緒だから、まとめてしまえ!

ということで、まずは空欄にまとめる方法。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM (SELECT 1 AS "k",'a'   AS "c"  --文字                              │
│    UNION SELECT 2 AS "k",''    AS "c"  --空欄                              │
│    UNION SELECT 3 AS "k",NULL  AS "c"  --NULL                              │
│    ) AS "t"                                                                │
│    ORDER BY COALESCE("c", '') ASC;                                         │
└──────────────────────────────────────┘
「空欄→NULL→文字」の順になる。
ちなにみ四番目に「空欄」を追加してみたが「空欄→空欄→NULL→文字」の順となった。
ま、「空欄→NULL」の部分はすべて等価なので、
第二ソート指定で、任意の順に並び替えるってことになるだろう。

続いてNULLの方にまとめる方法。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM (SELECT 1 AS "k",'a'   AS "c"  --文字                              │
│    UNION SELECT 2 AS "k",''    AS "c"  --空欄                              │
│    UNION SELECT 3 AS "k",NULL  AS "c"  --NULL                              │
│    ) AS "t"                                                                │
│    ORDER BY CASE WHEN LENGTH("c") > 0 THEN "c" ELSE NULL END ASC;          │
└──────────────────────────────────────┘
「文字→空欄→NULL」の順になる。
ちなにみ四番目に「空欄」を追加してみたが「文字→空欄→空欄→NULL」の順となった。
なにやら見えない「空欄→NULL」があるみたい。
といっても、同じ値(NULL)を並び替えても、どうなるか保証されない訳だから、
前述の通りあまり気にしなくてよかろう。
分類:PostgreSQL
PostgreSQL/空欄のソート(2)
2012年12月13日
いつも末尾になる「NULL」を先頭にもってきたい場合は、
「IS NOT NULL ASC」もしくは「IS NULL DESC」を最初に挟めばいい。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM (SELECT 1 AS "k",'a'   AS "c"  --文字                              │
│    UNION SELECT 2 AS "k",''    AS "c"  --空欄                              │
│    UNION SELECT 3 AS "k",NULL  AS "c"  --NULL                              │
│    ) AS "t"                                                                │
│    ORDER BY "c" IS NOT NULL ASC,                                           │
│             "c"             ASC;                                           │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM (SELECT 1 AS "k",'a'   AS "c"  --文字                              │
│    UNION SELECT 2 AS "k",''    AS "c"  --空欄                              │
│    UNION SELECT 3 AS "k",NULL  AS "c"  --NULL                              │
│    ) AS "t"                                                                │
│    ORDER BY "c" IS NULL DESC,                                              │
│             "c"         ASC;                                               │
└──────────────────────────────────────┘
これで「NULL→空欄→文字」となる。

論理型のソート順は「偽→真」なので、NULLと反対の条件にして
NULLだけを偽にしてしまえば、NULLが先頭にくる(ややこしい)という仕組みだ。
分類:PostgreSQL
PostgreSQL/空欄のソート
2012年12月12日
空欄とNULLのソート順もあやふやなので試してみた。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM (SELECT 1 AS "k",'a'   AS "c"  --文字                              │
│    UNION SELECT 2 AS "k",''    AS "c"  --空欄                              │
│    UNION SELECT 3 AS "k",NULL  AS "c"  --NULL                              │
│    ) AS "t"                                                                │
│    ORDER BY "c" ASC;                                                       │
└──────────────────────────────────────┘

  昇順:「空欄→文字→NULL」の順
  降順:「NULL→文字→空欄」の順(昇順の真逆)

という結果となった。

空欄とNULLの区別がぱっとみつかないので、
なんで空欄が先頭と末尾に固まるんだろうという罠にハマってしまいそうだ。
分類:PostgreSQL
PostgreSQL/文字長
2012年12月11日
文字数を取得したい場合には「LENGTH()」を使う。
┌──────────────────────────────────────┐
│SELECT LENGTH('abcあい');                                                →5│
└──────────────────────────────────────┘

文字長を取得したい場合には「OCTET_LENGTH()」を使う。
┌──────────────────────────────────────┐
│SELECT OCTET_LENGTH('abcあい');                                          →9│
└──────────────────────────────────────┘
「UTF-8」環境で実行したので、上記だと「1+1+1+3+3」で「9」となる。
分類:PostgreSQL
PostgreSQL/論理型のソート
2012年12月10日
論理型をソートするとどの順に並ぶのかあやふやなので以下で実験してみた。
┌──────────────────────────────────────┐
│SELECT *                                                                    │
│    FROM (SELECT TRUE  AS "c"                                               │
│    UNION SELECT FALSE AS "c"                                               │
│    UNION SELECT NULL  AS "c"                                               │
│    ) AS "t"                                                                │
│    ORDER BY "c" ASC;                                                       │
└──────────────────────────────────────┘
「ASC」(昇順)を「DESC」(降順)に置換したりして試したところ…。

  昇順:「FALSE→TRUE→NULL」の順
  降順:「NULL→TRUE→FALSE」の順(昇順の真逆)

という結果となった。

なんか、「TRUE→FALSE」が正順のように錯覚してたなぁ。

ちなみに、「UNION ALL」にして複数件ぐちゃぐちゃにして試してみたが、
上記の結果に従った結果となった(「FALSE…FALSE→TRUE…TRUE→」みたいな感じ)。

ちなみに、どれが根拠になってるんだろう(わからん)。
  ・FALSE   < TRUE
  ・'false' < 'true'
  ・'f'     < 't'
  ・'no'    < 'yes'
  ・'n'     < 'y'
  ・0       < 1
どちらにしろ、FALSEの方が前だわな。
分類:PostgreSQL
前へ 1 … 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 … 156 次へ