箱庭ハーブblog

7年目プログラマの趣味の小部屋

OracleのMerge文は使わないほうが無難

merge文を、UsingソースをDualで使用しましたとさ

 MERGE INTO ...
 USING (SELECT ... FROM DUAL) INPUT
   ON (... AND ... AND ...)
 WHEN MATCHED THEN UPDATE SET ...
 WHEN NOT MATCHED THEN INSERT ( ... );

「0行マージされました」

!?

!!?

!????!???!

確かに
・Usingソースの列に、サブクエリがいる。それは、結果無しNULLを返している
・ON句の結合条件に、Usingソース側がNULL

見たいな奇天烈なUsingソースではありますが、
ソース行自体は存在するので、絶対1行以上はマージしてほしいところ。
(条件にヒットすればUpdateするはずで、しなければInsertされるはずなので)


これ、Oracleのバグじゃないですか。
これだから、Merge文は信用できない。

LinuxとOracleとexpdp/impdp

ORACLE、Oracle、oracle、EXPDP、Expdp、expdp、IMPDP、Impdp、impdp
LINUX、Linux、linux
 
おつかれさまです。
今回は11gWindowsから10gLinuxにダンプしてコピーしようという方向性
Linuxとかまともに使ったことないので四苦八苦すぎですw
書き直すのも面倒なので、メモ書きをそのままコピペです。


以下、メモをそのままコピー。
 
Oracle用のOSアカウント作れば、ホームディレクトリがあるはず。
上記のホームディレクトリへimp、exp、sqlplusなどの環境パスを通す
11g→10gのexpimpの実行は、expdp/impdpでないとできない。(dmpには前方互換性がない)
expdpは、ディレクトリオブジェクト(DBがDB用に認識しているフォルダ)が設定されているフォルダを指定する必要がある
expしたものをimpdpしたり、expdpしたものをimpしたりは出来ない
 
expdpするまで(Windowsを想定)
1、コマンドラインでsqlplus起動
2、CREATE DIRECTORY dump_test AS 'C:\';
3、(GRANT READ, WRITE ON DIRECTORY dump_test TO <ユーザ>。管理者DBユーザ以外でやる場合に必要。SYSTEMとか使うなら不要)
4、quitしてコマンドラインに戻る
5、expdp.exe system/<パス> directory=dump_test dumpfile=test.dmpdp schemas=<ユーザ名> version=10.2.0
(出力されたファイルは、なぜか全部大文字でした。)


出力されたdmpdpファイルをLinuxに移動します。
 
 
impdpするまで(Linuxを想定)
1、コマンドラインからsqlplus起動
2、CREATE DIRECTORY dump_test AS 'home/oracle'; 
3、(GRANT READ, WRITE ON DIRECTORY dump_test TO <ユーザ>。管理者DBユーザ以外でやる場合に必要。SYSTEMとか使うなら不要)
4、quitしてコマンドラインに戻る
5、impdp system/<パス> directory=dump_test dumpfile=TEST.DMPDP remap_schema=<ソース>:<出力先>
 remap_tablespace=<ソース>:<出力先>
 
 
※1 Linux上のOracleのDIRECTORYでは、/と\を見分けるっぽい?それともOracleの設定?
※2 Linux上のexpdp/impdpは、ファイル名やディレクトリ名の大文字小文字を区別するらしい?それともoracleの設定ですかね?
※3 Windowsのexpdp/impdpで、ファイル名やディレクトリ名を区別するかどうかは未確認
 

64bit WindowsでOracle Clientが正常に動かない

Oracle、oracle、64bit

会社でOracle Clientのセットアップをしていて気づいたことです。
自分の開発PCとまったく同じ手順、再起動、その他でやったのに、Clientが動かない。
同様に、ObjectBrowserも動かない。



・・・

結論から先に。
Windowsのユーザーアカウント制御設定と管理者権限の仕様に違いがある模様。

32bitPCでは、以下で動きます。
標準ユーザー
アカウント制御 → 既定
通常権限で実行

64bitPCでは、以下にする必要があります。
管理者ユーザー
アカウント制御 → 以下の場合でも通知しない
通常権限で実行

もしかしたら標準ユーザーでも動くかもしれませんが、確認してません。
少なくともアカウント制御を最低にするか、管理者権限として実行する必要があります。
毎度毎度 警告メッセージなど出していては面倒なので、アカウント制御を最低にすることになります。

以下、64bitで確認できる異常動作。
・Oracle Net Configuration Assistantが起動しても何事もないかのように起動しない
・Net Managerの接続テストが成功しない。(エラー内容の一部が文字化けする)
・Sqlplusで接続しようとすると、Clientの初期化に失敗する(SP2-1503、SP2-0152)
・SI Object Browser で接続しようとすると、メモリアクセス違反を起こしてとまる

大体こんな感じの現象です。
64bit限定でおきるようなので、ぶち当たったら素直にWindowsアカウント周りを調整してあげましょう

FirebirdとIBOConsole

Firebird、firebird、IBOConsole、Iboconsole、iboconsole

1週間ぶりの更新ですね。
今回はFirebirdのインストールと運用でもメモしておきます。


「○○さまがPC替えるらしいから、Firebirdを利用してる会社で作った業務アプリを使えるようにしてきて」
といわれました。
さて、Firebirdを確認しておかないと・・・。
FirebirdというのはDBソフトウェアの一種で、比較的シンプルなのが特徴です。
・DBMS≒DBサーバとDBデータが完全に独立している。
・FirebirdはDBサーバである
・DBデータは単一ファイル(FDB)になっている
・Firebirdをインストールして、読み込むFDBファイルを指定すれば、動く
・Firebirdはちゃんとトランザクション&マルチアクセスに対応している
サンプルとして、実際の手順でも書いてみます。

