更新时间:2026-07-08 GMT+08:00
分享

创建函数

功能描述

平台支持创建使用UDF和UDTF等自定义函数应用于Spark作业开发中。

语法格式

CREATE FUNCTION [db_name.]function_name AS class_name
  [USING resource,...]

resource: 
  : JAR file_uri

CREATE OR REPLACE FUNCTION [db_name.]function_name AS class_name
  [USING resource,...]

resource: 
  : JAR file_uri

注意事项

  • 如果在数据库中存在同名的函数,系统将会报错。
  • 只支持Hive语法创建函数。
  • 请注意避免该场景:如果创建的自定义函数F1指定类C1,程序包名JAR1,创建自定义函数F2也指定类C1,程序包JAR2,因为F2和F1使用相同的类名,导致功能相互冲突,影响作业执行。
  • UDF热加载功能处于受限使用阶段,如需使用请提交工单申请开通。

关键字

  • USING :需要加载的资源。可以是JAR、文件或者URI的列表。
  • OR REPLACE:支持自定义函数热加载功能。
    • 如果创建自定义函数时不携带OR REPLACE,则需要注意以下场景:
      表1 不携带OR REPLACE场景说明

      场景说明

      场景举例

      生效机制

      操作影响

      场景一:修改了原有程序包类的实现逻辑,重新创建的函数指定的JAR包名和类名保持和原有一致。

      在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。后续对J1包中函数实现做了逻辑修改,重新执行创建函数F2,指定类名C1,Jar包名J1。注意,如果步骤2继续使用函数名F1,则会因为函数名重复导致创建失败。这时可以考虑使用OR REPLACE,或者替换所有作业中的函数F1为F2。

      需要重启Spark SQL队列后新创建的自定义函数F2生效

      需要重启Spark SQL队列,影响当前运行的作业。重启队列后,影响F1原有功能,F1的功能变为和F2一样。

      场景二:在原有程序包类的基础上新增了类,新创建的函数指定为新增的类,包名不变。

      在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。J1的Jar包中新增了类C2,C1保持不变,新创建自定义函数F2,指定类名C2,Jar包名J1。

      需要重启Spark SQL队列后新创建的自定义函数F2生效

      需要重启Spark SQL队列,影响当前运行的作业。重启队列后,F1的功能不变。

      场景三:原有程序包类的实现逻辑不变,重新打包程序包名。新创建的函数指定新JAR包名,类名保持不变。

      在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。重新打包Jar包为J2,功能逻辑不变。新创建的自定义函数F2,指定类名C1,Jar包名J2。

      新创建的自定义函数F2立即生效

      无影响。

    • 如果创建自定义函数携带OR REPLACE,表示需要对已有的函数内容进行功能替换并实时生效。
      该功能处于受限使用阶段,如需使用请提交工单申请开通。
      • 如果要在所有SQL队列上立即生效,需要分别选择SQL队列执行一遍:CREATE OR REPLACE xxx FUNCTION ...,否则没有执行的队列可能延迟0-12小时生效。
      • 如果当前运行的作业中使用自定义函数F1,该F1函数指定类名C1,程序包名J1,作业运行了一半后,重新修改J1程序包逻辑,CREATE OR REPLACE FUNCTION F1后,后续作业使用新的F1函数逻辑,但是已执行完一半的作业使用旧的函数逻辑。
        表2 携带OR REPLACE场景说明

        场景说明

        场景举例

        生效机制

        操作影响

        场景一:修改了原有程序包类的实现逻辑,重新创建的函数指定的JAR包名和类名保持和原有一致。

        在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。后续对J1包中函数实现做了逻辑修改,重新执行创建函数F1,指定类名C1,Jar包名J1。

        立即生效

        F1的功能变成新修改的逻辑。

        场景二:在原有程序包类的基础上新增了类,新创建的函数指定为新增的类,包名不变。

        在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。J1的Jar包中新增了类C2,C1保持不变,新创建自定义函数F2,指定类名C2,Jar包名J1。因为是第一次创建指定C2的函数,这时该F2函数不能立即生效。

        两种生效方式:1. CREATE OR REPLACE FUNCTION F2创建语句再执行一次生效;2. 重启Spark SQL队列后生效

        如果是选择重启Spark SQL队列,则会导致当前运行的作业受影响。

        场景三:修改了原有程序包类的类名,新创建的函数指定为新类名,包名不变。

        在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。J1的Jar包中修改原C1为C2,C1已经不存在,新创建自定义函数F2,指定类名C2,Jar包名J1。

        立即生效

        F1功能失效,F2功能立即生效。

        场景四:原有程序包类的实现逻辑不变,重新打包程序包名。新创建的函数指定新JAR包名,类名保持不变。

        在Spark SQL队列下已创建自定义函数F1,指定类名C1,Jar包名J1。重新打包Jar包为J2,功能逻辑不变。新创建的自定义函数F2,指定类名C1,Jar包名J2。

        立即生效

        无影响。

示例

创建函数mergeBill。

CREATE FUNCTION mergeBill AS 'com.xxx.hiveudf.MergeBill'
  using jar 'obs://onlyci-7/udf/MergeBill.jar';

相关文档