『ボヘミアン・ラプソディ』はなぜ人々を魅了したのか >>

下記PLSQLを実行した時に(sqlplus上で、@XXXX.SQLと実行)
WCOUNT :=WCOUNT + 1; エラー
PLS-00201: 識別子WCOUNTを宣言してください
のエラーがでます
宣言をしているのですがわからず、お助けください
また、他にもこのエラーを処置したあとに問題と
なりそうな箇所があれば指摘お願いします

-やろうとしてること
(1)テーブルA を、男子を出席順に読み込んでその読み込んだ順番に
1から番号をふり、テーブルBへ新規追加する
(2)テーブルAからテーブルBに新規追加していない女子を、出席順に読み込んで
1から番号をふり、テーブルBへ新規追加する
(3)テーブルBのKEYは順番のみ
(4)テーブルBのINSERT分は、今後機能追加する予定なのでNOT IN使用する


-組んだPL/SQL(2つのINSETを1つのファイルに記述しています)
DECLARE
WCOUNT number;
CURSOR カーソル IS
SELECT 出席番号,名前,成績 FROM テーブルA 
ORDER BY 出席番号;
BEGIN
FOR r IN カーソル LOOP
INSERT INTO テーブルB
(r.順番, r.名前,r.出席番号)
VALUES (WCOUNT,r.名前);
COMMIT;
WCOUNT :=WCOUNT + 1;
END LOO;
/
END;

DECLARE
CURSOR カーソル IS
SELECT 出席番号,名前,成績 FROM テーブルA A
WHERE A.出席番号 NOT IN (SELECT B.出席番号 FROM テーブルB B)
ORDER BY 出席番号;
BEGIN
FOR r IN カーソル LOOP
INSERT INTO テーブルB
(順番, 名前)
VALUES (WCOUNT,r.名前);
COMMIT;
WCOUNT :=WCOUNT + 1;
END LOOP;
/
END;

このQ&Aに関連する最新のQ&A

A 回答 (2件)

タイプミスがありました。


一行目のVARですが・・
VAR WCOUNT NUMEBR => VAR WCOUNT NUMBER

SQL*PLUS上なら、特別な作業を必要とせずに、バインド変数は使えるはずです。
    • good
    • 0

投稿されたSQLは、明らかな転記ミスと思しき箇所があるので、


何が転記ミスで、何が本来の問題点なのか区別が付かないのですが・・

declare ~(a)~ begin ~(b)~ end;
/
declare ~(c)~ begin ~(d)~ end;
/
という一連のスクリプトの場合、(a)で定義した変数は、(b)で有効ですが、
別の無名ブロックである(d)では、利用できません。改めて(c)で定義する必要があります。
無名ブロック間で変数を共有する場合、declareで定義するPL/SQL変数ではなく、
バインド変数を使います。(SQL*PLUSのVARコマンド参照)

--ここから
VAR WCOUNT NUMEBR
DECLARE
CURSOR カーソル IS
SELECT 出席番号,名前,成績 FROM テーブルA ORDER BY 出席番号;
BEGIN
FOR r IN カーソル LOOP
INSERT INTO テーブルB (r.順番, r.名前,r.出席番号) VALUES (:WCOUNT,r.名前);
COMMIT;
:WCOUNT := :WCOUNT + 1;
END LOOP;
END;
/
DECLARE
CURSOR カーソル IS
SELECT 出席番号,名前,成績 FROM テーブルA A
WHERE A.出席番号 NOT IN (SELECT B.出席番号 FROM テーブルB B)
ORDER BY 出席番号;
BEGIN
FOR r IN カーソル LOOP
INSERT INTO テーブルB (順番, 名前) VALUES (:WCOUNT,r.名前);
COMMIT;
:WCOUNT := :WCOUNT + 1;
END LOOP;
END;
/
--ここまで

カーソルループの中で、コミットしてるのは、気になったのですが、そのままにしています。
また、スクリプトファイル中での空行は気をつけた方がいいですよ。

この回答への補足

返信ありがとうございます
早速訂正し、SQLplus上にて実行したところ

SP2-0552: バインド変数”WCOUNT”が宣言されていません。

のエラーがでてしまいました
バインド変数を利用するのに何か設定がいるのでしょうか

補足日時:2009/12/30 15:30
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QStatement ignored というエラー

Oracle 9iを使ってsqlファイルを実行させたところ、タイトルにあるように、
PL/SQL: SQL Statement ignored
というエラーメッセージが出力されました。
いろいろ検索してみると、これは、私にシステム権限がないことからおこるとあったのですが、
その設定変更の仕方がいまいちよくわかりませんでした。設定変更のしかたを教えていただけないでしょうか。
また、設定変更したことによって変わるのは私自身のシステム権限だけであって、他にコンピュータ(UNIX)を共有している人たちには影響はありませんよね?
立て続けに質問ばかりすみませんが、よろしくおねがいします。

