質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

6558閲覧

PL/SQLの2次元配列の作り方について

teefpc

総合スコア111

Oracle

Oracleは、米オラクルが取り扱うリレーショナルデータベース管理システムです。メインフレームからPCまで、多様なプラットフォームに対応しています。

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2019/12/19 13:21

編集2019/12/19 15:40

PL/SQL で、テーブルの型に合わせた2次元配列を作りたいのですが、

普通、多次元配列の作り方は、

PL/SQL

1TYPE tElement IS TABLE OF NUMBER INDEX BY BINARY_INTEGER; 2TYPE tSquare IS TABLE OF tElement INDEX BY BINARY_INTEGER; 3 4vSquare tSquare; 5vSquare(0)(0) := 0; 6vSquare(0)(1) := 1; 7... 8

出典https://www.shift-the-oracle.com/plsql/collection/multi-dimension-array.html

のように書きますが、ここで、データ型を、あるテーブルAと同じにしたいのです。

やってみたことは、1行目を書き換えて、

PL/SQL

1TYPE tElement IS TABLE OF MY_TABLE_A%ROWTYPE INDEX BY BINARY_INTEGER; 2TYPE tSquare IS TABLE OF tElement INDEX BY BINARY_INTEGER; 3 4vSquare tSquare; 5vSquare(0)(0) := 1000; 6vSquare(0)(1) := 'ABC'; 7...

TABLE

1CREATE TABLE MY_TABLE_A ( 2 num NUMBER(5) NOT NULL, 3 name VARCHAR2(15) NOT NULL, 4 score1 NUMBER(10) NOT NULL, 5 score2 NUMBER(10) NOT NULL, 6 score3 NUMBER(10) NOT NULL, 7 score4 NUMBER(10) NOT NULL, 8 score5 NUMBER(10) NOT NULL, 9 score6 NUMBER(10) NOT NULL, 10 score7 NUMBER(10) NOT NULL, 11 score8 NUMBER(10) NOT NULL, 12 score9 NUMBER(10) NOT NULL 13);

としてみたことです。
しかし、どこでおかしくなっているのかわかりませんが、vSquareのどこかのデータを取得しようとすると、「型が違います」というエラーで中断されます。

たとえば、

PL/SQL

1IF vSquare(0)(10) = 0 THEN /* ここで型エラー TO_CHAR(0)でも同様 */ 2 /* 処理 */ 3END IF;

のようなことをすると、たちまち落ちます。配列の要素が空だったからではないかと思い、初期値をいれておいてもダメでした。

ところで、最初のサンプルのコード元は、配列の要素を

PL/SQL

1 /* 抜粋 */ 2 FOR i in 1 .. 9 LOOP 3 FOR j in 1..9 LOOP 4 P_ARRAY(i)(j) := i * j; 5 END LOOP; 6 END LOOP;

と、1から指定して、0から指定していません、計算の都合上からでしょうか。それともPL/SQLの仕様でしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Orlofsky

2019/12/19 14:43

PL/SQLです。大文字小文字はきちんと区別して書けた方が良いです。
teefpc

2019/12/19 14:52

見出しとリンクを修正しました
Orlofsky

2019/12/19 15:10

... MY_TABLE_A%ROWTYPE 質問に MY_TABLE_A の CREATE TABLE を追記してください。
Orlofsky

2019/12/19 15:11

宣言や実行文の終わりは ; です。抜けているところがあります。
teefpc

2019/12/19 15:40

テーブル定義を追加しました。
teefpc

2019/12/19 15:41

コードを修正しました。
guest

回答2

0

ベストアンサー

vSquare(0)(0) が MY_TABLE_A%ROWTYPE なので

SQL

1SQL> DECLARE 2 2 TYPE tElement IS TABLE OF MY_TABLE_A%ROWTYPE INDEX BY BINARY_INTEGER; 3 3 TYPE tSquare IS TABLE OF tElement INDEX BY BINARY_INTEGER; 4 4 vSquare tSquare; 5 5 BEGIN 6 6 vSquare(0)(0) := 1000; 7 7 vSquare(0)(1) := 'ABC'; 8 8 END; 9 9 / 10vSquare(0)(0) := 1000; 11 * 126でエラーが発生しました。: 13ORA-06550: 行6、列18: 14PLS-00382: 式の型が正しくありません。 15ORA-06550: 行6、列1: 16PL/SQL: Statement ignored 17ORA-06550: 行7、列18: 18PLS-00382: 式の型が正しくありません。 19ORA-06550: 行7、列1: 20PL/SQL: Statement ignored

となります。

SQL

1SQL> DECLARE 2 2 TYPE tElement IS TABLE OF MY_TABLE_A%ROWTYPE INDEX BY BINARY_INTEGER; 3 3 TYPE tSquare IS TABLE OF tElement INDEX BY BINARY_INTEGER; 4 4 vSquare tSquare; 5 5 BEGIN 6 6 vSquare(0)(0).NUM := 1000; 7 7 vSquare(0)(1).NAME := 'ABC'; 8 8 END; 9 9 / 10 11PL/SQLプロシージャが正常に完了しました。

こうなっていれば実行できます。

投稿2019/12/20 00:03

KOZ6.0

総合スコア2626

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teefpc

2019/12/20 00:28

ありがとうございました。
guest

0

PL/SQLに関する質問に対する回答

PL/SQLでは無名ブロックでの宣言は

SQL

1DECLARE -- 宣言するものがあれば 2 ここで宣言を記述 ; 3BEGIN 4 ここで実行文を記述 ; 5EXCEPTION -- 例外があれば記述 6 .... 7END ; 8/

ストアドでの宣言は

SQL

1CREATE ... 2IS 3 ここで宣言を記述 ; 4BEGIN 5以下略

PL/SQLの入門書を1冊買ってきて勉強されては?
わたしは有償で出向いて教えることもあります。その方が早くまともなコードを書けるようになるのでトータルでは安上がりです。

投稿2019/12/19 15:03

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

teefpc

2019/12/19 15:44 編集

ありがとうございます。ということは、配列の使い方は合っているということですね。
Orlofsky

2019/12/19 16:07

いいえ、PL/SQLでは配列の添字は 1 からで 0 はありません。
Orlofsky

2019/12/19 16:13

テーブルの用途がわかりませんが、 SQLをシンプルにパフォーマンス良く実行できるように、データベースのテーブルは データベースの正規化 https://oss-db.jp/measures/dojo_info_04.shtml に沿って設計します。通常、第3正規化まで行います。第1正規化で繰り返し(今回は配列)を排除します。 通常、第3正規化まで行います。
teefpc

2019/12/19 22:45

質問中のテーブルは処理の流れの中で一時的に作られるワークテーブルです。或るトランザクションテーブルのデータをピボットテーブルのように集計しながら縦横を入れ替えて作り変えます。そのためPL/SQL内で、出力するワークテーブル用のバッファを作る必要がありました。
teefpc

2019/12/20 00:29

ありがとうございました。こちらも参考にさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問