存储过程

您可以将复杂的数据库任务和例程压缩为存储过程。与外部过程不同,存储过程在数据库内部存在且可以从数据库内部执行;这使它们可以直接与您的数据库进行通信和交互,以执行维护、执行查询和更新表。

最佳实践

许多其他数据库针对专重于频繁事务的在线事务处理 (OLTP) 进行了优化。相比之下,Vertica 针对在线分析处理 (OLAP) 进行了优化,该处理专注于存储和分析大量数据,并对针对该数据的最复杂查询提供最快的响应。

这种架构差异意味着 Vertica 中存储过程的推荐用例和最佳实践与其他数据库中的存储过程略有不同。

虽然面向 OLTP 的数据库中的存储过程通常用于执行小型事务,但应使用 Vertica 等面向 OLAP 的数据库中的存储过程来增强分析工作负载。Vertica 可以处理孤立的事务,但频繁的小事务可能会影响性能。

一些推荐的 Vertica 存储过程用例包括信息生命周期管理 (ILM) 活动(例如提取、转换和加载 (ETL))以及用于机器学习等任务的数据准备。例如:

  • 根据生命期交换分区

  • 在生命期结束时导出数据并删除分区

  • 保存机器学习模型的输入、输出和元数据 — 运行模型的人员、模型的版本、模型运行次数以及接收结果的人员

Vertica 中的存储过程还可以对需要比调用者更高权限的对象进行操作。可选参数允许过程使用定义者的权限运行,允许调用者以受控方式执行敏感操作。

已知问题和解决方法

  • 您不能使用 PERFORM CREATE FUNCTION 创建 SQL 宏。

    解决方法
    使用 EXECUTE 在存储过程中创建 SQL 宏

    CREATE PROCEDURE procedure_name()
    LANGUAGE PLvSQL AS $$
    BEGIN
        EXECUTE 'macro';
    end;
    $$;
    

    其中 macro 是 SQL 宏的创建语句。例如,此过程创建 argmax 宏:

    => CREATE PROCEDURE make_argmax() LANGUAGE PLvSQL AS $$
    BEGIN
        EXECUTE
            'CREATE FUNCTION
            argmax(x int) RETURN int AS
            BEGIN
                RETURN (CASE WHEN (x IS NOT NULL) THEN x ELSE 0 END);
            END';
    END;
    $$;
    
  • 嵌入式 SQL 语句中的非错误异常不会被报告。

  • DECIMAL、NUMERIC、NUMBER、MONEY 和 UUID 数据类型尚不能用于实参。

  • 游标应该在声明时捕获变量上下文,但它们目前在打开时捕获变量上下文。

  • 对具有键约束的表的 DML 查询还不能返回值。

    解决方法
    不要使用以下语句:

    DO $$
    DECLARE
        y int;
    BEGIN
        y := UPDATE tbl WHERE col1 = 3 SET col2 = 4;
    END;
    $$
    

    而应使用 SELECT 检查 DML 查询结果:

    DO $$
    DECLARE
        y int;
    BEGIN
        y := SELECT COUNT(*) FROM tbl WHERE col1 = 3;
        PERFORM UPDATE tbl SET col2 = 4 WHERE col1 = 3;
    END;
    $$;