Verified against the official Snowflake COF-C03 Exam Study Guide — follows guide sections
3.1-3.3. Closest domain to your day job — should be the fastest review, but the exact
options/syntax below are exactly what gets tested (see the official sample question on PURGE).
@~, one per user, not shareable), table stage (@%table,
tied to the table, not shareable, no custom file format), named internal stage (explicit
CREATE STAGE, shareable, most flexible).SNOWFLAKE_SSE or
customer-provided keys) as part of the stage or COPY statement so Snowflake correctly
reads/writes already-encrypted objects.FILE FORMAT objects: CSV/delimited, JSON, Avro, ORC, Parquet, XML — reusable across
multiple stages/COPY statements. Semi-structured formats load into VARIANT naturally.COPY INTO and error handlingCOPY INTO <table> bulk-loads staged files; tracks load history by file name + checksum for
64 days so re-running the same load is idempotent by default (FORCE = TRUE overrides).PURGE = TRUE: deletes staged files automatically after a successful load — the fix when
a stage is accumulating already-loaded files, without affecting ON_ERROR behavior or
causing reloads (this exact scenario is one of the official guide's sample questions).ON_ERROR (CONTINUE, SKIP_FILE, SKIP_FILE_<n>,
ABORT_STATEMENT default), PATTERN (regex filter), VALIDATION_MODE (dry-run).insertFiles). Billed per actual compute-second on
Snowflake-managed compute (not a warehouse you size), micro-batch latency (seconds-minutes).
Uses COPY INTO semantics under the hood, so the same idempotency rules apply.INSERT ... SELECT * FROM my_stream, advances the offset). Cloning behavior: cloning a
schema/table that has a stream with unconsumed records creates a stream that is re-initialized
at the point of cloning — pending change records from the original are not carried over
to the clone (a documented gotcha the official guide tests directly via sample question).
AFTER <task>) execution of a SQL
statement/procedure — paired with a Stream to build incremental ELT: stream captures changes,
task processes them on a schedule.
CREATE TASK ... WHEN SYSTEM$STREAM_HAS_DATA('<stream>') AS ...
runs the task only when the named stream actually has unconsumed change data, instead of
polling on a fixed schedule regardless of whether there's anything to do — lower latency, less
wasted compute, for event-driven ELT.AFTER <task>),
letting a chain of dependent tasks run in the right order, including parallel branches that
later converge.CHANGE_TRACKING metadata that Streams use —
verified hands-on: building a Dynamic Table over a table we didn't own (a shared database)
silently fell back to FULL refresh (recompute everything, every time) with the explicit
reason "Change tracking cannot be enabled for secondaries". Dynamic Tables aren't a separate
mechanism from Streams+Tasks under the hood — they're the same change-tracking foundation,
wrapped in a declarative interface. Requires write access on the source to enable
CHANGE_TRACKING = TRUE; a shared/read-only source can only ever refresh FULL.refresh_mode can be requested as AUTO (Snowflake decides), or forced INCREMENTAL/FULL
— SHOW DYNAMIC TABLES reports both the configured mode and the actual mode with a reason
when they differ.PURGE = TRUE solves the "accumulating staged files" problem
without touching ON_ERROR or reload behavior?