declare
  -- INSERT many rows, bulk syntax

  -- dynamic SQL
  -- fails at 9.2.0 with PLS-00457:
  -- expressions have to be of SQL types
  --
  -- NO FLAVOR OF EXECUTE IMMEDIATE IS SUPPORTED WITH A RECORD BIND YET

  --
  v_emprecs Emp_Util.emprec_tab_t  := Emp_Util.Get_Many_Rows;
begin
  forall j in v_emprecs.first..v_emprecs.last
    execute immediate '
      insert into employees_2 values :emprec'

      using v_emprecs(j);
end;
/
-- ERROR at line N:
rollback /* prepare for repeat or for next sample */;
-- Rollback complete.






declare
  -- WORKAROUND
  -- Doesn't use RECORD bind so works pre 9.2.0
  type Employee_Id_Tab_t    is table of employees.employee_id    %type index by binary_integer;

  type First_Name_Tab_t     is table of employees.first_name     %type index by binary_integer;
  type Last_Name_Tab_t      is table of employees.last_name      %type index by binary_integer;
  type Email_Tab_t          is table of employees.email          %type index by binary_integer;
  type Phone_Number_Tab_t   is table of employees.phone_number   %type index by binary_integer;
  type Hire_Date_Tab_t      is table of employees.hire_date      %type index by binary_integer;
  type Job_Id_Tab_t         is table of employees.job_id         %type index by binary_integer;
  type Salary_Tab_t         is table of employees.salary         %type index by binary_integer;
  type Commission_Pct_Tab_t is table of employees.commission_pct %type index by binary_integer;
  type Manager_Id_Tab_t     is table of employees.manager_id     %type index by binary_integer;

  type Department_Id_Tab_t  is table of employees.department_id  %type index by binary_integer;

  v_employee_ids    Employee_Id_Tab_t;
  v_first_names     First_Name_Tab_t;
  v_last_names      Last_Name_Tab_t;
  v_emails          Email_Tab_t;
  v_phone_numbers   Phone_Number_Tab_t;
  v_hire_dates      Hire_Date_Tab_t;
  v_job_ids         Job_Id_Tab_t;
  v_salaries        Salary_Tab_t;

  v_commission_pcts Commission_Pct_Tab_t;
  v_manager_ids     Manager_Id_Tab_t;
  v_department_ids  Department_Id_Tab_t;

  v_emprecs Emp_Util.emprec_tab_t  := Emp_Util.Get_Many_Rows;
begin
  for j in v_emprecs.First..v_emprecs.Last
  loop
    v_employee_ids(j)    := v_emprecs(j).employee_id;
    v_first_names(j)     := v_emprecs(j).first_name;
    v_last_names(j)      := v_emprecs(j).last_name;

    v_emails(j)          := v_emprecs(j).email;
    v_phone_numbers(j)   := v_emprecs(j).phone_number;
    v_hire_dates(j)      := v_emprecs(j).hire_date;
    v_job_ids(j)         := v_emprecs(j).job_id;
    v_salaries(j)        := v_emprecs(j).salary;
    v_commission_pcts(j) := v_emprecs(j).commission_pct;
    v_manager_ids(j)     := v_emprecs(j).manager_id;
    v_department_ids(j)  := v_emprecs(j).department_id;
  end loop;

  Emp_Util.Initialize_Count ( 'employees_2' );
  forall j in v_emprecs.First..v_emprecs.Last

    execute immediate '
      insert into employees_2 (
        employee_id,
        first_name,
        last_name,
        email,
        phone_number,
        hire_date,
        job_id,
        salary,
        commission_pct,
        manager_id,
        department_id )

      values (
        :employee_id,
        :first_name,
        :last_name,
        :email,
        :phone_number,
        :hire_date,
        :job_id,
        :salary,
        :commission_pct,
        :manager_id,
        :department_id )'
      using
        v_employee_ids(j),

        v_first_names(j),
        v_last_names(j),
        v_emails(j),
        v_phone_numbers(j),
        v_hire_dates(j),
        v_job_ids(j),
        v_salaries(j),
        v_commission_pcts(j),
        v_manager_ids(j),
        v_department_ids(j);
  Emp_Util.Show_Count_Change;
end;
/
-- PL/SQL procedure successfully completed.
rollback /* prepare for repeat or for next sample */;

-- Rollback complete.