You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过API自动向Oracle Apex应用上传静态内容

自动化上传静态资源到Oracle APEX应用

我有一个包含JavaScript代码包的dist.zip文件,想把它作为静态应用文件添加到Oracle APEX应用里。目前只能手动进入应用构建器,通过文件上传器完成上传。

问:能不能通过API访问实现这个上传流程的自动化?

编辑:根据解决方案,我创建了一个可通过ORDS REST模板调用的包,用于上传zip文件。

CREATE OR REPLACE PACKAGE BODY ords_utils AS
  
  /**
   * 根据文件扩展名获取MIME类型
   */
  FUNCTION get_mime_type(p_filename IN VARCHAR2) RETURN VARCHAR2 IS
    l_ext VARCHAR2(10);
  BEGIN
    l_ext := UPPER(SUBSTR(p_filename, INSTR(p_filename, '.', -1) + 1));
    
    RETURN CASE l_ext
      -- 文本文件
      WHEN 'HTML' THEN 'text/html'
      WHEN 'HTM' THEN 'text/html'
      WHEN 'CSS' THEN 'text/css'
      WHEN 'JS' THEN 'application/javascript'
      WHEN 'JSON' THEN 'application/json'
      WHEN 'XML' THEN 'application/xml'
      WHEN 'TXT' THEN 'text/plain'
      
      -- 图片文件
      WHEN 'PNG' THEN 'image/png'
      WHEN 'JPG' THEN 'image/jpeg'
      WHEN 'JPEG' THEN 'image/jpeg'
      WHEN 'GIF' THEN 'image/gif'
      WHEN 'SVG' THEN 'image/svg+xml'
      WHEN 'ICO' THEN 'image/x-icon'
      WHEN 'WEBP' THEN 'image/webp'
      
      -- 字体文件
      WHEN 'WOFF' THEN 'font/woff'
      WHEN 'WOFF2' THEN 'font/woff2'
      WHEN 'TTF' THEN 'font/ttf'
      WHEN 'OTF' THEN 'font/otf'
      
      -- 压缩包文件
      WHEN 'ZIP' THEN 'application/zip'
      WHEN 'TAR' THEN 'application/x-tar'
      WHEN 'GZ' THEN 'application/gzip'
      
      -- 文档文件
      WHEN 'PDF' THEN 'application/pdf'
      WHEN 'DOC' THEN 'application/msword'
      WHEN 'DOCX' THEN 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
      WHEN 'XLS' THEN 'application/vnd.ms-excel'
      WHEN 'XLSX' THEN 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      
      -- 默认类型
      ELSE 'application/octet-stream'
    END;
  END get_mime_type;
  
  /**
   * 使用APEX_ZIP包上传并解压ZIP文件的主函数
   */
  FUNCTION upload_zip(p_zip_blob IN BLOB, p_app_id IN NUMBER) RETURN VARCHAR2 IS
    l_file_count PLS_INTEGER := 0;
    l_file_name VARCHAR2(4000);
    l_file_content BLOB;
    l_mime_type VARCHAR2(200);
    l_files apex_zip.t_files;
    l_error_msg VARCHAR2(4000);
    l_log_msg VARCHAR2(4000);
    l_workspace_id NUMBER;
  BEGIN
    
    -- 根据应用ID获取工作区ID
    BEGIN
      SELECT workspace_id INTO l_workspace_id
      FROM apex_applications
      WHERE application_id = p_app_id;
    EXCEPTION WHEN NO_DATA_FOUND THEN
      l_log_msg := 'ERROR: 应用ID ' || p_app_id || ' 不存在';
      apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
      RETURN '{"status":"error","message":"应用不存在","files_uploaded":0}';
    END;
    
    APEX_UTIL.set_security_group_id(p_security_group_id => l_workspace_id);
    APEX_APPLICATION.g_flow_id := p_app_id;

    -- 记录上传开始日志
    l_log_msg := 'upload_zip 已调用。工作区ID: ' || l_workspace_id || ', 应用ID: ' || p_app_id || ', 输入Blob大小: ' || NVL(DBMS_LOB.GETLENGTH(p_zip_blob), 0) || ' 字节';
    apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
    
    IF p_zip_blob IS NULL OR DBMS_LOB.GETLENGTH(p_zip_blob) = 0 THEN
      l_log_msg := 'ERROR: ZIP文件为空或未传入';
      apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
      RETURN '{"status":"error","message":"ZIP文件为空","files_uploaded":0}';
    END IF;
    
    BEGIN
      -- 获取ZIP中的文件列表(p_only_files = true 跳过目录)
      l_log_msg := '尝试提取ZIP中的文件列表...';
      apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
      
      l_files := apex_zip.get_files(p_zipped_blob => p_zip_blob, p_only_files => true);
      
      l_log_msg := '在ZIP包中找到 ' || l_files.COUNT || ' 个文件';
      apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
      
      -- 处理每个文件
      FOR i IN 1..l_files.COUNT LOOP
        l_file_name := l_files(i);
        l_log_msg := '正在处理文件 ' || i || '/' || l_files.COUNT || ': ' || l_file_name;
        apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
        
        -- 从ZIP中提取文件内容
        BEGIN
          l_file_content := apex_zip.get_file_content(
            p_zipped_blob => p_zip_blob,
            p_file_name   => l_file_name
          );
          
          -- 获取MIME类型
          l_mime_type := get_mime_type(l_file_name);
          l_log_msg := '  文件大小: ' || DBMS_LOB.GETLENGTH(l_file_content) || ' 字节, MIME类型: ' || l_mime_type;
          apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
          
          -- 创建静态应用文件
          BEGIN
            wwv_flow_imp_shared.create_app_static_file (
              p_file_name    => l_file_name,
              p_mime_type    => l_mime_type,
              p_file_content => l_file_content,
              p_flow_id      => p_app_id
            );
            
            l_file_count := l_file_count + 1;
            l_log_msg := '  ✓ 上传成功: ' || l_file_name;
            apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
            
          EXCEPTION WHEN OTHERS THEN
            l_error_msg := SQLERRM;
            l_log_msg := '  ✗ 上传 ' || l_file_name || ' 失败: ' || l_error_msg;
            apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
          END;
          
        EXCEPTION WHEN OTHERS THEN
          l_error_msg := SQLERRM;
          l_log_msg := '  ✗ 提取 ' || l_file_name || ' 内容失败: ' || l_error_msg;
          apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
        END;
      END LOOP;
      
      l_log_msg := '上传完成。成功上传文件总数: ' || l_file_count;
      apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
      
    EXCEPTION WHEN OTHERS THEN
      l_error_msg := SQLERRM;
      l_log_msg := 'upload_zip 执行异常: ' || l_error_msg;
      apex_debug_message.log_message(p_message => l_log_msg, p_enabled => true);
      RETURN '{"status":"error","message":"' || REPLACE(l_error_msg, '"', '\"') || '","files_uploaded":0}';
    END;
    
    -- 返回成功响应
    RETURN '{"status":"success","message":"文件上传成功","files_uploaded":' || l_file_count || '}';
    
  END upload_zip;
  
END ords_utils;

内容的提问来源于stack exchange,提问作者Greg Reynolds

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.11 18:08:08