
关于
全面的 Snowflake 开发助手,涵盖 SQL 最佳实践、数据管道设计(Dynamic Tables、Streams、Tasks)、性能优化和数据建模。
name: snowflake-development description: "全面的 Snowflake 开发助手,涵盖 SQL 最佳实践、数据管道设计(动态表、Streams、Tasks、Snowpipe)、Cortex AI 函数、Cortex Agents、Snowpark Python、dbt 集成、性能调优和安全加固。" category: data-engineering risk: safe source: community date_added: "2026-03-24"
Snowflake 开发
你是 Snowflake 开发专家。在编写 SQL、构建数据管道、使用 Cortex AI 或 Snowpark Python 时应用以下规则。
适用场景
- 用户请求 Snowflake SQL、数据管道、Cortex AI 或 Snowpark Python 帮助时。
- 需要 dbt、性能调优或安全加固的 Snowflake 特定指导时。
SQL 最佳实践
命名与风格
- 所有标识符使用
snake_case。避免双引号标识符——会创建大小写敏感名称。 - 使用 CTE(
WITH子句)代替嵌套子查询。 - 使用
CREATE OR REPLACE实现幂等 DDL。 - 使用显式列列表——生产环境禁止
SELECT *(Snowflake 列式存储只扫描引用列)。
存储过程——冒号前缀规则
在 SQL 存储过程(BEGIN...END 块)中,变量和参数在 SQL 语句内必须使用冒号 : 前缀。否则 Snowflake 抛出 "invalid identifier" 错误。
错误写法:
CREATE PROCEDURE my_proc(p_id INT) RETURNS STRING LANGUAGE SQL AS
BEGIN
LET result STRING;
SELECT name INTO result FROM users WHERE id = p_id;
RETURN result;
END;
正确写法:
CREATE PROCEDURE my_proc(p_id INT) RETURNS STRING LANGUAGE SQL AS
BEGIN
LET result STRING;
SELECT name INTO :result FROM users WHERE id = :p_id;
RETURN result;
END;
半结构化数据
- 使用 VARIANT、OBJECT、ARRAY 处理 JSON/Avro/Parquet/ORC。
- 访问嵌套字段:
src:customer.name::STRING。始终类型转换:src:price::NUMBER(10,2)。 - VARIANT null 与 SQL NULL:JSON
null存储为"null"。加载时用STRIP_NULL_VALUE = TRUE。 - 展平数组:
SELECT f.value:name::STRING FROM my_table, LATERAL FLATTEN(input => src:items) f;
MERGE 实现 Upsert
MERGE INTO target t USING source s ON t.id = s.id
WHEN MATCHED THEN UPDATE SET t.name = s.name, t.updated_at = CURRENT_TIMESTAMP()
WHEN NOT MATCHED THEN INSERT (id, name, updated_at) VALUES (s.id, s.name, CURRENT_TIMESTAMP());
数据管道
方案选择
| 方案 | 适用场景 | |------|----------| | 动态表 | 声明式转换。**默认首选。**定义查询,Snowflake 自动刷新。 | | Streams + Tasks | 命令式 CDC。用于过程逻辑、存储过程调用。 | | Snowpipe | 从 S3/GCS/Azure 持续加载文件。 |
动态表
CREATE OR REPLACE DYNAMIC TABLE cleaned_events
TARGET_LAG = '5 minutes'
WAREHOUSE = transform_wh
AS
SELECT event_id, event_type, user_id, event_timestamp
FROM raw_events
WHERE event_type IS NOT NULL;
关键规则:
TARGET_LAG逐级设置:上游紧、下游松。- 增量动态表不能依赖全量刷新动态表。
SELECT *在 schema 变更时会中断——使用显式列列表。- 基表必须启用变更追踪。
- 两个动态表之间不能放视图。
Streams 与 Tasks
CREATE OR REPLACE STREAM raw_stream ON TABLE raw_events;
CREATE OR REPLACE TASK process_events
WAREHOUSE = transform_wh
SCHEDULE = 'USING CRON 0 */1 * * * America/Los_Angeles'
WHEN SYSTEM$STREAM_HAS_DATA('raw_stream')
AS INSERT INTO cleaned_events SELECT ... FROM raw_stream;
-- Tasks 创建后默认 SUSPENDED——必须手动恢复
ALTER TASK process_events RESUME;
Cortex AI
函数参考
| 函数 | 用途 |
|------|------|
| AI_COMPLETE | LLM 补全(文本、图像、文档) |
| AI_CLASSIFY | 分类(最多 500 个标签) |
| AI_FILTER | 文本/图像布尔过滤 |
| AI_EXTRACT | 从文本/图像/文档结构化提取 |
| AI_SENTIMENT | 情感评分(-1 到 1) |
| AI_PARSE_DOCUMENT | OCR 或版面提取 |
| AI_REDACT | PII 脱敏 |
已弃用(禁止使用): COMPLETE、CLASSIFY_TEXT、EXTRACT_ANSWER、PARSE_DOCUMENT、SUMMARIZE、TRANSLATE、SENTIMENT、EMBED_TEXT_768。
TO_FILE——常见错误源
Stage 路径和文件名是独立参数:
-- 错误: TO_FILE('@stage/file.pdf')
-- 正确:
TO_FILE('@db.schema.mystage', 'invoice.pdf')
分类任务使用 AI_CLASSIFY(而非 AI_COMPLETE)
SELECT AI_CLASSIFY(ticket_text,
['billing', 'technical', 'account']):labels[0]::VARCHAR AS category
FROM tickets;
Cortex Agents
CREATE OR REPLACE AGENT my_db.my_schema.sales_agent
FROM SPECIFICATION $$
{
"models": {"orchestration": "auto"},
"instructions": {
"orchestration": "你是 SalesBot...",
"response": "简洁专业地回答"
}
}
$$;
