
こんばんは。
oracle9iでPL/SQLを使用して、CSVファイルを
読み込んで、テーブルの更新を行いたいと
思っています。
CSVファイル、テーブル共に最初の2つがキー項目です。
■CSVファイル
001, 111, 10000, 20000
002, 222, 30000, 40000
・・・・・
・・・・・
009, 999, 55555, 55555
■テーブル
001, 111, 99999, 99999
002, 222, 99999, 99999
・・・・・
・・・・・
009, 999, 99999, 99999
■テーブル(処理後)
001, 111, 10000, 20000
002, 222, 30000, 40000
・・・・・
・・・・・
009, 999, 55555, 55555
わかったのは、CSVファイルを行単位で読み込む所までです。
DECLARE
File_Handle UTL_FILE.FILETYPE;
Read_Line VARCHAR2(1023);
BEGIN
File_Handle := UTL.FILE.FOPEN('dir', 'file', 'r');
BEGIN
LOOP
UTL.FILE.GETLINE(File_Handle, Read_line);
END LOOP;
END;
UTL.FILE.FCLOSE(File_Handle);
END;
1行を読み込んだのはいいけど、この後がよくわかりません。テーブルを更新する所とあわせて、ご教示ください。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
基本的に GoF さんの意見に賛成です。
方法がスマートなのはそちらかなというだけなのですが・・
PL*SQL でやろうとするのであれば、以下のようにすることで
出来るのではないかと思います。
プログラマではないので、コーディングが下手な部分は許してください。
あくまで参考として捕らえてください。
-- test.csv
001, 111, 10000, 20000
002, 222, 30000, 40000
003, 333, 50000, 60000
004, 444, 70000, 80000
005, 555, 90000, 55555
006, 666, 55555, 55555
007, 777, 55555, 55555
008, 888, 55555, 55555
009, 999, 55555, 55555
--定義
create table test (col1 varchar2(3),
col2 varchar2(3),
col3 varchar2(5),
col4 varchar2(5));
--初期データ
insert into test values ('001','111','99999','99999');
insert into test values ('002','222','99999','99999');
insert into test values ('003','333','99999','99999');
insert into test values ('004','444','99999','99999');
insert into test values ('005','555','99999','99999');
insert into test values ('006','666','99999','99999');
insert into test values ('007','777','99999','99999');
insert into test values ('008','888','99999','99999');
insert into test values ('009','999','99999','99999');
**********************************************************
SQL> select * from test;
COL COL COL3 COL4
--- --- ----- -----
001 111 99999 99999
002 222 99999 99999
003 333 99999 99999
004 444 99999 99999
005 555 99999 99999
006 666 99999 99999
007 777 99999 99999
008 888 99999 99999
009 999 99999 99999
9行が選択されました。
SQL> DECLARE
2 c1 number;
3 c2 number;
4 c3 number;
5 c4 number;
6 data1 varchar2(100) := null;
7 data2 varchar2(100) := null;
8 data3 varchar2(100) := null;
9 data4 varchar2(100) := null;
10 File_Handle UTL_FILE.FILE_TYPE;
11 Read_Line VARCHAR2(1023);
12 BEGIN
13 File_Handle := utl_file.fopen('c:\temp', 'test.csv', 'r');
14 LOOP
15 BEGIN
16 UTL_FILE.GET_LINE(File_Handle, Read_line);
17 -- カンマ位置
18 c1 := instr(Read_line,',',1,1);
19 c2 := instr(Read_line,',',1,2);
20 c3 := instr(Read_line,',',1,3);
21 c4 := length(Read_line);
22 -- 列データ
23 data1 := ltrim(substr(Read_line,1 ,c1-1));
24 data2 := ltrim(substr(Read_line,c1+1,c2-c1-1));
25 data3 := ltrim(substr(Read_line,c2+1,c3-c2-1));
26 data4 := ltrim(substr(Read_line,c3+1,c4));
27 -- update
28 update test set col3 = data3
29 where col1=data1 and col2=data2;
30 update test set col4 = data4
31 where col1=data1 and col2=data2;
32 commit;
33 exception
34 when no_data_found then exit;
35 END;
36 END LOOP;
37 UTL_FILE.FCLOSE(File_Handle);
38 END;
39 /
PL/SQLプロシージャが正常に完了しました。
SQL> select * from test;
COL COL COL3 COL4
--- --- ----- -----
001 111 10000 20000
002 222 30000 40000
003 333 50000 60000
004 444 70000 80000
005 555 90000 55555
006 666 55555 55555
007 777 55555 55555
008 888 55555 55555
009 999 55555 55555
9行が選択されました。
No.3
- 回答日時:
回答ではないのですが
ファイルをアクセスして取り込むのも一つの方法ですが
別のアプローチでのやり方をお勧めします。
・CSVファイルを外部表の読み取り表として定義する。
・MERGE文でINSERT/UPDATEする。
これでやるメリットは、仕様変更に柔軟に対応でき、
普通のSQLだけなのでファイルIOエラーを意識する必要がありません。
No.2
- 回答日時:
#1 diashun です。
訂正です。
CustCode := SUBSTRB(line,1,3); の「line」は
「Read_line」に修正してください。
(他の箇所も)・・・お手数です。
No.1
- 回答日時:
/*処理したいテーブル名が仮に「顧客マスタ」とし、列名を最初から「会社コード」「会社名」「住所」「電話番号」と仮定します。
次に宣言部に変数を追加します。*/
CustCode 顧客マスタ.会社コード%TYPE;
CustName 顧客マスタ.会社名%TYPE;
Address 顧客マスタ.住所%TYPE;
TelNo 顧客マスタ.電話番号%TYPE;
/*次に
loop
UTL_FILE.GET_LINE(File_Handle, Read_line);の
後に以下を記述します。(桁数はmkimさんの参考例)*/
CustCode := SUBSTRB(line,1,3);
CustName := SUBSTRB(line,4,3);
Address := SUBSTRB(line,8,5);
TelNo := SUBSTRB(line,14,5);
INSERT INTO 顧客マスタ (会社コード,会社名, 住所
,電話番号)
VALUES (CustCode, CustName, Address,
TelNo);
end loop;
/*念のため例外処理も・・・*/
EXCEPTION
WHEN NO_DATA_FOUND then
dbms_output.put_line('正常終了');
commit;
utl_file.fclose(File_Handle);
WHEN OTHERS then
dbms_output.put_line('エラー発生');
rollback;
utl_file.fclose(File_Handle);
/* おしまい (頑張って下さい)-----------*/
end;
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP 値の取り出し方について教えて下さい。 1 2023/03/31 13:30
- Ruby 教えてください 2 2023/01/04 17:50
- その他(プログラミング・Web制作) セレクトボックスで選択された値をコントローラーで使用したい 2 2022/07/26 16:41
- Visual Basic(VBA) このVBAでExcelアプリケーションを作成は必要ですか? 3 2023/07/19 21:13
- Access(アクセス) access,vbaでフォルダ内のファイルをテーブルにインポート、ファイル名もフィールドに追加したい 1 2022/08/31 11:11
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
- C言語・C++・C# #include <stdio.h>int main(void) { int buf[100] = 6 2022/11/01 22:45
- その他(プログラミング・Web制作) Fortranでの出力ファイル 2 2023/03/21 21:25
- Visual Basic(VBA) vbaの構文の修正相談(xmlファイルを順に開いてコピペ作業) 1 2023/04/22 01:18
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
このQ&Aを見た人はこんなQ&Aも見ています
-
SQLローダーCSV取込で、囲み文字がデータ中に入っている場合について
Oracle
-
データ削除とSQL*Loaderでのインポート
Oracle
-
SQL*Loader Append
Oracle
-
-
4
PL/SQLで文字列を分割
Oracle
-
5
PL/SQLでログを確認したい。
Oracle
-
6
既存データをINSERT文にして出力するツールは?
Oracle
-
7
SELECT INTOで一度に複数の変数へ代入をするにはどのようにすれがよいでしょうか?
PostgreSQL
-
8
ORA-29280:無効なディレクトリ・パスです
Oracle
-
9
SQLローダーで複数のCSVファイルのデータを一つのテーブルにInsertしたい
その他(データベース)
-
10
Statement ignored というエラー
Oracle
-
11
SQL*Plusで、コマンドの返答を非表示にする方法
Oracle
-
12
PL/SQLでSPOOLさせたいのですが、可能でしょうか?
Oracle
-
13
PL/SQLをWindowsのBATファイルで実行するには
Oracle
-
14
カンマがデータとして入ってるCSVについて
Oracle
-
15
異なるスキーマからデータを抽出するには?oracl、PL/SQL
Oracle
-
16
SQL*LoaderでCSVから指定した列のみインポートしたい。
Oracle
-
17
FTPで書き込み中のファイルの完了を知りたい
C言語・C++・C#
-
18
【PL/SQL】FROM区に変数を使う方法
Oracle
-
19
変数が選択リストにありません
Oracle
-
20
SQLPLUSで結果を画面に表示しない
Oracle
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CSVファイルを読み込んでテーブ...
-
平均値のもとめ方
-
データがリストアできない!!
-
型について
-
timestamp が空のデータを除い...
-
配列データに対する、要素の追...
-
SQLSERVER 連番更新について
-
【SQL】他テーブルに含まれる値...
-
フラグをたてるってどういうこ...
-
SELECT INTOで一度に複数の変数...
-
sqlに記述できない文字
-
UPDATEで既存のレコードに文字...
-
'modify' 付近に不適切な構文が...
-
エラーを起こす方法
-
SQLサーバに対するSQL文で抽出...
-
truncate tableを使って複数の...
-
複数の条件に該当する結果を、...
-
SELECT文の結果をDEFINEの値と...
-
オラクルのUPDATEで複数テーブル
-
既存データをINSERT文にして出...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CSVファイルを読み込んでテーブ...
-
SQLSERVER 連番更新について
-
timestamp が空のデータを除い...
-
テキストボックスの背景をVB...
-
ACCESS テキストボックスに入...
-
SELECT文で足し算をした場合、N...
-
エクセルVBA 10分後にエクセル...
-
エクセルVBEについて
-
date型でのbetweenについて教え...
-
Accessエクスポート時に連番を...
-
1つのドメインを複数のDNSで管...
-
配列データに対する、要素の追...
-
【Access】SQL文教えてください!
-
データがリストアできない!!
-
型について
-
Access VBA Excelbookを開く際...
-
PostgreSQLのnumericでの書き込...
-
エクセル vba 色分け
-
Japanese schools
-
バッチファイルでrenを使用時、...
おすすめ情報