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

PL/SQLプロシージャで動的表名のカーソルを開く

    これは、単一のselect-as-selectステートメントとして実行しますが、table_nameを渡すという事実だけが複雑になるため、動的SQLを使用する必要があります。

    私はそれを次のようにします:

    CREATE OR REPLACE PROCEDURE some_name(p_table_name IN VARCHAR2,
                                          p_chunk_size IN NUMBER,
                                          p_row_limit  IN NUMBER) AS
    
      v_table_name VARCHAR2(32); -- 30 characters for the tablename, 2 for doublequotes in case of case sensitive names, e.g. "table_name"
    
      v_insert_sql CLOB;
    BEGIN
      -- Sanitise the passed in table_name, to ensure it meets the rules for being an identifier name. This is to avoid SQL injection in the dynamic SQL
      -- statement we'll be using later.
      v_table_name := DBMS_ASSERT.ENQUOTE_LITERAL(p_table_name);
    
      v_insert_sql := 'insert into chunks (common_column_name, chunk_number)'||CHR(10)|| -- replace the column names with the actual names of your chunks table columns.
                      'select common_column,'||CHR(10)||
                      '       ora_hash(substr(common_column, 1, 15), :p_chunk_size) AS chunk_number'||CHR(10)||
                      'from   '||v_table_name||CHR(10)||
                      'where  rownum <= :p_row_limit';
    
      -- Used for debug purposes, so you can see the definition of the statement that's going to be run.
      -- Remove before putting the code in production / convert to proper logging code:
      dbms_output.put_line(v_insert_sql);
    
      -- Now run the statement:
      EXECUTE IMMEDIATE v_insert_sql USING p_chunk_size, p_row_limit;
    
      -- I've included the p_row_limit in the above statement, since I'm not sure if your original code loops through all the rows once it processes the
      -- first p_row_limit rows. If you need to insert all rows from the p_table_name into the chunks table, remove the predicate from the insert sql and the extra bind variable passed into the execute immediate.
    END some_name;
    /
    

    単一のinsert-as-selectステートメントを使用することにより、作業を行うための最も効率的な方法を使用しています。 (使用していた)一括収集を実行すると、メモリが使い果たされ(配列にデータが格納され)、PL/SQLエンジンとSQLエンジンの間で余分なコンテキストスイッチが発生します。これはselect-as-selectステートメントでは回避されます。




    1. 一定時間後に行を自動的に更新します

    2. 1899-12-30が12/31ではなくAccess/SQL Serverのゼロ日付であるのはなぜですか?

    3. SQLサーバーでID列の値が突然1001にジャンプします

    4. レプリケーションが不可能な2つの異なる独立したネットワーク間で、同じ名前とデータベース名を持つ特定のテーブルを同期するにはどうすればよいですか?