0

最初の実際の PL/SQL ストアド プロシージャが完成しました。このストアド プロシージャは期待どおりに動作します。私は PL/SQL を初めて使用します。コードの間違いや不適切な点を指摘していただけますか?

このコードは、命名規則を想定しています。たとえば、「t_company」テーブルは「companyId」を主キーとして使用し、そのタイプは数値です。

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

create or replace
package body test_erp AS    
    procedure init_data is        
    begin         
       logMessage('procedure init_data');
       SAVEPOINT do_insert; 
       insert into t_company(companyId, companyName) values(gen_key('t_company'), 'IBM');
       COMMIT;
    exception
       WHEN OTHERS THEN  
            rollback to do_insert;  
            logMessage('roll back , due to '|| SQLERRM);
    end init_data;        
end test_erp;

この関数を呼び出します

create or replace
function gen_key(tblName varchar2)
return number is
    l_key number := 1000;

    l_tmpStr varchar(2000); -- not good, how to fix it  ?
begin
    l_tmpStr := substr(tblName, 3, length(tblName));   
    EXECUTE IMMEDIATE ' SELECT CASE WHEN MAX('||l_tmpStr||'Id) IS NULL THEN 1000 ELSE MAX('||l_tmpStr||'Id)+1 END FROM '|| tblName into l_key; 

     logmessage('gen primary key '|| tblName ||' '||l_key);
    return l_key;
end;
4

2 に答える 2

3

あなたのケースで関数を使用するgen_keyは非常に遅く、データベースで書かれたものは正しくなく、非常に非効率的です。

したがって、私のアドバイスは、これにSEQUENCE一般的に使用されるを作成することです。次に、それぞれTRIGGERに新しいものを生成するために作成するか、直接追加する必要があります。PKINSERTNEXTVAL

したがって、SEQUENCE缶は次のようになります。

CREATE SEQUENCE YOUR_COMP_SEQ
  MINVALUE 1
  MAXVALUE 999999
  START WITH 1
  INCREMENT BY 1
  NOCACHE
;

次に、意味のある使用をお勧めしますTRIGGER

CREATE OR REPLACE TRIGGER AUTOSET_ID_COMP
BEFORE INSERT ON t_company
FOR EACH ROW
BEGIN
   SELECT YOUR_COMP_SEQ.NEXTVAL INTO :NEW.companyId FROM DUAL;
END;

そして最後にクエリを呼び出すだけです:

INSERT INTO t_company(companyName) VALUES('SomeValue');

TRIGGER を作成したくない場合は、次のように直接作成できます。

INSERT INTO t_company(companyId, companyName)
VALUES(YOUR_COMP_SEQ.NEXTVAL, 'SomeValue');


注:もちろん、TABLE独自のfor every を作成してから、 for eachSEQUENCEを使用できます。 注2:シーケンスは非常に優れていますが、たとえば、テーブルに20行を追加した場合、1、2、3、...などの問題があり、たとえば15行を削除します。この15行以降、もう使わないで。TRIGGERSTABLE
IDsID

アップデート:

@Benと少し話し合った後、回答と解決策が更新されました。ありがとうございます。

于 2012-07-01T17:46:59.860 に答える
3

あなたのkey_gen手順はかなり問題があります。を実行してキーを生成するのMAX(key)+1は遅く、マルチユーザー環境では機能しません。2 人のユーザーがいると仮定すると、両方のユーザーが同じものを見てMAX(key)、同じ主キーを持つ行を挿入しようとするのは比較的簡単です。

Oracle では、マルチユーザー環境で主キーを効率的に生成するためにシーケンスを提供しています。シーケンスを使用してキーを生成する方がはるかに優れています。従来、テーブルごとに 1 つのシーケンスを作成します。つまり、

CREATE SEQUENCE company_seq;

あなたのINSERTステートメントは次のようになります

insert into t_company(companyId, companyName) values(company_seq.nextval, 'IBM');

または、テーブルにトリガーを作成して、主キーを自動的に入力することもできます。

さらに、ログに記録するために例外をキャッチすることは問題ありませんが、呼び出し元がINSERT失敗したことを認識できるように、その例外を再生成する必要があります。

于 2012-07-01T17:34:33.980 に答える