Aベストアンサー

PL/SQLで権限がないということは、EXECUTE PROCEDUREシステム権限がないということでしょうか・・・。
前後のエラーも記載していただいた方が良いとは思いますが。

システム権限の付与方法は下記で行うことが可能です。
※ここでいう"ユーザ"はOracleユーザのことでスキーマとイコールです。
1.SYSTEMまたはSYS(DBA権限を持ったユーザ)でログイン
2.grant execute procedure to [対象ユーザ];
  または
  grant resource to [対象ユーザ];

以上で一応権限付与はできますが、どのような処理を行いたいかによって、これだけで解決するかどうかわかりません。
また、他の人への影響ですが、ユーザをどのように使用しているか、どのようなポリシーのシステムかによって異なります。(「私自身」というのが、セッションのことかスキーマのことかわかりませんでした。)
同じユーザを他の人と共通で使っていれば、もちろん他の人へ影響が出ますし、一人1ユーザ(スキーマ)で割当てられていれば、影響なく使えます。
「影響が出る」という意味は、セキュリティレベルが権限付与された分落ちるということで、機能的に使用できなくなることはありません。

なお、セッション単位で権限を割当てる方法はないと思っています。
付与した権限をセッション終了次第revokeすれば、元に戻るのではないでしょうか。

PL/SQLで権限がないということは、EXECUTE PROCEDUREシステム権限がないということでしょうか・・・。
前後のエラーも記載していただいた方が良いとは思いますが。

システム権限の付与方法は下記で行うことが可能です。
※ここでいう"ユーザ"はOracleユーザのことでスキーマとイコールです。
1.SYSTEMまたはSYS(DBA権限を持ったユーザ)でログイン
2.grant execute procedure to [対象ユーザ];
  または
  grant resource to [対象ユーザ];

以上で一応権限付与はできますが、どのような処理を...続きを読む

QPL/SQLのコンパイルエラーについて(ignored)

以下はPL/SQLの一部です。

if (vn_CNT > 0 ) then
-- 座席マスタ更新実行
行27update M_SEAT
行28 set M_SEAT.CD_PC = :new.NK_PC ,
行29 M_SEAT.CD_TANTO = :new.CD_TANTO,
行30 where M_SEAT.NO_PORT = :new.NO_PORT ;
end if ;


実行すると以下のエラーがでます。。
行番号 = 27 列番号 = 3 エラー・テキスト = PL/SQL: SQL Statement ignored
行番号 = 30 列番号 = 5 エラー・テキスト = PL/SQL: ORA-01747: user.table.column、table.columnまたは列指定が無効です

ちなみにOEMコンソールで作成しています。
M_SEATというテーブルは存在します。

権限どうのと言われているのはわかるのですが結局なにが原因なのかわかりません。
どなたか教えてください。

以下はPL/SQLの一部です。

if (vn_CNT > 0 ) then
-- 座席マスタ更新実行
行27update M_SEAT
行28 set M_SEAT.CD_PC = :new.NK_PC ,
行29 M_SEAT.CD_TANTO = :new.CD_TANTO,
行30 where M_SEAT.NO_PORT = :new.NO_PORT ;
end if ;


実行すると以下のエラーがでます。。
行番号 = 27 列番号 = 3 エラー・テキスト = PL/SQL: SQL Statement ignored
行番号 = 30 列番号 = 5 エラー・テキスト = PL/SQL: ORA-01747: user.table.column、table.columnまたは列指定が無効です...続きを読む

Aベストアンサー

if (vn_CNT > 0 ) then
-- 座席マスタ更新実行
行27 update M_SEAT
行28 set M_SEAT.CD_PC = :new.NK_PC ,
行29 M_SEAT.CD_TANTO = :new.CD_TANTO
行30 where M_SEAT.NO_PORT = :new.NO_PORT ;
end if ;

これでどうでしょうか?

NK_PCというカラムはありますか?

Qバインド変数について

PL/SQLのバインド変数について調べていますが理解できず困っています。

[理解内容]
1.利点
 :SQL文の検索にバインド変数を利用すると、同一のSQLとして実行できる
  ⇒ 繰り返し処理(ループ)では有効

