zoukankan      html  css  js  c++  java
  • 一步步实现ABAP后台导入EXCEL到数据库【2】

    前文:http://www.cnblogs.com/hhelibeb/p/5912330.html

      既然后台作业只能在应用服务器运行,那么,我们可以先将要上传的数据保存在应用服务器中,之后再以后台作业的形式导入数据库。这里需要使用的关键字是OPEN DATASET。

    1. OPEN DATASET 

    Syntax

    OPEN DATASET dset
      FOR { INPUT | OUTPUT | APPENDING | UPDATE }
      IN { { BINARY MODE }
         | { TEXT MODE ENCODING { DEFAULT
                                | {UTF-8 [SKIPPING|WITH BYTE-ORDER MARK]}
                                | NON-UNICODE }
                       [WITH {NATIVE|SMART|UNIX|WINDOWS} LINEFEED]  }
         | { LEGACY BINARY MODE [{BIG|LITTLE} ENDIAN]
                                [CODE PAGE cp] }
         | { LEGACY TEXT MODE [{BIG|LITTLE} ENDIAN]
                              [CODE PAGE cp]
                              [WITH {NATIVE|SMART|UNIX|WINDOWS} LINEFEED] } }
      [AT POSITION pos]
      [TYPE attr]
      [FILTER opcom]
      [MESSAGE msg]
      [IGNORING CONVERSION ERRORS]
      [REPLACEMENT CHARACTER rc].

    效果

      打开由dset指定的应用服务器上的文件。

    附加项

    tips: text evirionment

    text evirionment是ABAP程序的运行时环境的一部分,由语言、locale和系统内码表组成。同一个内部会话中的所有程序有一个共同的文本环境。默认情况下,内部会话的text environment由登录语言决定,并且也可以被语句set locale指定。当前的text environment包含在系统字段sy-langu中
      • CODE PAGE cp
        决定文件中字符型数据对象以指定的内码表cp操作.
      • TYPE attr
        为文件设置操作系统参数,或者控制文本文件的行尾选项.

         例子:    

               创建一个文件test.dat。TYPE指定的文件属性是操作系统IBM i5/OS(在OS/400之前)中的。

    OPEN DATASET 'test.dat'
      TYPE 'lrecl=80, blksize=8000, recfm=FB'
      FOR OUTPUT IN TEXT MODE
                 ENCODING DEFAULT
                 WITH SMART LINEFEED.
      • MESSAGE msg
        如果发生了错误,可以在msg中返回操作系统信息.

       使用OPEN DATASET来实现上传数据到应用服务器,即程序中的output_data子进程:

    *&---------------------------------------------------------------------*
    *&      Form  OUTPUT_DATA
    *&---------------------------------------------------------------------*
    *       将数据写入到Applacation Server
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM output_data .
    
      DATA s_file TYPE rlgrap-filename.
    
      PERFORM generate_filename_in_server USING s_file.
    
      OPEN DATASET s_file FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.
    
      IF sy-subrc = 0 .
    
        LOOP AT itab INTO wa.
    
          TRANSFER wa TO s_file.
    
          IF sy-subrc <> 0 .
            MESSAGE 'ERROR!!' TYPE 'E'.
          ENDIF.
    
        ENDLOOP.
    
        CLOSE DATASET s_file.
    
        WRITE: /'写入服务器文件成功'.
    
        PERFORM submit_insert_program USING s_file.  "调用导入程序
    
      ELSE.
    
        WRITE: /'写入服务器文件失败' .
    
      ENDIF.
    
    ENDFORM.
    *&---------------------------------------------------------------------*
    *&      Form  GET_file_name_in_server
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM generate_filename_in_server USING s_file .
    
      DATA s_name TYPE string.
    
      CALL FUNCTION 'SO_SPLIT_FILE_AND_PATH'
        EXPORTING
          full_name     = p_source
        IMPORTING
          stripped_name = s_name
    *     FILE_PATH     =
        EXCEPTIONS
          x_error       = 1
          OTHERS        = 2.
      IF sy-subrc <> 0.
    * Implement suitable error handling here
      ENDIF.
    
      GET TIME.
    
      CONCATENATE '/tmp/' sy-datum  sy-uzeit s_name  '.txt' INTO s_file.
    
      TRANSLATE s_file TO LOWER CASE.
    
    ENDFORM.

    2,实现导入程序

      上传到服务器的程序已经实现,现在新建一个程序ztest_import,实现导入到数据库的功能。同样使用OPEN DATASET语句来实现:

    REPORT ztest_import.
    
    SELECTION-SCREEN: BEGIN OF BLOCK blk.
    PARAMETERS: s_file TYPE rlgrap-filename .
    SELECTION-SCREEN END OF BLOCK blk.
    
    
    DATA: BEGIN OF wa,
            col1(30) TYPE c,
            col2(30) TYPE c,
            col3(30) TYPE c,
          END OF wa.
    
    FIELD-SYMBOLS: <hex_container> TYPE c.
    
    TRANSLATE s_file TO LOWER CASE.
    
    
    OPEN DATASET s_file FOR INPUT IN TEXT  MODE ENCODING DEFAULT.
    
    IF sy-subrc = 0.
    
      ASSIGN wa TO <hex_container> CASTING.
    
      DO.
        "由于没有使用MAXIMUM LENGTH选项,所以每次读取的最大字节数
        "由<hex_container>所占字节数决定
        READ DATASET s_file INTO <hex_container>.
    
        IF sy-subrc = 0.
    
    *"ztestly是在SE11中新建的表,结构和上传的excel相符,过程省略
    
          INSERT ztestly FROM wa. 
    
        ELSE.
    
          EXIT.
    
        ENDIF.
    
      ENDDO.
    
      CLOSE DATASET s_file.
    
      DELETE DATASET s_file.  "成功执行导入后,删除服务器上的文件
    
    ELSE.
    
      MESSAGE 'open failed' TYPE 'I

    3,在上传程序中调用导入程序

      如果你看过我博客中有关submit的文章,可能会记得,submit语句是可以安排程序作为后台作业进行的。下面我们就使用这个特性,在上传程序ztest_upload的子程序submit_insert_program中调用导入程序ztest_import,代码如下:

    *&---------------------------------------------------------------------*
    *&      Form  SUBMIT_INSERT_PROGRAM
    *&---------------------------------------------------------------------*
    *       text
    *----------------------------------------------------------------------*
    *  -->  p1        text
    *  <--  p2        text
    *----------------------------------------------------------------------*
    FORM submit_insert_program USING s_file.
    
      DATA: w_jobid  TYPE tbtcjob-jobcount,
            w_stepnm TYPE tbtcjob-stepcount,
            p_job_nm TYPE tbtcjob-jobname VALUE  'ZTEST_IMPORT'.
    
      CLEAR:w_jobid.
    
      CALL FUNCTION 'JOB_OPEN'
        EXPORTING
    *     DELANFREP        = ' '
    *     JOBGROUP         = ' '
          jobname          = p_job_nm
    *     SDLSTRTDT        = NO_DATE
    *     SDLSTRTTM        = NO_TIME
        IMPORTING
          jobcount         = w_jobid
        EXCEPTIONS
          cant_create_job  = 1
          invalid_job_data = 2
          jobname_missing  = 3
          OTHERS           = 4.
    
      SUBMIT ztest_import WITH s_file = s_file VIA JOB p_job_nm NUMBER w_jobid  AND RETURN.
    
      IF sy-subrc = 0.
    
        CALL FUNCTION 'JOB_CLOSE'
          EXPORTING
            jobcount             = w_jobid
            jobname              = p_job_nm
            strtimmed            = 'X'
          EXCEPTIONS
            cant_start_immediate = 1
            invalid_startdate    = 2
            jobname_missing      = 3
            job_close_failed     = 4
            job_nosteps          = 5
            job_notex            = 6
            lock_failed          = 7
            OTHERS               = 8.
    
        IF sy-subrc <> 0.
          WRITE: /'后台作业发布失败'.
        ELSE.
          WRITE: /'后台作业发布成功'.
        ENDIF.
    
      ENDIF.
    
    ENDFORM.

      运行zterst_upload,上传一个有效的excel文件,我们便可以在上一篇文章提到的自有作业界面看到后台作业执行成功,并且在SE16中查到自建表zestly中已经插入了相关数据。如果要改变后台作业的计划时间,可以在JOB_CLOSE函数中设置相关参数。

     
  • 相关阅读:
    【转】微信小程序原理
    【转】onAttachedToWindow()在整个Activity生命周期的位置及使用
    中序遍历非递归遍历算法
    多项式加法运算
    中缀表达式转换为后缀表达式
    多项式计算
    最大子列和问题
    广度优先搜索
    广搜和深搜的区别
    cookie 与 session 的区别详解
  • 原文地址:https://www.cnblogs.com/hhelibeb/p/5931727.html
Copyright © 2011-2022 走看看