Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Otwórz kursor dla dynamicznej nazwy tabeli w procedurze PL/SQL

Zrobiłbym to jako pojedynczą instrukcję insert-as-select, skomplikowaną tylko przez fakt, że przekazujesz nazwę tabeli, więc musimy użyć dynamicznego sql.

Zrobiłbym to coś takiego:

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;
/

Używając pojedynczej instrukcji insert-as-select, korzystasz z najbardziej wydajnego sposobu wykonywania pracy. Zbieranie zbiorcze (którego używałeś) zużywałoby pamięć (przechowywanie danych w tablicy) i powodowało dodatkowe przełączanie kontekstu między silnikami PL/SQL i SQL, których unika instrukcja insert-as-select.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Obejście dla sprzężenia zewnętrznego z operatorem IN w Oracle

  2. Oracle PL/SQL — czy wyjątki NO_DATA_FOUND są złe dla wydajności procedury składowanej?

  3. Cloud Native i DevSecOps na dużą skalę dzięki Capgemini Agile Innovation Platform i Oracle Cloud

  4. Jak unieważnić instrukcję SQL w obszarze Oracle SQL, aby podczas zbierania statystyk powstał nowy plan?

  5. Odzyskaj ostatnio wstawioną tożsamość Oracle