忍者ブログ
IT関係の小作人労働の日々の日記です。 最近データベースが好きです。 インフラ構築、DB構築、アプリケーション開発・・・何でも屋です。 何でもできそうで、何にもできない。

【Oracle Cloud Free & DB】第3回:JSTに変えても時間が違う?都度切断の罠を「ログオン・トリガー」で根本から美しく解決する


前回、ツール側の地域設定を「日本」に変更しました。これで画面の見た目は日本仕様になりましたが、ここで最大級の罠が立ちはだかります。お馴染みの SELECT SYSDATE FROM DUAL; だけでなく、セッションに従うはずの SELECT CURRENT_DATE FROM DUAL; を実行しても、返ってくるのは相変わらず9時間遅れの「世界標準時(UTC)」のままなのです。ネットにある『ALTER SESSIONを使おう』という泥臭い方法ではなく、データベースの機能を活かして「最もエレガントに根本解決する」現場の定石を解説します。

1. なぜ「ALTER SESSION」を実行しても時間がズレるのか?

Autonomous Database(PaaS)において、SYSDATEがクラウド基盤のOS時刻(UTC)に固定されているのは仕様ですが、なぜ画面上で ALTER SESSION SET TIME_ZONE = 'Asia/Tokyo'; を実行した後に CURRENT_DATE を叩いても時間が戻してしまうのでしょうか?

その原因は、ブラウザ上の開発ツールである「データベース・アクション」の挙動にあります。このツールは、SQLを実行するたびに内部でセッションを一度切断・再接続するような挙動(ステートレスな制御)をとっています。そのため、画面上で手動でALTER SESSIONを実行しても、次のSQLを実行した瞬間にはその効果がリセットされ、初期状態(UTC)へと戻ってしまうのです。

2. 【最高にエレガントな解決策】「AFTER LOGONトリガー」で自動化する

毎回SQLに足し算(+9/24)を書いたり、実行手順を工夫したりするのはスマートではありません。一番エレガントな解決策は、「誰が、どのツールから、いつ接続してきても、ログインした瞬間に自動でタイムゾーンを日本(JST)に書き換える仕組み」をデータベース側に仕込むことです。

Oracleの標準機能である「AFTER LOGONトリガー(ログオン後トリガー)」をADMIN権限で1回作成しておくだけで、システムが自動的にセッションをコントロールしてくれます。

タイムゾーン自動変更トリガーの作成SQL
ワークシートで以下のSQLを1度だけ実行します(※この時だけはF5などのスクリプト実行で流します)。

CREATE OR REPLACE TRIGGER SET_JST_AFTER_LOGON
AFTER LOGON ON DATABASE
BEGIN
    EXECUTE IMMEDIATE 'ALTER SESSION SET TIME_ZONE = ''Asia/Tokyo''';
END;
/

3. 実機での検証ログ:普通に叩くだけで完璧な日本時間に!

トリガーの作成が完了したら、もう面倒な前処理やF5キーでの一括実行すら不要です。ブラウザをリロードし、ただ普通にいつもの標準関数を通常の実行ボタン(▶)で1行ずつ叩いてみましょう。ツール特有の揮発性に邪魔されることなく、見事に正真正銘の「正しい日本時間」が一発で返ってきます。

実際の検証SQLと実行結果

SELECT CURRENT_DATE FROM DUAL;

CURRENT_DATE
------------------
2026/05/17 19:48:06
経過時間: 00:00:00.002
1行が選択されました。

--------------------------------------------------

SELECT LOCALTIMESTAMP FROM DUAL;

LOCALTIMESTAMP
---------------------------
2026-05-17T19:48:06.502281Z
経過時間: 00:00:00.002
1行が選択されました。

4. まとめ:インフラの仕組みで解決するのがプロの定石

開発者が個別にワークアラウンド(回避策)を講じるのではなく、データベースというインフラ側の仕組み(トリガー)で縛る。これこそが、複数人での開発や、将来的なアプリケーション接続も見際据えた、最もスムーズでエレガントなアーキテクチャの形です。

本日の日付処理チェックリスト
1. ツール側でセッションが都度切断される特性をデータベースの機能でカバーする。
2. ADMIN権限を活かし、「AFTER LOGONトリガー」を仕込んでセッション初期化を完全自動化。
3. 環境が整えば、以降は「CURRENT_DATE」を叩くだけで常にスムーズに日本時間を取得可能。


これで言語、日付書式、そして最も難所だった「自動での日本時間取得」まで、クラウド特有の罠をすべてエレガントに攻略し、完璧な開発ベースが整いました!ストレスが一切なくなったところで、次回第4回は、いよいよもう一つの無料枠を使って「19c」インスタンスを追加し、この最新26aiとの本格的な並走比較検証に入っていきます。どうぞお楽しみに!


PR

