sql >> データベース >  >> RDS >> Oracle

ネストされたテーブルに RowId 値を含める

    ROWID 疑似列です 、テーブルのデータ ディクショナリ ビューの一部ではありません (たとえば、dba_tab_columns には表示されません)。 ) であるため、%rowtype には含まれません。 . PL/SQL レコード (PL/SQL テーブルを作成するもの) には物理ストレージがないため、実際の行 ID または疑似行 ID はありません。

    本当に行 ID をレコード/テーブルに格納したい場合は、型を明示的に宣言する必要があります:

    create or replace package dat_pkg is
    
        type typ_dat_rec is record (
            data_id     data_test.data_id%type,
            data_value  data_test.data_value%type,
            data_rowid  rowid);
    
        type typ_dat_tst is table of data_test%rowtype index by pls_integer;
    
        procedure proc_test (p_dat  typ_dat_tst);
    
    end dat_pkg;
    /
      

    レコード フィールドを rowid だけで呼び出すことはできません これはデータ型なので、接頭辞として data_ を付けました しかし、あなたは何か他のものを好むかもしれません。そして、パッケージ本体でそのフィールド名を使用する必要があります。明らかに:

    create or replace package body dat_pkg is
    
        procedure proc_test (p_dat  typ_dat_tst)
        is
        begin
    
            for i in 1..p_dat.count loop
    
                update  data_test        
                set     data_value  = p_dat(i).data_value  
                where   data_id     = p_dat(i).data_id
                and     rowid       = p_dat(i).data_rowid;
    
            end loop;
    
        end proc_test;
    
    end dat_pkg;
    /
      

    あなたが提案したように、行タイプ全体を保存できます and レコード タイプの 2 つのフィールドとしての行 ID:

    create or replace package dat_pkg is
    
        type typ_dat_rec is record (
            data_rec    data_test%rowtype,
            data_rowid  rowid);
    
        type typ_dat_tst is table of typ_dat_rec index by pls_integer;
    
        procedure proc_test (p_dat  typ_dat_tst);
    
    end dat_pkg;
    /
      

    しかし、それはフィールドを参照するのを少し面倒にします:

    ...
            for i in 1..p_dat.count loop
    
                update  data_test        
                set     data_value  = p_dat(i).data_rec.data_value  
                where   data_id     = p_dat(i).data_rec.data_id
                and     rowid       = p_dat(i).data_rowid;
    
            end loop;
    ...
      

    また、コレクションへのデータの取り込みがさらに厄介になる可能性もあります。いずれにせよ、ループ内でそれらを参照できるようにするには、すべての列/フィールド名を知っている必要があるため、大きな利点があるかどうかはわかりませんが、その方がすっきりしていることがわかるかもしれません.

    もちろん、これを行うには、行の rowid が 時間の経過とともに変化する可能性があります。 forall も調べてみてください。 for を置き換える構文 あなたが実際に何をしているかに応じて、ループします。 (ただし、コレクションが必要かどうかも検討する必要があります。コレクションにデータを入力し、それを更新に使用する場合は、単一の SQL 更新の方がさらに高速になります...)




    1. クエリで人間が読める定数を使用する

    2. SQL-特定のアイテムのみを含む注文を検索し、製品ごとに表示する

    3. Javaのselectクエリにプリペアドステートメントを使用するにはどうすればよいですか?

    4. djangoでのsqliteからpostgresqlへの移行