プロが教える店舗&オフィスのセキュリティ対策術

タイトルの通りで、もう50回くらい翔泳社の
「やさしいPL/SQL入門」を読んでいるのですが、
最初の変数の段階でもう頭が付いていけません(大涙
だからもう、みなさんにすがることにしました。
基本のキを優しく教えて下さい。

もちろん実際は違いますが単純化します。

表名はTBL_1

品名(CHAR),数量(NUMBER),販売日(DATE)
COKE,100,07-04-01
COKE,250,07-04-01
PEPSI,150,07-04-01
PEPSI,300,07-04-02
・・・
・・・
(旨く表示できないのでカンマで区切りました)
品名毎の日別販売量を把握するには

SELECT 販売日,品名,SUM(数量)
FROM TBL_1
WHERE 販売日 = 07-04-**
GROUP BY 販売日,品名;

で良いと思うのですが(違ったりして・・・)、やりたいことは、
1.SYSDATEにて日付を取得し、その前日(つまりは昨日)の分だけを毎日取りたい。
2.且つ実行結果をSPOOLでテキストに吐き出したい。
の2つです。
これをPL/SQLで実現するにはどうしたらいいのでしょう?
ダイレクトなお答えをいただけるとうれしいです。
いただいた回答を基に、もう一度本を読み直してみます。

SYSDATEを、宣言した変数に格納し、その変数をSELECT文にあてはめる
(上記例の07-04-**の部分)、という考えから抜け出せないのです。
何故にカーソルという物が必要なのかが理解できないのです。
きっとエクセルVBAしか知らないからなのです。

A 回答 (3件)

>宣言部で記述されるSELECT文で返される1行、あるいは複数行の、


>行そのものが変数という扱いなのだろうか。
行はクラス、列はメンバ変数と考えたほうがわかり易いと思います

>実行部はそれを一行ずつ取り出して加工しているのだろうか。
FETCHで1行ずつ取り出します(参考URL参照、類似の質疑応答:http://okwave.jp/qa2929010.html

>仮にそうだとしたら、WHERE句の値を様々に変えたい時はどうしたらい>いのだろうか。
動的SQLで解決します(参考URL参照)

>最終的な結果をどうやってテキストに吐き出すのだろうか。
set serveroutput on;
をまずPS/SQLの1行目に記述しておいて
dbms_output.put_line で画面に出力させて、これをSPOOLしてもいいし、(参考URL参照)

utl_file.fopen
utl_file.put_line
utl_file.fclose
を使用して、直接ファイル出力してもいいと思います(参考URL参照)

以下サンプルソース(テスト環境無いので未実行です)
SQL> set serveroutput on
SQL> spool /testdata.csv
SQL> declare
begin
for cu_rec in (※1) loop
dbms_output.put_line (cu_rec.csvrow);
end loop;
end;
/
spool off

<※1の部分>
SELECT 販売日|| ',' || 品名 || ',' || SUM(数量) csvrow ←CSV形式のカンマ区切り編集です
FROM TBL_1
WHERE 販売日 = TO_CHAR(SYSDATE-1,'YY-MM-DD')
GROUP BY 販売日,品名

参考URL:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
最初から疑問点も書けば良かったですね。
どうも「やさしいPL/SQL入門」すら自分には難解だったようです。
参考URLも99%わかりません(涙
でもちょっとだけもやが晴れたので、もう少しがんばります。

お礼日時:2007/04/25 07:28

>「やさしいPL/SQL入門」を読んでいるのですが、


>最初の変数の段階でもう頭が付いていけません

どういう風についていけないのですか?
エクセルVBAが出来るのであれば変数の用語の意味が分からないわけではないですよね?

>ダイレクトなお答えをいただけるとうれしいです。
これは処理のソースそのものを期待されていますか?

何かPL/SQLで実装しないといけない理由があると仮定して、
カーソルとはVBAでのレコードセットのようなものです。(あくまでイメージですが)
VBA+OracleでもSELECTの結果がレコードセットオブジェクトに格納されてそれをループ処理したりしますよね?
それと考え方は同じです。

あとSQL文が間違っていますよ。

SELECT 販売日,品名,SUM(数量)
FROM TBL_1
WHERE 販売日 = TO_CHAR(SYSDATE-1,'YY-MM-DD')
GROUP BY 販売日,品名;

ではないでしょうか。

ただこのままではPL/SQL内ではSQLの結果がどこにも保存されません。VBAでのレコードセットがない状態です。
これを処理内で利用するためにカーソルとして実装しループさせるのです。
※selectしただけではsqlplusでの実行のように標準出力には出ません。
カーソル内でループしながら標準出力に出したりファイルに書き出したりします。

本を見ながらサンプルを書いたりしていますか?

?ばかりの回答になっていますが、きちんと書籍を読んで1つずつ実行していけば動きと命令の意味は分かると思いますよ。
基本的な言語の仕様の難易度はVBAとそれほど変わらないと思います。

この回答への補足

もう少し頭のもやもやを書きます。

宣言部で記述されるSELECT文で返される1行、あるいは複数行の、
行そのものが変数という扱いなのだろうか。

一時表なりビュー表なりを作るイメージだろうか。
実行部はそれを一行ずつ取り出して加工しているのだろうか。

仮にそうだとしたら、WHERE句の値を様々に変えたい時はどうしたらいいのだろうか。

(質問にも書きましたが)最終的な結果をどうやってテキストに吐き出すのだろうか。

まずはそんなようなところです。
ところでご回答の中にある、
>VBA+OracleでもSELECTの結果がレコードセットオブジェクトに格納されて・・
そんな技があることすら知らない(涙
エクセルからオラクルDBに接続して・・ってやつでしょうか。
アクセスからでもろくに接続できないです。
そこらへんのODBCの関係も、いくら読んでも理解できない馬鹿頭。

補足日時:2007/04/24 07:39
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
書きました「ダイレクトな答え」はおっしゃるとおりソースそのものです。
外国小説苦手なんで、scottさんのsalがemp表では・・・って例だと、
ものすごくイメージしづらい(故に馬鹿頭)。
自分の使っている表で、単純な例に対してのソースならイメージできるかなと思った次第です。
SQL文に関しては基本文を示しただけですのでご容赦いただきたく。

お礼日時:2007/04/24 07:39

システム日付の前日であれば


SELECT 販売日,品名,SUM(数量)
FROM TBL_1
WHERE 販売日 = (SYSDATE -1)
GROUP BY 販売日,品名;
で代入しなくてもOKだとおもいます。
ちなみに、販売日に時間・分・秒まで入っているなら
SELECT 販売日,品名,SUM(数量)
FROM TBL_1
WHERE trunc(販売日) = trunc(SYSDATE -1)
GROUP BY 販売日,品名;
で、販売日の列の値を丸める必要があります。

PL/SQLでなくても良いのでは?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
質問にも書きましたとおり、思い切り単純化したモデルですので、
やりたいことの部分も本当はもう少し複雑です。
単純な例題に対する解から、何かしらこの馬鹿頭にひらめく物があるかも知れないと思い、質問いたしました。
無理矢理PL/SQLにはめ込んでいただけないでしょうか。
引き続きお願いいたします。

お礼日時:2007/04/23 23:21

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

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