Using Oracle-Supplied Packages
DBMS_OUTPUT
PUT_LINE writes into the session output buffer. SQL*Plus displays it only after SET SERVEROUTPUT ON, and the buffer is flushed at the end of the block. The default buffer is 20000 bytes; exceeding it raises ORU-10027 (buffer overflow) wrapped in ORA-20000 - call DBMS_OUTPUT.ENABLE(size) when producing large volumes.
UTL_FILE
Writes and reads server-side operating system files. You must use an Oracle directory object name, not a filesystem path, and the user needs READ/WRITE on it plus EXECUTE on UTL_FILE. The pattern is FOPEN(dir, file, mode) โ PUT_LINE / GET_LINE โ FCLOSE; forgetting FCLOSE leaves the handle open until the session ends.
Dynamic SQL
Native dynamic SQL: EXECUTE IMMEDIATE sql_string [INTO ...] [USING ...] [RETURNING INTO ...] for DDL and single-row statements, and OPEN cur FOR sql_string USING ... for multi-row queries. Use DBMS_SQL when the statement shape is unknown until run time (unknown column lists, DESCRIBE_COLUMNS). Bind variables substitute values only - never table or column names; validate identifiers with DBMS_ASSERT.
Other common packages
DBMS_UTILITY (FORMAT_ERROR_STACK, COMMA_TO_TABLE), DBMS_SCHEDULER (jobs), DBMS_STATS (statistics), DBMS_RANDOM, DBMS_LOB.
Rule of thumb: every value that comes from outside must go through USING, and every identifier you concatenate must be checked with DBMS_ASSERT.