前文:IT虾米网

  既然后台作业只能在应用服务器运行,那么,我们可以先将要上传的数据保存在应用服务器中,之后再以后台作业的形式导入数据库。这里需要使用的关键字是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函数中设置相关参数。

 

评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

一步步实现ABAP后台导入EXCEL到数据库【1】