【Oracle Cloud Free & DB】第2回:初期状態の「世界標準時」を「日本仕様(NLS)」へ変更・保存する設定の定石


前回、無料枠を活用して最新の「26ai」環境を無事に立ち上げることができました。しかし、初期状態のままで言語や通貨の書式、日付の表示形式を確認すると英語仕様になっていたりと、日本の開発環境としては少々使いづらい状態です。今回は、これらの環境を使いやすい「日本仕様」へ変更し、設定を維持する方法を実機検証のログを交えて解説します。

1. クラウド(PaaS)における設定の制限と2つのアプローチ

従来のオンプレミス環境であれば、サーバー側の初期化パラメータ(init.oraやSPFILE)を直接書き換えてシステム全体のNLS設定を「日本仕様」に固定するのが一般的でした。しかし、Autonomous DatabaseのようなフルマネージドなPaaS環境では、クラウド側が基盤を管理しているため、サーバー側の初期化パラメータをユーザーが直接変更することはできません。

そのため、PaaS環境で日本仕様(日本語NLS)を適用・保存するには、以下の2つのアプローチのいずれかを採用するのがクラウドの作法となります。

方法A:開発ツール(接続クライアント)側で設定を保存する
ブラウザ上の「データベース・アクション」自体の機能として、ログイン時に自動で地域・言語設定を適用するようUI上で固定する方法です。
方法B:データベースの「ログオン・トリガー」で自動変更する
データベース内部に「ユーザーがログインした瞬間にセッション設定を書き換える」トリガーを仕込み、永続化(自動化)する方法です。

2. 現在の地域・言語設定(NLS)を確認する

まずは現在のデータベースセッションがどの地域を向いているのか、データ・ディクショナリを叩いて確認してみましょう。

初期状態の確認SQLと結果
SELECT parameter, value FROM v$nls_parameters WHERE parameter IN ('NLS_LANGUAGE', 'NLS_TERRITORY', 'NLS_DATE_FORMAT');

【実行結果】
PARAMETER VALUE
------------------------
NLS_LANGUAGE JAPANESE
NLS_TERRITORY AMERICA
NLS_DATE_FORMAT DD-MON-RR

※初期状態では言語こそ「JAPANESE」になっているものの、領域(TERRITORY)が「AMERICA」のため、日付書式が西欧風の「DD-MON-RR」になっています。

3. SQL(ALTER SESSION)の実行と、ツール特有の挙動

次に、セッションレベルでの変更コマンドを動かして、動的に日本仕様へ切り替わるか検証します。

セッション変更のコマンド群
ワークシートで以下のSQLを実行します。
ALTER SESSION SET NLS_LANGUAGE = 'JAPANESE';(エラーメッセージ等の日本語化)
ALTER SESSION SET NLS_TERRITORY = 'JAPAN';(通貨や曜日を日本基準に)

実行後の再確認結果
"PARAMETER" "VALUE"
"NLS_LANGUAGE" "JAPANESE"
"NLS_TERRITORY" "AMERICA"
"NLS_DATE_FORMAT" "DD-MON-RR"

【検証のポイント】値が変わらない理由とは?
実機でALTER SESSIONを実行しても、v$nls_parameters上は「AMERICA」や「DD-MON-RR」のまま変化しないように見えます。これは、ブラウザ上の開発ツールであるデータベース・アクション(SQLワークシート)が、内部で独自のセッション制御(プロキシ接続)を行っているためです。ツール側が接続のたびに設定を上書きしてしまうため、SQLによる動的なALTER SESSIONが一部表面化しないという、クラウドツール特有の挙動(罠)があります。

4. 【解決策】データベース・アクションの機能で日本仕様を固定する

上記のようにツール側の制御が強いため、データベース・アクションを使う場合は、ツールそのものの設定機能を使って地域設定を保存させてしまうのが最も確実で安全なアプローチになります。

設定手順
1. データベース・アクションの画面右上にある「ユーザー設定(歯車マークやユーザーアイコン)」を開きます。
2. 「ナビゲーション」または「グローバリゼーション(地域設定)」の項目を探します。
3. 言語を「日本語」、地域を「日本」に変更し、日時の書式(NLS_DATE_FORMAT)に YYYY-MM-DD HH24:MI:SS を指定して「保存」します。
効果:ツール側のグローバリゼーション設定を直接書き換えることで、次回以降のログイン時も自動的に設定が引き継がれ、常に日本時間や見慣れた日本の日付フォーマットで結果が返るようになります。

5. まとめ:環境の基礎が整ったら、次は「時刻」の深い罠へ

サーバー側のパラメータを直接いじれないPaaS、そして特有の挙動を持つクラウドツールだからこそ、仕様を正しく把握しておくことが無駄なトラブルを避ける鍵になります。

