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

いつもお世話になっております。
次で、PL/SQLで自動的に表tbを作成し、日時を挿入することを試みています。

BEGIN
EXECUTE IMMEDIATE
'CREATE TABLE tb (t TIMESTAMP)';
INSERT INTO tb VALUES(SYSTIMESTAMP);
END;
/

実行すると、tbが作られていない旨のエラーになってしまいます。
INSERT部分がなければ、表tbは作成できます。
表を作成し、データを挿入するにはどのようにすればよろしいでしょうか。
何卒よろしくお願いいたします。

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

A 回答 (3件)

PL/SQLのプログラムは実行する前に解析されます。



実行する前にはtbというテーブルが存在しないのでエラーになります。

# 動的SQLの'CREATE TABLE ...'はただの文字列です。

回避策は、

1. CREATE TABLEとINSERTを別々のプログラムにする。
2. INSERTも動的SQLにする。

# DDL文とDML文を同一のプログラムで使用するときは注意が必要です。
    • good
    • 0
この回答へのお礼

dda167 様
いつもいつも、本当にありがとうございます。
おかげさまで、INSERT部分を動的SQLで実行したら成功しました。
「CREATE TABLE ...」がただの文字列の状態のときに、INSERTが先に解析されてしまうのですね。
よく理解することができました。
いつも感謝しております。
ありがとうございました。

お礼日時:2010/01/24 16:51

PL/SQLは解析⇒実行ですよね。


この解析時にINSERTしたいテーブルがなければエラーになります。
なので、とりあえずエラーとしないのであれば、INSERT文も動的SQLにした方が良いと思います。

BEGIN
EXECUTE IMMEDIATE
'CREATE TABLE tb (t TIMESTAMP)';
EXECUTE IMMEDIATE
'INSERT INTO tb VALUES(SYSDATE)';
END;
/

間違ったINSERT文なら、実行前にエラーにしてくれるという恩恵にあずかれなくなりますが。
    • good
    • 0
この回答へのお礼

saneppie 様
さっそくのご回答、ありがとうございました。
おっしゃる通り「INSERT文も動的SQLに」したら成功しました。
「解析⇒実行」で、解析のときにtbがなかったからエラーになったのですね。
おかげさまでよく理解できました。
ありがとうございました。

お礼日時:2010/01/24 16:53

訂正します(寝ぼけてました)。



> 動的SQLの'CREATE TABLE ...'はただの文字列です。
動的SQLのCREATE TABLE文は実行するときに評価されます。
実行する前は単なる文字列です。

> 1. CREATE TABLEとINSERTを別々のプログラムにする。
1. あらかじめテーブルを作成しておく。
    • good
    • 0

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

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

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

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

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

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

Qテーブルの存在チェックについて

oracle初心者です。
テーブルの存在をチェックする命令はあるのでしょうか?
オンラインマニュアルやSQLポケットリファレンスなどを参考に探したのですが見つかりませんでした。
SELECT count(*) FROM テーブルA・・・などでステータスを判断(ZERO以外は未存在)し存在有無を確認するような方法しかないのでしょうか?
よろしくお願いします。

Aベストアンサー

データディクショナリの USER_TABLES を利用すると良いでしょう。これは表と同様に扱えます。

例えばこのような感じです

select * from user_tables
where table_name = 'TABLE_A';

TABLE_A が(自分のテーブルとして)あれば1件引っかかりますし、なければ結果0件になります。

データディクショナリには他にもいろいろありますので詳しくは参考 URL をご参照ください。

参考URL:http://cyberam.dip.jp/database/oracle/oracle/dd/dd_main.html

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 [対象ユーザ];

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

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.年月 = 任意の値

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

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。

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

で確認ができる。

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というカラムはありますか?

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

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

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;
とすれば良いです。

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

QSELECT INTOで一度に複数の変数へ代入をするにはどのようにすれがよいでしょうか?

初めてこちらで質問させていただきます。
どうぞよろしくお願いします。
早速ですが、
現在ストアドファンクション(PL/pgSQL)にて以下のような形になっています。
変数d1,d2,d3に値をセットするにあたり
テーブルt1を3回スキャンしています。
これを1回のスキャンでセットするような
方法はないのでしょうか?

DECLARE
d1 integer;
d2 integer;
d3 varchar(10);

begin
select min(c1) into d1 from t1;
select min(c2) into d2 from t1;
select min(c3) into d3 from t1;
各種処理
return v;
end;

気持ち的には以下のようなSQLを書きたいのですが、
syntax error となります。
(NG例)
select min(c1) into d1,min(c2) into d2,min(c3) into d3 from t1;

何か良い案がありましたら教えてください。
「それは出来ません」と言う回答でもありがたいです。
※あきらめがつくので。。

それではよろしくお願いします。

初めてこちらで質問させていただきます。
どうぞよろしくお願いします。
早速ですが、
現在ストアドファンクション(PL/pgSQL)にて以下のような形になっています。
変数d1,d2,d3に値をセットするにあたり
テーブルt1を3回スキャンしています。
これを1回のスキャンでセットするような
方法はないのでしょうか?

DECLARE
d1 integer;
d2 integer;
d3 varchar(10);

begin
select min(c1) into d1 from t1;
select min(c2) into d2 from t1;
select min(c3) into ...続きを読む

Aベストアンサー

select min(c1),min(c2),min(c3) into d1,d2,d3 from t1;
でダメ?


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

人気Q&Aランキング