EXECUTE IMMEDIATE and what it can do

It uses a string for further queries. It could be applied for ref cursors and for a simple CRUD scripting with “prepared statement” values.

declare
    quer varchar2(32000);
    res ref cursor;
    date1 integer := 201101;
    date2 integer := 201201;
    returnID integer;
begin

    -- select into refcur
    quer := 'SELECT col1, col2 FROM sometable WHERE datte between :1 and :2';
    OPEN res FOR quer USING date1, date2;
 
    -- insert/delete/update some values
    quer := 'INSERT INTO sometable (col1, col2) VALUES (:1, :2)';
    EXECUTE IMMEDIATE quer USING date1, date2;

    quer := 'DELETE FROM sometable WHERE col1 = :1 OR col2 = :2';
    EXECUTE IMMEDIATE quer USING date1, date2;

    quer := 'UPDATE sometable SET col1 = :1 WHERE datte = :2';
    EXECUTE IMMEDIATE quer USING date1, date2;

    -- returning
    quer := 'INSERT INTO sometable (col1, col2) VALUES (:1, :2) RETURNING col_id INTO :3';
    EXECUTE IMMEDIATE quer USING date1, date2 RETURNING INTO returnID;
 
    quer := 'SELECT count(*) FROM sometable WHERE datte between :1 and :2';
    EXECUTE IMMEDIATE quer INTO returnID USING date1, date2;

end;

In fact, you can create as long script(query string) as you wish (limited by maximum length of VARCHAR2 datatype 32767).

Note: you cannot use names of columns and tables and other similar stuff as an input variable for EXECUTE IMMEDIATE.