本日の設定チェックリスト
1. パラメータを直接変更できないPaaS特有の制限を理解できたか?
2. ツール側のユーザー設定で言語や地域を固定できたか?
3. 今後アプリケーションから接続する際は、AFTER LOGONトリガーの活用を検討できているか?


言語や日付のデフォルト書式といった基礎の土台はこれで完成です。しかし、実はこれだけでは解決しない、クラウド環境における最大の罠が「時刻(SYSDATE)」の挙動に隠されています。次回第3回は、『なぜタイムゾーンを変えてもSYSDATEが日本時間にならないのか?』その理由と解決策に迫ります。どうぞお楽しみに!


【Oracle Cloud Free & DB】第1回:最新26ai環境構築と最初のSELECT文


Oracle Databaseの最新機能を試してみたいけれど、環境構築のハードルが高いと感じていませんか?今回は、すでにOCI(Oracle Cloud)のログインIDをお持ちの方向けに、無料枠(Always Free)をフル活用して最新の「26ai」環境を立ち上げ、ブラウザ上でSQLを実行するまでの最短ルートを整理しました。

1. データベース・インスタンスを作成する

【 現場の感触 】 OCIのメニューは日々進化しています。最新のUIに対応した「迷わない」作成手順を踏むことが、スムーズな環境構築の第一歩です。

ナビゲーションの選択:コンソールメニューから「Oracle AI database」>「Autonomous Database」へ進みます。
「Always Free」のトグルスイッチ(最重要!):画面中央のスイッチを必ず「ON」にします。これで無料枠のスペックに固定され、課金の心配がなくなります。
バージョンの選択:最新のAI機能を試すなら「23ai」(自動的に26aiがプロビジョニングされます)、従来版なら「19c」を選択します。
ADMINパスワードの構成:管理者ユーザー用のパスワードを設定し、必ずメモしておきます(※OCI自体のログインパスワードとは異なります)。

2. データベース・アクション(SQL実行画面)を開く

【 現場の感触 】 クライアントツールをPCにインストールする必要はありません。ブラウザだけで完信・完結する強力な開発環境「データベース・アクション」を活用します。

ステータスの確認:作成実行後、アイコンが「プロビジョニング中(オレンジ)」から「使用可能(緑)」に変わるまで2〜5分ほど待ちます。
ツールの起動:詳細画面上部の「データベース・アクション」ボタンをクリックし、メニューから「SQL」を選択します。
認証のパス:ユーザー名「ADMIN」と、インスタンス作成時に設定した管理用パスワードを入力してログインします。

3. SQLワークシートで一括実行を試す

【 現場の感触 】 SQLの実行ボタンには「1文実行」と「スクリプト実行」があります。複数の検証用SQLをまとめて流すときは、ボタンの使い分けが肝心です。

検証用SQLの記述:バージョン確認用の「v$version」と、現在日時確認用の「dual」からデータを引く2つのSQLをワークシートに貼り付けます。
スクリプトの実行(F5キー):通常の再生ボタン(▶)ではなく、「紙に小さな再生マークが付いたボタン」をクリックすることで、すべてのSQLの結果をまとめて出力できます。

4. まとめ:無料枠で広がる「新旧Oracle」の検証環境

Oracle Cloud Free(Always Free)の素晴らしい点は、この自律型データベース(Autonomous Database)を同時に最大2つまで無料で維持できる点にあります。

本日の検証ログ(スクリプト出力例)
・Oracle AI Database 26ai Enterprise Edition Release 23.26.2.1.0 - Production
・現在日時:2026-05-16 08:44:46


今回、最新の「26ai」環境が手に入ったことで、話題のベクトル検索やJSON連携などの新機能を自由に試せるようになりました。無料枠はもう1つ残っているため、同じ手順で「19c」を追加すれば、新旧の挙動や実行計画の違いを実機で比較検証する最強の学習環境が整います。さっそく、次の一手を試してみましょう!



【C言語入門】変数の宣言と初期化:C99規格で変わった「自由な書き方」


プログラムの中で値を一時的に保存しておく「箱」が変数です。今回は基本中の基本である整数型(int)を例に、その宣言方法と、規格の進化によって効率化したポイントを解説します。

1. 実践:int型の宣言と初期化

【 動作確認 】 以下のコードを `var.c` として保存して実行します。変数 `a` に値を格納し、表示する基本的な構造です。

#include <stdio.h>

int main(void) {
    int a = 10; // 宣言と同時に初期化

    printf("aの値は %d です\n", a);

    a = 20; // 値の書き換え(代入)
    printf("書き換え後の値は %d です\n", a);

    return 0;
}

2. 規格による宣言位置の制限と緩和

【 仕組みの解説 】 C言語の規格によって、変数を宣言できる場所のルールが異なります。現代のMac環境(C11/C17)では、C99以降の緩和されたルールが適用されています。