1、業務アプリが利用しているversionのFirebirdサーバ(DBMS)をインストール
firebird.png
全てデフォルトでインストールしました。Program Files下にFirebirdサーバがインストールされます。

2、インストールが終わると、Win2000以降のOSでサービス(デーモン)が自動起動します。
サービスは特殊な常駐プログラムの総称で、Linuxではデーモン、Windowsではサービスと呼ばれます。
コントロールパネル>管理ツール>サービスで起動していることを確認します。
firebird2.png
サーバと、サーバを監視するサービスがペアで起動しているのがわかります。
Serverは実際にFirebirdを起動し処理を実行するための窓口です。
GuardianはServerサービスを監視して、異常終了時のログ出力やServerの再起動したりします。
(Win2000以降のOSでは、OS自体にサービス再起動機能があるのでGuardianは不要だったり・・)
プログラムがFDBにアクセスする流れとしては
業務アプリ>サービス>Program FilesのFirebird>FDBとアクセスすることになります。

3、業務アプリのパラメータ設定
業務アプリはDBデータのアカウントとアクセス先のFDBファイルパスを指定してアクセスします。
・アクセス先のパス
・DBデータへのアクセスに必要なアカウントID
・DBデータへのアクセスに必要なアカウントのパス
は業務アプリフォルダにあるテキストファイルで指定できるように作ってあるので、適当にあわせます。
(・・・セキュリティ的にまずいだろうというのはまぁ、ええとその通りで。)
今回の業務アプリは、業務アプリのexeとFDBファイルが同じフォルダにいます。
ここら辺は業務アプリをどう作ったかによって大きく異なるので、あまり参考になりませんね。

4、FirebirdのDBアカウントの設定
FirebirdはDBMSですので、他のOracleやSQL Serverと同じようにDBアカウントがあります。
以下の「デフォルト・ユーザ名とパスワード」を読めばわかりますが、
http://www.firebirdsql.org/manual/ja/qsg15-installing-ja.html
初期状態ではidがSYSDBA、パスがmasterkeというアカウントがいます。
このアカウントでログインし、
業務アプリで使うアカウントをDBMSに登録するなりセキュリティを設定するなりすればOKです。
CUIでFirebirdフォルダ\bin\gsec.exeを起動してゴリゴリがんばってください。
「unavailable database - unable to open database」
と出る場合、
・管理者権限があるか
・PCを再起動したり、サービスを再起動したりしてみる
・コントロールパネルにいるFirebird Control  Managerの状態を確認する
あたりをすれば、なんとかなると思います



5、サーバへのFDB登録と接続テスト
CUIで確認してもいいんですが、GUIツールがあると楽です。
IBOConsoleというソフトを使うと楽です。
firebird3.png
まずはDBサーバ接続を登録。
IBOConsoleを起動して、サービスへのアクセス設定を登録します。
そしてIBOConsoleにサーバー接続を登録します。
こうすれば、サーバがどのFDBを読み込むか、FDBを新規に作成するなどが行えます。


最後にサーバーにFDBのファイルパスを登録し、サーバがDBデータを見れるようにします。
これでFDBの中身が見れれば成功。アカウント設定が正しく設定されたことになります。
後は業務アプリから確認すれば完了といった感じです。

(※)
IBOConsoleからFDBの中身が見れるのに業務アプリでうまく動かない場合は、
そもそもサービスに正常にアクセスできてないか、アカウントを間違えていることになります。

久しぶりの作業なのでかなり忘れてました。
今ではSQLiteとMySQLに株を奪われてあまり使う機会もないので、なかなかあれですが。
でもFirebirdもなかなか使い勝手がいいですよ!
皆さんも試しに使ってみてはいかがでしょうか。

Oracleのvarchar2と空文字列とNULL

ORACLE、Oracle、oracle、オラクル、NULL、Null、null、SQL、Sql、sql、Database、database、データベース、DB、db

Oracleだと、空文字列('')とNULLが等価。
「colSTR1 <> ''」 なんて条件式を書こうもんなら、なにも出てこない。ええ、出てきませんもの。
「colSTR1 <> NULL」なわけですから。

ちなみに。
Nullと=や<>すると何も出てこないことは、DBでは基本ですが、ちゃんと理由も押えておきましょう。
Nullが=や<>ではいけない理由は、C++などと異なり3値論理の1つとして働くからです。
(C系統のプログラミング言語はnullは値で、3値論理の3つ目ではない。)
さらに言えば、NULL = NULLがTRUEではないのは、クリーネ方式を採用したものだからですね。

DBとプログラミング言語の比較
  • C系統のプログラミング言語
    a != Null   aはnull値か?
  • DBの場合
    a != Null   aは未知なる値と異なるか?
DBの3値論理はどれ?
  • ウカシェヴィッチ:indeterminate(不定)を加えたもの。不定同士は同じ値である。i=i は true
  • クリーネ:undefinedness(未定義)を加えたもの。未定義同士はわからない。u=uはu、u<>uはu。
  • ボフバール:meaningless(無価値)を加えたもの。無価値と演算すると問答無用で無価値になる。
補足
  • IN句:サブクエリ結果にNULLが含まれると、FALSEを返さない。(TRUEかNULLが返る。)
  • EXISTS句:サブクエリ結果にNULLが含まれても、NULLは返さない。

フリーエリア

takemori
Twitter : @takemori_kondo

1. Unityと戯れてます
2. Cake3は劣化じゃないRails

iOS
coming soon...

Windows
Html Editor - Nazuna
Managed DirectX サンプル集

beginning since
2006.08.17
renewaled on
2011.06.03

最新コメント

[2013/06/14 ミューネ]
[2012/08/30 ノートPC]