0

ヘイホー、

選択ステートメントからテーブルに結果セットを挿入するプロシージャを作成する必要があります。私の同僚は、あるテーブルから別のテーブルに値をコピーするために、以前に似たようなことをしました。彼の声明は次のようになります。

CREATE OR REPLACE PROCEDURE Co-Worker(
    pId IN INT
)
AS
BEGIN
    INSERT INTO Table1_PROCESSED
    SELECT * FROM Table1
    WHERE ID = pId;

    DELETE FROM Table1
    WHERE ID = pId;

END Co-Worker;
/

ここで言及した 2 つのテーブルは同じ構造になっています (実際、table1_processed はテーブル 1 の単なるコピーです)。だから私は、「ちょっと、私も select-statement から結果セットを取得します!だから、少し調整しないで同じようにするのはなぜですか!」と考えました。そこで、次のようにテーブルを作成しました。

MyTable:
TIMEID (number) | NAME (varchar2 - 128)
-----------------------------------
VALUE       | VALUE
VALUE       | VALUE
VALUE       | VALUE

そして私の手順は次のようになります:

CREATE OR REPLACE procedure MyProcedure(
pdate in date,
pJobtype in number  default 3,
pTasktype in number default 4,
pJobstatus in number default 1,
pTaskstatus in number default 4
)
AS
    pformateddate date;
BEGIN
    Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
    into pformateddate 
    from dual;
Insert into MyTable (TIMEID, NAME)
Select Function_GETTIMEID(to_date(st, 'DD.MM.YYYY HH24')) TIMEID
       ,to_char(ext) NAME 
from(
    Select to_char(arch_job.exec_start, 'DD.MM.YYYY HH24') st
           ,file.name ext
           , count(file.id) cnt
    from 
         arch_task_file 
             left join file on arch_task_file.File_ID = file.ID
             left join arch_task on arch_task_file.Task_ID = arch_task.ID
             left join arch_job on arch_task.Job_ID = arch_job.ID
    where 
        arch_job.exec_start > pformateddate 
        and arch_job.exec_end <pformateddate + 1 
        and arch_job.jobtype_id = pJobtype 
        and arch_job.jobstatus_id = pJobstatus 
        and arch_task.Tasktype_ID = pTasktype 
        and arch_task.Taskstatus_ID = pTaskstatus
     group by 
         file.name,
           to_char(arch_job.exec_start, 'DD.MM.YYYY HH24'
       )
    );
End MyProcedure;
/

大きな Select-Statement ALONE の結果は次のようになります。

TIMEID      | NAME
-----------------------------------
VALUE       | VALUE
VALUE       | VALUE
VALUE       | VALUE

しかし、この手順を実行してダミーの日付 (sysdate - 12 または '16.07.2010 10:32:50' のような日付) を指定すると、Toad から「手順が完了しました」というメッセージが表示され、テーブルが空のままになります...! しかし、前に述べたように、大きな Select-Statement によって結果が得られるため、空の結果セットを挿入しようとするべきではありません...! 私の手順が機能しない理由を誰か教えてもらえますか?

すべての有用な回答に感謝します。=)

グリーツ!

追伸:

Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
into pformateddate 
from dual;

pDate-value を短くするには が必要です! 私はそれをテストしたので、それも機能し、ロジック全体で無視できます。状況の全体像をお伝えするのはここだけです!

4

3 に答える 3

3

これは、SQL フォーラムで非常に一般的なパターンです。パターンはOPが言う

「この SQL を TOAD ワークシート (またはその他のもの) で実行すると機能します。しかし、ストアド プロシージャなどの別のコンテキストに含めると、機能しません。何が得られますか?」

つまり、2 つのステートメントは同じではありません。ところどころ書き間違いがあります。結合が省略されたか、余分な結合が追加された可能性があります。最も可能性の高いエラーの原因は、ワークシートのリテラルをストアド プロシージャのパラメーターに置き換えることです。

もちろん、違いがどこにあるのかはわかりません。私にできることは、2 つの SQL ステートメントを詳しく調べて、不一致を見つけていただくことだけです。

本当に違いが見つからない場合は、コードをデバッグする必要があります。開始する最も簡単な方法は、Devil's Debugger を使用することです。insert ステートメントの後に次の行を追加します。

dbms_output.put_line('Rows inserted = '||to_char(sql%rowcount));

TOAD で DBMS_OUTPUT を有効にする必要があります。どこかにタブがあります。これにより、少なくとも、クエリが実際にゼロ行を返しているのか、それともプロシージャが行を挿入していて、何らかの理由で行が表示されていないのかがわかります。これらは 2 つの異なる問題です。

于 2010-07-28T10:14:46.100 に答える
0

テーブルブラウザなどの他のセッションでテーブル内のデータを表示する前に、この手順を実行したToadセッションでCOMMITする必要があります。あなたはそれをすることを覚えていましたか?

于 2010-07-28T09:06:54.280 に答える
0

あなたの問題にはあまり関係ありませんが、これは

Select to_date(to_char(to_date(pdate, 'DD.MM.YYYY HH24:MI:SS'), 'DD.MM.YYYY'), 'DD.MM.YYYY') 
into pformateddate 
from dual;

渡されたパラメーターから時間要素を削除するための長い方法です。これは同じことをします:

Select trunc(pdate) 
into pformateddate 
from dual; 

または実際、Tony が指摘するように、単純な課題は次のとおりです。

pformateddate := trunc(pdate);
于 2010-07-28T09:37:50.477 に答える