PLSQL
CREATE OR REPLACE PROCEDURE donar_lectura_esquema (
    p_nom_esquema IN VARCHAR2,
    p_nom_usuari  IN VARCHAR2
)
IS
  v_esquema   VARCHAR2(128);
  v_usuari    VARCHAR2(128);
  v_sql       VARCHAR2(4000);
  v_esq_q     VARCHAR2(300);
  v_usr_q     VARCHAR2(300);
BEGIN
  v_esquema := DBMS_ASSERT.SCHEMA_NAME(UPPER(TRIM(p_nom_esquema)));
  v_usuari  := DBMS_ASSERT.SIMPLE_SQL_NAME(UPPER(TRIM(p_nom_usuari)));

  -- Quota identificadors (per noms “especials”)
  v_esq_q := DBMS_ASSERT.ENQUOTE_NAME(v_esquema, FALSE);
  v_usr_q := DBMS_ASSERT.ENQUOTE_NAME(v_usuari,  FALSE);

  DBMS_OUTPUT.PUT_LINE('Esquema: ' || v_esquema || ' | Usuari: ' || v_usuari);

  FOR fila IN (
    SELECT table_name
    FROM all_tables
    WHERE owner = v_esquema
  ) LOOP
    BEGIN
      v_sql:='GRANT SELECT ON ' || v_esq_q || '.' || DBMS_ASSERT.ENQUOTE_NAME(fila.table_name, FALSE) || ' TO ' || v_usr_q;
      DBMS_OUTPUT.PUT_LINE(v_sql);
      EXECUTE IMMEDIATE v_sql;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('ERROR a ' || v_esquema || '.' || fila.table_name || ' -> ' || SQLERRM);
        -- Continua amb la següent taula
    END;
  END LOOP;

  DBMS_OUTPUT.PUT_LINE('Fi.');
END donar_lectura_esquema;
/

S’executa amb:

PLSQL
CALL donar_lectura_esquema('ESQUEMA', 'USUARI');

L’usuari que executa això ha de tenir permisos per donar privilegis a qualsevol taula de qualsevol esquema

PLSQL
GRANT SELECT ON SYS.DBA_TABLES TO USUARI;
GRANT GRANT ANY OBJECT PRIVILEGE TO USUARI;