古い規格(C89以前)
変数の宣言は、ブロック( { } )の先頭にまとめて記述しなければなりませんでした。

// C89スタイル
int main(void) {
    int a;
    int b;

    a = 10;
    b = 20;
    return 0;
}


現代の規格(C99以降)
「任意の位置」で宣言が可能になりました。これにより、ロジックの途中で必要になったタイミングで変数を定義できます。

// C99以降のスタイル(Macのデフォルト)
int main(void) {
    int a = 10;
    printf("%d\n", a);

    int b = 20; // 必要になった段階で宣言が可能
    printf("%d\n", b);
    return 0;
}

3. 未初期化変数のリスク

【 技術的注意点 】 `int a;` のように初期化を行わずに宣言した場合、その変数にはメモリ上に残っていた以前のデータ(不定値)が保持されます。これをそのまま使用すると意図しない挙動やバグの原因となるため、宣言時に明示的に初期化を行うことが推奨されます。

4. 変数の性質に応じた宣言位置の選択

現代の規格では自由な位置で宣言が可能ですが、コードの可読性を保つためには変数の役割に応じた整理が有効です。

一時的な計算用変数:使用する直前で宣言することで、変数の有効範囲(スコープ)を限定し、コードの複雑さを抑えます。
主要な制御変数:関数全体に関わる重要な変数は、あえて冒頭にまとめることで、その処理で何が中心的な役割を果たすかを明示できます。

5. 理解度チェック!練習問題

【 復習問題 】 現代のC言語(C99以降)における変数の宣言について、**正しい説明**はどれでしょうか?

選択肢:
A. 変数の宣言は必ず関数の1行目に書かなければならない。
B. `int a = 10;` のように、宣言と同時に値を代入(初期化)することができる。
C. 初期化していない変数には、自動的に「0」が代入される。
D. `int` 型の変数には、後から文字列を代入できる。

正解と解説を見る

正解:B

宣言と同時に初期化を行うのは、現代のC言語における標準的な作法です。初期化されていない変数には不定値が入るため、Bが唯一の正解となります。

6. まとめ

C99規格による制約の緩和は、C言語の記述効率を大きく向上させました。MacのClang環境では、これらのモダンな仕様をデフォルトで利用できます。変数の性質を見極め、適切な位置で宣言・初期化を行うことで、堅牢なプログラムの構築が可能になります。

【データベースの知識】結合(JOIN)アルゴリズムの選択と最適化


データベースを扱う上で避けて通れないのが「テーブル結合(JOIN)」です。SQLを書けば結果は同じに見えますが、内部のアルゴリズム選択ひとつで、処理速度は100倍、1000倍と劇的に変わります。今回は実務で役立つ3つの主要アルゴリズムを解説します。

1. 主要な3つの結合アルゴリズム

【 基本 】 データベースが2つのテーブルを繋ぐ際、主に以下の3つの手法から最適なものを選択します。それぞれ「得意なデータ量」と「リソースの使い方」に明確な違いがあります。

Nested Loop Join(入れ子ループ法)
外側の表から1行ずつ取り出し、内側の表を走査して一致を探します。少量のデータに強く、インデックスの活用が前提となります。
Sort Merge Join(ソートマージ法)
両方の表を結合キーでソートし、端から順に突き合わせます。大量データに強く、不等号結合(<, >)でも利用可能です。
Hash Join(ハッシュ結合)
片方の表からメモリ上にハッシュテーブルを作り、もう片方と突き合わせます。大量データ同士の等価結合(=)において非常に強力です。

2. 特徴比較表:データ量とインデックス

【 ポイント 】 実行計画を確認する際、現在のデータ量に対して適切な方法が選ばれているかを判断する基準を持っておくことが重要です。

アルゴリズム得意なデータ量インデックス備考
Nested Loop 1件〜少量 必須 オンライン処理の基本
Sort Merge 大量データ あれば尚可 ソートのCPU負荷あり
Hash Join 大量データ 不要 メモリ(ワークエリア)を消費

3. パフォーマンス改善:DBへの介入術

通常、DBは統計情報を元に自動で判断しますが、判断を誤ることもあります。その際、エンジニアが特定のアルゴリズムを強制・誘導する方法は製品ごとに異なります。

[ 製品別の介入方法 ]
Oracle(ヒント句):/*+ USE_NL(a b) */ のように、SQL内に直接指示を書き込みます。
PostgreSQL(パラメータ):SET enable_mergejoin = off; 等で特定の機能を無効化し誘導します。
MySQL(インデックスヒント):USE INDEX を指定することで、間接的にNLJなどへ誘導します。


結合アルゴリズムの仕組みを知ることは、スロークエリの根本原因を特定し、最適なパフォーマンスを引き出す第一歩となります。


        
  • 1
  • 2
  • 3