2.使用方法
 :静的SQL・動的SQLで使用可能 

 [疑問点]
  静的SQLではバインド変数をどう宣言すればよいですか?
  [SQL*Plus]・[動的SQL]は例文がありました

  ●SQL*Plusでの宣言方法

   (例)
    SQL> set null '<null>'
    SQL> set head off
    SQL> variable var_at_sqlplus number

  ●動的SQLの記述方法

   (例)
    declare
     v_sql varchar2(256);
     v_id varchar2(3);

    begin
     v_sql = 'select id into :v_id from test';
     execute immediate v_sql into v_id;
    end;

  ●静的SQL ・・・【 エラーになる 】

    declare
     variable v_id varchar2(3);

    begin
     select id into :v_id from test'
    end;


どんな事でもかまいませんので回答よろしくお願いします

PL/SQLのバインド変数について調べていますが理解できず困っています。

[理解内容]
1.利点
 :SQL文の検索にバインド変数を利用すると、同一のSQLとして実行できる
  ⇒ 繰り返し処理(ループ)では有効

2.使用方法
 :静的SQL・動的SQLで使用可能 

 [疑問点]
  静的SQLではバインド変数をどう宣言すればよいですか?
  [SQL*Plus]・[動的SQL]は例文がありました

  ●SQL*Plusでの宣言方法

   (例)
    SQL> set null '<null>'
    SQL> set head off
    SQL> variable var_at...続きを読む

Aベストアンサー

#1 です。

>という事はPL/SQL内の静的SQLではバインド変数は使えないと言うことでしょうか?

ストアドプログラム(パッケージ/プロシージャ/ファンクション)内では動的以外には使えないと思います。
(SQL*PlusからストアドをEXECUTEする時の引数として使用する事は、もちろん可能ですが)

但し、私が例に書いた通り、無名PL/SQLブロック(DECLARE~BEGIN~END)内では静的にも使用可能です。

質問者様の試したサンプルで言えば。

CREATE OR REPLACE PROCEDURE TEST.TEST(v_Id IN VARCHAR2) IS

v_name varchar2(20);

BEGIN
SELECT name
INTO v_name
FROM test
WHERE id = v_Id;

EXCEPTION
WHEN OTHERS THEN
RETURN;
END;
/

これでコンパイルは通りますよね。(すいません、環境が無いので未検証です)

「これじゃ、v_Idはバインド変数にならないんじゃ?」と思うかもしれませんが、これバインド変数なんです。
(うーん、混乱しちゃいますかね?)

SQLトレースを取るとわかるんですが、引数v_Idが '1' だろうが '2' だろうがトレースで解析されるSQLでは

WHERE id = :b1

と言うバインド変数になるんですよ。

>このあたりが理解できていない部分です。

パフォーマンスチューニングで扱われるバインド変数と置換変数(リテラル)の差異を把握する事が、実はこの辺の理屈を理解する上での近道かもしれません。
OTNでパフォーマンス・チューニング・ガイドを落とすか、もしくはパフォチュー系の本を一冊読んでみるとよいかと思います。

もしJavaの経験がおありでしたら、"?"(プレースホルダ)を使ったSQLと、リテラル直指定の同じSQLをそれぞれ実行するJDBCプログラムを作って、SQLトレース(とtkprof)を取って較べてみると見えてくる物があると思います。
私自身、SQLトレースの中身を見るようになって、この辺の事が理解できるようになりましたから。
(SQLトレースに関しては前述のチューニング・ガイド等参照)

#1 です。

>という事はPL/SQL内の静的SQLではバインド変数は使えないと言うことでしょうか?

ストアドプログラム(パッケージ/プロシージャ/ファンクション)内では動的以外には使えないと思います。
(SQL*PlusからストアドをEXECUTEする時の引数として使用する事は、もちろん可能ですが)

但し、私が例に書いた通り、無名PL/SQLブロック(DECLARE~BEGIN~END)内では静的にも使用可能です。

質問者様の試したサンプルで言えば。

CREATE OR REPLACE PROCEDURE TEST.TEST(v_Id IN VARCHAR2) IS

v_name var...続きを読む

QPL/SQL PLS-00103エラーについて

PL/SQL PLS-00103エラーについて

夜分遅くに申し訳ございません。
PL/SQLのコーディングを実施し、コンパイル中にPLS-00103エラーが発生してしまったのですが、
対処方法がわからず困ってしまいました。

・メッセージ内容:”PLS-00103: 記号"="が見つかりました。”


上記メッセージで指定されていたソース内容(イメージ)↓
--------------------------------------------------------------


BEGIN
LV_STEP := '**登録処理開始'  -- 左記の:=の=部分がエラーメッセージで指定されていました。(LV_STEPはログ出力用の変数)

CURSOR AAAA IS
SELECT GG.EPLY_NO GG_EPLY_NO
,GG.R_CD GG_R_CD
,GG.S_CARD GG_S_CARD

    ・
   ・
