   FUNCTION query_ref_fk(tab_name VARCHAR2, schema_name VARCHAR2 := USER) RETURN SYS_REFCURSOR;
   FUNCTION gen_delete_ref_by_ids_stmt(tab_name VARCHAR2, fk_column_name VARCHAR2) RETURN VARCHAR2;
   FUNCTION gen_delete_ref_by_ids_call(tab_name VARCHAR2, fk_column_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_m_ref_by_ids_stmt(m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, n_m_tab_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_m_ref_by_ids_call(m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, n_m_tab_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_n_m_ref_by_ids_stmt(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_n_m_ref_by_ids_call(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2) RETURN VARCHAR2;
+  FUNCTION gen_delete_m_ref_by_ids_stmt(m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, fk_table_name STRARRAY, fk_columns STRARRAY) RETURN VARCHAR2;
+  FUNCTION gen_delete_m_ref_by_ids_call(m_tab_name VARCHAR2, fk_table_name STRARRAY, fk_columns STRARRAY) RETURN VARCHAR2;
+  FUNCTION gen_delete_n_m_ref_by_ids_stmt(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, m_ref_column_name VARCHAR2, schema_name VARCHAR2 := USER) RETURN VARCHAR2;
+  FUNCTION gen_delete_n_m_ref_by_ids_call(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, schema_name VARCHAR2 := USER) RETURN VARCHAR2;
   PROCEDURE create_ref_array_delete(tab_name VARCHAR2, schema_name VARCHAR2 := USER, vars OUT VARCHAR2, ref_block OUT VARCHAR2);
   FUNCTION gen_delete_ref_by_id_stmt(tab_name VARCHAR2, fk_column_name VARCHAR2) RETURN VARCHAR2;
   FUNCTION gen_delete_ref_by_id_call(tab_name VARCHAR2, fk_column_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_m_ref_by_id_stmt(m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, n_m_tab_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_m_ref_by_id_call(m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, n_m_tab_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_n_m_ref_by_id_stmt(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2) RETURN VARCHAR2;
-  FUNCTION gen_delete_n_m_ref_by_id_call(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2) RETURN VARCHAR2;
+  FUNCTION gen_delete_m_ref_by_id_stmt(m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, fk_table_name STRARRAY, fk_columns STRARRAY) RETURN VARCHAR2;
+  FUNCTION gen_delete_m_ref_by_id_call(m_tab_name VARCHAR2, fk_table_name STRARRAY, fk_columns STRARRAY) RETURN VARCHAR2;
+  FUNCTION gen_delete_n_m_ref_by_id_stmt(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, m_ref_column_name VARCHAR2, schema_name VARCHAR2 := USER) RETURN VARCHAR2;
+  FUNCTION gen_delete_n_m_ref_by_id_call(n_m_tab_name VARCHAR2, n_fk_column_name VARCHAR2, m_tab_name VARCHAR2, m_fk_column_name VARCHAR2, schema_name VARCHAR2 := USER) RETURN VARCHAR2;
   PROCEDURE create_ref_delete(tab_name VARCHAR2, schema_name VARCHAR2 := USER, vars OUT VARCHAR2, ref_block OUT VARCHAR2);
   FUNCTION query_ref_to_fk(tab_name VARCHAR2, schema_name VARCHAR2 := USER) RETURN SYS_REFCURSOR;
   PROCEDURE create_ref_to_array_delete(tab_name VARCHAR2, schema_name VARCHAR2 := USER, vars OUT VARCHAR2, returning_block OUT VARCHAR2, collect_block OUT VARCHAR2, into_block OUT VARCHAR2, fk_block OUT VARCHAR2);

    parent_table := query_ref_parent_fk(tab_name, schema_name);

    IF parent_table IS NOT NULL THEN
      -- create array delete function for parent table
      citydb_delete_gen.create_delete_function(parent_table, schema_name);
      parent_block := parent_block
        ||chr(10)||'  -- delete '||lower(parent_table)
        ||chr(10)||'  IF deleted_id IS NOT NULL THEN'

    ref_table_name VARCHAR2(30);
    ref_column_name VARCHAR2(30);
    fk_columns VARCHAR2(500);
    cleanup_ref_table VARCHAR2(30);
    ref_to_ref_tables STRARRAY;
    ref_to_ref_columns STRARRAY;
    ref_tables STRARRAY;
    ref_columns STRARRAY;
  BEGIN
    ref_to_cursor := query_ref_to_fk(tab_name, schema_name);

    LOOP
      FETCH ref_to_cursor
      INTO ref_table_name, ref_column_name, fk_columns, cleanup_ref_table;
      EXIT WHEN ref_to_cursor%NOTFOUND;

      IF vars IS NULL THEN
