make sure u grant the CREATE PROCEDURE PRIVILEGE explicitly as shown.
SQL> connect sys
Enter password: ***
Connected.
SQL> grant create procedure to mag;
Grant succeeded.
SQL> connect mag
Enter password: ***
Connected.
SQL> set serveroutput on
SQL> create or replace procedure dynamic_test is
2 string varchar2(200);
3 begin
4 string := 'create or replace procedure dyn is begin dbms_output.put_line(''asdf''); end;';
5 execute immediate string;
6 end;
7 /
Procedure created.
SQL> exec dynamic_test;
PL/SQL procedure successfully completed.
SQL> exec dyn
asdf
PL/SQL procedure successfully completed.
SQL>