FROM GRA_GRA_TR GG



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

といった感じなのですが、
このPLS-00103エラーの対処方法をどなたかご教示いただけませんでしょうか。
よろしくお願いいたします。

PL/SQL PLS-00103エラーについて

夜分遅くに申し訳ございません。
PL/SQLのコーディングを実施し、コンパイル中にPLS-00103エラーが発生してしまったのですが、
対処方法がわからず困ってしまいました。

・メッセージ内容:”PLS-00103: 記号"="が見つかりました。”


上記メッセージで指定されていたソース内容(イメージ)↓
--------------------------------------------------------------


BEGIN
LV_STEP := '**登録処理開始'  -- 左記の:=の=部分がエラーメッセージで指定されていま...続きを読む

Aベストアンサー

PLS-00103は構文解析エラーです。
指定されている行にはセミコロンがありませんが、
これが原因だとすると、
エラーメッセージは後ろに続く文で出るはずです。
エラーメッセージで示された箇所より前の部分(行)を調べてください。

# ソースの内容をイメージで示されても困ります。
# 回答者に超能力者は(おそらく)いないと思いますので
# 勘で答えるよりほか仕方がありません。

Qsqlplusで表示が変なので、出力を整形したい。

いつもお世話になっています。

サーバにアクセスしてsqlplusで、
データを調べたいのですが、
出力形式が見づらくて困っています。

よくわからいのですが、
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------
1の値 2の値
3の値
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------

上記のように意味不明な形式で出てきます。

例えばこんな風に

select カラム1,カラム2,カラム3 from hoge;

カラム1 1の値
---------------------------
カラム2 2の値
---------------------------
カラム3 3の値

等のように分かりやすく表示できないでしょうか?

ちなみにOracle9iR2を使用しています。
sqlに関するツールは使用できないルールでして、あくまでsqlplusのコマンド上でみやすくしなければなりません。

分かりづらくですいませんが、皆さま、ご教授お願いします。

いつもお世話になっています。

サーバにアクセスしてsqlplusで、
データを調べたいのですが、
出力形式が見づらくて困っています。

よくわからいのですが、
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
---------------------------
1の値 2の値
3の値
---------------------------
カラム名1
---------------------------
カラム名2
---------------------------
カラム名3
-----------------------...続きを読む

Aベストアンサー

SQLPLUSを起動して、

SQL>set linesize 列数

でどうだ。

SQL>show linesize

で確認ができる。

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

Qデータベース内のテーブル名の取得

お世話になります。
初心者的な質問でしたらすいません。
SQL文にてデータベース内のテーブル名を
調べることができると聞いたことがあるのですが、
可能でしょうか。

もし、可能であれば、SQLの記述を教えてください。
お願いします。

Aベストアンサー

select * from tab;

私の場合、テーブル名だけ手っ取り早く知りたいとき、↑を打ちます。その他の情報も知りたいときは#2さんの仰るとおり、user_tablesで取得します。

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

Q日付型カラムへのデータINSERT

お世話になります。ひとつご教授ください。

オラクル10g, ojdbc14でjdk1.4.2から接続です。

INSERT命令を使ってテーブルにレコードを追加する際に、DATE型のカラムに対して

INSERT TABLE_A (DATE1, ...) VALUES ('2006-4-27 12:00:00', ...);

を実行するとエラーORA-01861が出ます。そこで

INSERT TABLE_A (DATE1, ...) VALUES ('2006-4-27', ...);

このように記述して再度実行すると通ります。

このようなとき、時間の部分まで設定した値をカラムに格納したいときはどうしたらよろしいでしょうか?

よろしくお願いします。

Aベストアンサー

ごめんなさい。
説明と文例が違ってしまいました。
正しくはこちらです。

INSERT TABLE_A (DATE1, ...) VALUES (to_date('2006-4-27 12:00:00','yyyy/mm/dd hh24:mi:ss'), ...);
というように、to_date関数を使うのが一般的かと思います。

Qbatファイルからsql文実行

クライアントOS:WIN2000
Oracle:9i(サーバ(UNIX)上にあります)

現在、クライアントからbatを起動し、SQL文を投げ、結果を取得したいと思っております。
(SQL文は単純にTBLをカウントしているだけです)

・batの中身
sqlplus %UID%/%PASS%@%SID% @test.sql > output

結果は取得出来るのですが、余分な情報も結果に出力されてしまいます。結果のみを出力させるにはどうすればよろしいでしょうか?

・余分な情報
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
に接続されました。

Aベストアンサー

sqlplus に -S オプションを追加してみればどうでしょうか。

参考URL:http://biz.rivus.jp/sqlplus_overview.html


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング