Oracle   Oracleちょっとメモ
  2001/01/13 - 2025/10/11

パスワードに「%」文字を含めるには?
ALTER USER USER1 IDENTIFIED BY "PASS%WORD";
のように二重引用符で囲めばOKです。一重だとエラーになるので注意。
SQL*Plusの「&」
SQL*Plusの変数置換「&」を効かないようにするには「SET DEFINE OFF」を使います。
SQL*Plusでリモートデータベースに接続するとき「@サービス名」部分を省略したい
環境変数TWO_TASKを定義します。
export TWO_TASK=REMOTEDB1
sqlplus USER1/PASS1
とすると、
sqlplus USER1/PASS1@REMOTEDB1
と同じ意味になります。
他の開発ツールで実行できるCREATE文が、SQL*PlusだとORA-00933エラーになる
ストアドプロシージャなど以外の「単一のDDL文」の中に空の行が含まれていると、 SQL*PlusではORA-00933(SQLコマンドが正しく終了されていません)エラーになるようです。
ストアドプロシージャにエラーがないのにORA-06508エラーになる
プロシージャAがBを呼び出す処理の時、Oracleセッション1でAを開き、 その後セッション2でBを開いて変更してコンパイルした後で、セッション1でAを実行すると、 Bにエラーがなくても「ORA-06508: PL/SQL:コールしているプログラム単位が見つかりません」が発生します。
この場合はおとなしくセッション1を終了し、再度接続して実行する必要があります。
SELECT文にDISTINCTを付けただけでORA-01791エラーになる
次のようなSQLだとどうなるでしょうか?
SELECT DISTINCT ORDER_NO||'-'||LINE_NO, ITEM_NAME
  FROM ORDERS WHERE BUYER_NAME = 'TARO' ORDER BY ORDER_NO, LINE_NO
これ、「ORA-01791: SELECT式が無効です。」というエラーになります。
DISTINCTを付けた場合、ORDER BYに指定できるのはSELECT句に含めたカラムだけになります。 したがって、エラーを解消するには、
SELECT DISTINCT ORDER_NO||'-'||LINE_NO, ORDER_NO, LINE_NO, ITEM_NAME
  FROM ORDERS WHERE BUYER_NAME = 'TARO' ORDER BY ORDER_NO, LINE_NO
このようにORDER_NO,LINE_NOをSELECT対象に入れるか、または
SELECT DISTINCT ORDER_NO||'-'||LINE_NO, ITEM_NAME
  FROM ORDERS WHERE BUYER_NAME = 'TARO' ORDER BY ORDER_NO||'-'||LINE_NO
このようにORDER BYの方を変えるかのいずれかにする必要があります。
DBMS_SQLパッケージでCREATE文を使うとORA-01031エラー
DBMS_SQLパッケージだと通常PL/SQLでは実行できないDDL文も実行できて便利、 ですが、データベースオブジェクトのDROPはできるのに、 CREATEしようとするとORA-01031エラー(権限が足りません)って? これはDBMS_SQLの仕様で、CREATE文を使う場合には、RESOURCEロールなどのロール経由ではなく、 CREATE SEQUENCE、CREATE TRIGGERなどそのものずばりの権限が必要です。
「PLS-00313: この有効範囲内で***が宣言されていません。」ってなあに?
PL/SQLパッケージやストアドプロシージャなどで内部プロシージャを定義している場合、 コールしている個所よりも上(前)に内部プロシージャの定義がなければこのエラーになります。 下(後ろ)に書いても認識されません。これはPL/SQLの大きな制約です。(9i時点では)
どうしてもプロシージャ定義をコール個所より上に書けない場合は、 「先に宣言だけ書いておく」という方法で回避できます。詳しくは、マニュアルで。
ALTER TABLE 〜 MOVE文の後にビューを参照するとORA-01502エラー
ALTER TABLE 〜 MOVE文を使うと、exp/TRUNCATE/impを行わなくてもセグメントの物理再編成 (最高水位標のリセット)が行え、便利です。 が、その対象表に索引が張られていると、セグメントの移動と同時に索引はUNUSABLE になってしまい、そのままビューなどで検索するとORA-01502エラーが発生します。
そのため、MOVE後は必ず対象表の索引をALTER INDEX 〜 REBUILDで再作成する必要があります。
参照整合性制約の参照先の表をTRUNCATEするとORA-02266エラー
参照整合性制約(外部キー制約)の参照「先」になっている表は、 TRUNCATEできません。これは例え参照元の表のデータが0件であってもできません。
DELETEではなくどうしてもTRUNCATEしたい場合は、一時的に制約をDISABLE CONSTRAINTで無効にするか、 DROP CONSTRAINTで削除してからTRUNCATEを実行する必要があります。
オブジェクト権限の検索
自分が他のユーザから付与されている権限はUSER_TAB_PRIVS_RECD、 自分が他のユーザに付与している権限はUSER_TAB_PRIVS_MADE というデータディクショナリを検索すると調べることができます。
「他スキーマのシノニム」へのシノニム
表USER1.FRUITSにシノニムUSER1.KUDAMONOがついており、 さらに別のユーザーUSER2にFRUITSのSELECT権限を付与しています。
CREATE SYNONYM KUDAMONO FOR FRUITS;
GRANT SELECT ON FRUITS TO USER2;
このとき、USER2が
CREATE SYNONYM KUDAMONO FOR USER1.KUDAMONO;
SELECT * FROM KUDAMONO;
を実行したらデータが見れるでしょうか?答えは見れます。
Oracleでは、シノニム自身にはSELECT権限という概念はありません。 まさに「別名」というラベルが貼られているだけの状態です。
この例のようにシノニム参照が多重化している場合、 最終的な参照先オブジェクトである USER1.FRUITS への権限を持っていれば、 シノニムを利用したデータ操作が可能です。
シノニムをGRANTするとどうなるの?
シノニムを他のスキーマ(ユーザー)にGRANT SELECTすると、エラーになりませんが、 USER_TAB_PRIVS_MADEにも出てきません。この状態はどうなってるの?
Oracleでは、シノニムをGRANTするということは、シノニムの参照先のオブジェクトをGRANTしている意味になります。 従ってすぐ上の例のように、他のOracleユーザーは、参照先のオブジェクトに対する権限を持っていれば、 シノニムを名指ししてそのオブジェクトを操作することも自動的にできるようになります。
整数を16進数に変換して文字列に格納する
SELECT TO_CHAR(255,'FMXXXX') FROM DUAL;
Xを大文字で書くと16進数のアルファベットが大文字に、小文字にすると16進数のアルファベットが小文字になります。
0.6は0.6、6は6と表記する
これは少しはまります。というのは、普通に TO_CHAR(0.6)とすると、「.6」という表記になるからです。 「0.6」にしたければ、TO_CHAR(0.6, 'FM999990.999)のようにすればOKですが、 今度は6が「6.」になってしまいます。
小数点が邪魔なんだけどなあ、邪魔だなあ…ではどうするか、 面倒なのでRTRIMすればいいんじゃないでしょうか(おーい)
SELECT RTRIM(TO_CHAR(6,'FM999990.999'), '.') FROM DUAL;
なお、FMをつけずに、代わりに'.0'をRTRIMしても同じ結果が得られます。
EBCDICコード順のORDER BY
以下のような感じで可能です。これは驚きました。
SELECT ORDER_NO, LINE_NO
  FROM ORDERS
 ORDER BY ORDER_NO, CONVERT(LINE_NO, 'JA16EBCDIC930');
表をある列でORDER BYし、先頭の1行だけを取り出す
3つの方法があります。1つ目はポピュラーな
SELECT ID, NAME, AGE FROM EMPS
 WHERE AGE = (SELECT MIN(AGE) FROM EMPS)
こんな感じですね(年齢が最も若い人のレコードを取得)。
ただし、複数の表を結合したり、「最も」ではなく「3番目」を取りたいといった場合難しくなってきます。 そのときは2つ目の方法として行番号を振るROW_NUMBER関数を使って
SELECT ID, NAME, AGE FROM (
  SELECT ID, NAME, AGE, ROW_NUMBER() OVER (ORDER BY AGE) RN FROM EMPS
) WHERE RN = 1
このように書けます。
ちなみに、ORDER BYする必要がなく、複数行返る可能性は分かっているが、 それらのどの行を取り出しても問題ないのであればROWNUM擬似列を使うのが分かりやすいです。
SELECT ID, NAME, AGE FROM EMPS WHERE ROWNUM = 1;
但し、ROWNUMはソートする前に連番を振ってしまうので、 どの行でもいいわけではなく、あくまでソートしてから1行目だけを取り出したい場合は、 ORDER BY有りのSQLを副問合せとして、ORDER BY無しのSQLで囲んで二重に書けばOKです。
SELECT ID, NAME, AGE FROM
 (SELECT ID, NAME, AGE FROM EMPS ORDER BY AGE) WHERE ROWNUM = 1;
表をある列でグループ化し、グループごとに別のソートキー列で連番を振る
上と同じ表を使い、所属課別・若い人順に連番を振る例です。
SELECT ID, NAME, AGE,
       ROW_NUMBER() OVER (PARTITION BY DEPT_NO ORDER BY AGE) RN FROM EMPS
これにWHERE句をつけると、「総務部で3番目に若い人は誰か」のような検索ができます(あまり現実的でないか)。 もっと実用的な例で言えば、店舗の営業日カレンダーマスタなんかに使えますね。 「ある月の第3営業日は何日か?」のような問合せは在庫管理システムなどでいかにもありそうです。
表を横向きに集計する
「横向きに集計」って何じゃ? うーん、これはなんと表現していいのか分からない表現方法ですが、 企業データベースを運用していると、 利用者に結構よく依頼される集計方法ではあると思います。
ええと、 1つの注文番号で複数のお届け先がありうるとします。
ORDER_NO | OTODOKESAKI
-----------------------------------
00012345 | 横浜市西区南幸z-z-zz
00012345 | 新潟市中央区柳島町z-z-zz
00034567 | 横浜市西区南幸z-z-zz
00034567 | 新潟市中央区柳島町z-z-zz
00034567 | 大阪市淀川区西中島z-z-zz
...
これを
ORDER_NO | お届け先1            | お届け先2                | お届け先3
------------------------------------------------------------------------------------
00012345 | 横浜市西区南幸z-z-zz | 新潟市中央区柳島町z-z-zz | 
00034567 | 横浜市西区南幸z-z-zz | 新潟市中央区柳島町z-z-zz | 大阪市淀川区西中島z-z-zz
SQL1個でこのように集計したいという。 これは次のようにすれば可能です。
SELECT a.ORDER_NO,
       MAX(CASE WHEN a.RN = 1 THEN a.OTODOKESAKI ELSE NULL END) AS OTO1,
       MAX(CASE WHEN a.RN = 2 THEN a.OTODOKESAKI ELSE NULL END) AS OTO2,
       MAX(CASE WHEN a.RN = 3 THEN a.OTODOKESAKI ELSE NULL END) AS OTO3,
       MAX(CASE WHEN a.RN = 4 THEN '他' ELSE NULL END)          AS OTO4
  FROM
(SELECT ORDER_NO, OTODOKESAKI,
        ROW_NUMBER() OVER (
          PARTITION BY ORDER_NO ORDER BY DELIVERY_DATE ) AS RN
   FROM DELIVERY_DB) a
 GROUP BY a.ORDER_NO
DECODE関数が返すデータ型
CASE WHENに置き換えが可能なので、今後はもうあまり使うことはないDECODE関数ですが、 一応豆知識を。
DECODE(COL1, '1', NULL, '2', 100, 200)
を実行したとき、COL1の値が'3'だった場合、整数の200が返ると思うかな?
違います。文字列の'200'が返ってしまいます。
DECODE関数の戻り値のデータ型は、DECODE(s, r1, v1, r2, v2, r3, v3...) とやったとき、v2やv3のデータ型には一切関係なく、常にv1のデータ型が採用されます。 v1がNULLであれば、v2やv3のデータ型には一切関係なく、常にVARCHAR2型で返されます。
ストアドプロシージャの更新日とソースコードを検索する
SELECT b.NAME, b.TYPE, MAX(TO_CHAR(a.LAST_DDL_TIME, 'YYYY/MM/DD HH24:MI:SS')),
       MAX(b.LINE), SUM(LENGTHB(b.TEXT))
  FROM USER_OBJECTS a, USER_SOURCE b
 WHERE a.OBJECT_NAME = b.NAME
   AND a.OBJECT_TYPE = b.TYPE
 GROUP BY b.NAME, b.TYPE
 ORDER BY b.NAME, b.TYPE
ソースコードに特定の文字列を含むストアドプロシージャ、ファンクション、パッケージを抽出する
SELECT DISTINCT NAME, TYPE FROM USER_SOURCE
 WHERE TYPE IN ('PROCEDURE', 'FUNCTION', 'PACKAGE') AND TEXT LIKE '%TARGET_STRING%';
ストアドプロシージャをコンパイルしてもLAST_DDL_TIMEが更新されない
コンパイル前後で内容が全く同じだと、コンパイルしても USER_OBJECTS.LAST_DDL_TIMEは更新されないようです。
あるはずのデータが見れない!
SELECT ITEM_CODE FROM TABLE_A a
 WHERE NOT EXISTS (SELECT 1 FROM TABLE_B WHERE ORDER_NUMBER = a.ORDER_NUMBER)
TABLE_Bに存在しない注文番号をTABLE_Aから探し、その品目コードを表示するという、 超ありがちな例ですが、そのようなデータが存在するはずなのに、 1件も該当しません。なぜでしょうか。
ありがちな例として、TABLE_Aの注文番号がORDER_NUMBER、 TABLE_Bの注文番号がORDER_NOだったとしたら? 「それなら列名が違うからエラーになるだろう」と思ってSQLを再度よく見ると? 「(SELECT 1 FROM TABLE_B WHERE ORDER_NUMBER = a.ORDER_NUMBER)」 の左側のORDER_NUMBERは、当然TABLE_Bの列だろうと読めてしまいますが、 TABLE_BにはORDER_NUMBERという列はないのにエラーにならない? そうです、左も右もORDER_NUMBERはTABLE_Aの同じ列を指しているので、 このSQLでは該当行が現れることはありません。
EXPLAIN PLANで実行計画を見ようとすると 「ORA-01039 insufficient privileges on underlying objects of the view (ORA-01039: ビューのもとになるオブジェクトに関する特権が不十分です)」 というエラーが出る。
これはビューの実行計画を見ようとしているときに、ビュー自体のSELECT権限を持っていて、 その元表になる表(のどれか)のSELECT権限を持っていない場合に発生します。 実行計画を見るには、全ての元表に対するSELECT権限も必要です。
Oracle8iでPRAGMA AUTONOMOUS_TRANSACTIONで自立型トランザクションを行わせると、 ORA-00164 「移行可能な分散トランザクション内で自立型トランザクションの処理はできません」 というエラーが出る。
トランザクションの中で、データベースリンクを使って別のデータベースを参照している場合、 自立型トランザクションは開始できません。 そのような処理を一旦確定してセッションを切り、 再度別のトランザクションとして自立型処理を含む処理を実行します。
シーケンスにいつも20くらいの飛び(欠番)が発生する!
CREATE SEQUENCE文でNOCACHEオプションをつけていないと、デフォルトで「CACHE 20」となります。 このCACHE句がついていると、1つのセッションで続けて高速に連番を発番できるように、 幾つかの値をまとめて発番してメモリに先に取得しておく、ということが行われますが、 使われずにセッションが終了すると残りは欠番になります。 20くらい飛ぶという現象は多分これが原因です。 欠番を出すのが嫌で、1セッションで1つしか発番しない場合は、NOCACHE句をつければOKです。 なおWebの情報によると、CACHEの効果はそんなに劇的なものではないそうです…
文字列の簡単な暗号化
Oracle8i以降では、DESまたはDES3方式で簡単に文字列を暗号化することができ、 ユーザーのパスワードなどをテーブルに格納する際に便利に使えます。
DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT(
    input_string => lv_plain_pass,
    key_string => lv_key,
    encrypted_string => lv_enc_pass
);
暗号化には、「DBMS_OBFUSCATION_TOOLKIT.DESENCRYPT」や 「DBMS_OBFUSCATION_TOOLKIT.DES3ENCRYPT」を使い、 復号には「EN」が「DE」に変わった名前の関数を使います。
引数の名前を明示しているのは、 オーバーロードしている関数があるためです。 つまり引数の名前を指定しないと PLS-00307 (複数のプロシージャが宣言されている) というエラーになります。
入力文字列(上記の例のlv_plain_pass)は、文字列の長さ(バイト数)が8の倍数でなければいけません。 つまり、少なくとも8バイトの長さが必要で、 それを超える場合には16、24…という長さに文字列を合わせてやる必要があります。
元表の持ち主にビューをGRANTしてもORA-01720が発生する
スキーマAが表CHUMONを、スキーマBが表ZAIKOを持っているとします。 AがBに「GRANT SELECT ON CHUMON」して、BがCHUMONとZAIKOからビューNYUKO_VIEWを作りました。 普通に考えると、このビューをそのままBがAにGRANT SELECTできそうですが、実際にはORA-01720が発生します。
そうです、AがBに「GRANT SELECT ON CHUMON」する際に「WITH GRANT OPTION」をつけない限り、 相手が元表の持ち主といえどもビューを公開することはできません。
普通に発行できるSQLをPL/SQLの中で使うとORA-00942でコンパイルエラーになる
他のユーザの表やビューにアクセスしている、 単独では普通に発行できるSQLを、PL/SQLストアドプロシージャの中で使うと 「ORA-00942:表またはビューが存在しません」になることがあります。
これは、実行に必要な権限の一部を、ロール経由で付与されていると発生します。 例えば、MY_ROLEロールをつくり、SELECT ANY TABLEシステム権限をMY_ROLEに付与し、 MY_ROLEを各ユーザに付与すれば、 各ユーザは他ユーザの表やビューを個別のGRANTなしにSELECTできるようになります。 しかし、同じSELECT文をストアドプロシージャの中で使おうとすると、 ORA-00942でコンパイルエラーになってしまうのです。
Oracleは一意制約違反になる条件がおかしい?
複数の列からなる一意制約(UNIQUE)を定義しているとき、 それらの値が全てNULLの行はいくつあってもエラーになりませんが、 一部の列の値が同じで、一部の列の値がNULLという行を複数作ろうとすると、 一意制約違反が発生します。
つまり例えば、表に3つの列からなる一意制約を付けたとします。 それらの値が(NULL,NULL,NULL)の行はいくつあっても一意制約違反になりませんが、 (値A、値B、NULL)という行が複数作られようとすると、一意制約違反になります。 直感的にはよく分からない仕様ですね。 RDBMSとはこういうものなのか、それともOracleだけが特殊なのか? 全てはなぞのままなのであった。(帰れ)
「1.2.3」のような「本の章立て」みたいなデータを並び替える
「1.2.3」のような文字列をそのままASCIIコード順に並び替えると「1.10」が「1.1」と「1.2」の間に来てします。
これを正しく並び替える方法は色々考えられますが、一例として次のようなソートキーを作る方法があります。 この例では「.1」または「{行頭}1」を「.01」と左0詰して2桁に揃えた後、 元々の「10」が「010」になっているのを後ろ2桁に削り直しています。これをORDER BYに食わせれば所望の事ができると思います。
なおこの例は「1.100.3」のような3桁以上の数字には非対応です。
SELECT REGEXP_REPLACE(REGEXP_REPLACE('1.3.4',  '(\.|\A)(\d)', '.0\2'), '\d(\d\d)', '\1') FROM DUAL;
.01.03.04
SELECT REGEXP_REPLACE(REGEXP_REPLACE('1.23.4', '(\.|\A)(\d)', '.0\2'), '\d(\d\d)', '\1') FROM DUAL;
.01.23.04
副問合せを使って更新する
品目マスタの各品目の価格を、新テーブルの同じ品目の価格で更新するような例です。
UPDATE ITEMS a
   SET PRICE = (SELECT PRICE FROM NEW_ITEMS b WHERE b.PRICE = a.PRICE)
 WHERE EXISTS  (SELECT 1     FROM NEW_ITEMS b WHERE b.PRICE = a.PRICE)
副問合せを二重に使うなんて、処理がものすごく遅いんじゃないのと一見思ってしまいがちですが、 やってみると場合にもよりますが割と負荷にならないこともありますよ。不思議ですね(←あるまじき発言)
SELECT文の結果で複数列を更新する
よくある例が、業務テーブルのレコードの 「更新者ID、更新者氏名、更新者所属部署ID、更新者所属部署名」を従業員テーブルを検索して一括更新したい場合です。
ストアドプロシージャを作らなくても、次のようにSQL一発で実行できます。これは超便利。
UPDATE ORDERS
   SET (UPDATED_USER_ID, UPDATED_USER_NAME, UPDATED_USER_SEC_ID, UPDATED_USER_SEC_NAME) =
       (SELECT USER_ID, USER_NAME, USER_SEC_ID, USER_SEC_NAME FROM EMP_DB WHERE USER_ID = 'U0001')
 WHERE ORDER_ID = "A123"
SYSDBAで接続しようとするとORA-01017が発生する
sqlplus / as sysdba や connect / as sysdba でORA-01017(logon denied)が起きる原因を一つずつ見ていきます。
1. そもそもOracleインスタンスが起動していない。
2. 環境変数ORACLE_HOMEやORACLE_SIDが正しく設定されていない。
3. 実行しているOSユーザーがdbaグループに所属していない。groupsコマンドを実行してdbaが出てこなければアウトです。
4. sqlnet.oraでOS認証が許可されていない。 sqlnet.oraは通常 $ORACLE_HOME\network\admin に置かれています。 Windowsの場合は
SQLNET.AUTHENTICATION_SERVICES= (NTS)
Linuxの場合は
SQLNET.AUTHENTICATION_SERVICES= (BEQ)
と記述します。(NONE)と書かれていたらそれはOS認証を許可しない設定です。
なお、NTSはWindows、BEQはLinux/UNIX専用の認証方式です。逆側を書いても認証が効くようにはなりません。
また、sqlnet.oraの設定を変えたらOracleインスタンスやリスナーは再起動した方がいいの? ネット情報では様々ですが、ざっくり言うと認証方式に関する設定を変えた場合は再起動が必要で、 その他の設定を変えた場合は不要です。よくわからん場合は再起動した方が無難です。
アーカイブログモードで、残しておくべきアーカイブログファイルの表示
オンライン・バックアップを行うと、V$BACKUPにバックアップした日付が残るので、 全てのデータファイルのバックアップ日付より古いアーカイブログファイルは削除することができます。 下のSQLは、残しておかなくてはいけないアーカイブログファイルのみを抽出するものです。
SET PAGESIZE 50
SET HEADING OFF
SELECT NAME || ' ' || SEQUENCE# || ' ' || NEXT_CHANGE#
  FROM V$ARCHIVED_LOG
 WHERE NEXT_CHANGE# >= (SELECT MIN(CHANGE#) FROM V$BACKUP
                       WHERE CHANGE# > 0);
データファイルを使用しているDBオブジェクトの検出
データ量が大きく減少して、表領域に空きができた、 というときにはデータファイルのサイズを減らしたいものですが、 所望のサイズを越えるブロックを占有しているデータベースオブジェクトがあってなかなか減らせない、 というようなときに下のSQLが役に立ちます。 まず、DBA_DATA_FILES表を検索して、データファイル名からファイルIDを知ります。 そのうえで、下のようにファイルIDと、所有者や表領域名も使って検索を行います。
SELECT A.SEGMENT_NAME, A.EXTENT_ID, A.FILE_ID
  FROM DBA_EXTENTS A
 WHERE A.OWNER = 'PO' AND A.TABLESPACE_NAME = 'POX'
   AND A.FILE_ID = 22
 ORDER BY A.SEGMENT_NAME
Oracle Instant Clientって
Instant Clientは 米国サイトで常に最新版が入手できるほか、 日本語サイトでも10gなら入手できます。(2008/05/27現在) 入手、設定方法は以下の通りです。
  1. お勧めは「Basic」と「SQLPlus」です。この2つをダウンロードし、同じディレクトリで展開します。 「Basic Lite」は、日本語のNLS_LANGをサポートしておらず、 sqlplus.exeを使うと「NLS Initialization Error」というエラーになり、 PHPでも「OCIEnvNlsCreate() failed:なんとか」というエラーになり使えません。まったく使えないと思ってよいでしょう。
  2. 特にインストーラなどでシステムに書き込んだりしないので、展開したディレクトリは好きな場所に移動、改名できます。 ここではC:\oracle\instantclient11という名前にしたとします。
  3. 自分でテキストエディタなどを使ってtnsnames.oraを作り、C:\oracle\instantclient11に配置します。
  4. システム環境変数を設定します。
    1.PATHにC:\oracle\instantclient11を追加
    2.TNS_ADMIN=C:\oracle\instantclient11と定義
    3.ORACLE_HOME=C:\oracle\instantclient11と定義
    4.NLS_LANGに「JAPANESE_JAPAN.JA16SJIS」など適切な値を設定
  5. これでsqlplus.exeを起動して、接続を試します。「sqlplus taro/taropass@remote_db」問題なく接続できればokです。

  もくじ
Oracle   (C) 2002-2025 MISUMI URANO