本文介紹如何對SAP數據庫表進行增刪改查操作,重點是說明如何爲數據的增刪改查提供編輯界面。假定現在要對 zemployee 表進行增刪改查操作。表的字段如下:
通過ABAP 代碼進行 CRUD 操作
INSERT 語句對 database table 的記錄進行插入操作。語法如下:
INSERT dbtab from wa/itab.
如果至少有一筆記錄插入成功,sy-subrc = 0,如果至少有一筆記錄插入失敗, sy-subrc =4,比如可能由於 primary key 重複。
DATA: gs_emp LIKE zemployee.
CLEAR gs_emp.
gs_emp-empid = '003'.
gs_emp-empname = 'WANG'.
gs_emp-empaddr = 'Wuhan'.
INSERT zemployee1 FROM gs_emp.
IF sy-subrc IS INITIAL.
WRITE sy-dbcnt.
ELSE.
WRITE 'Error'.
ENDIF.
UPDATE 語句允許對數據庫表的記錄進行修改。
DATA: gs_emp LIKE zemployee1.
CLEAR gs_emp.
gs_emp-empid = '003'.
gs_emp-empname = 'Stone Wang'.
gs_emp-empaddr = 'Wuhan'.
UPDATE zemployee1 FROM gs_emp.
IF sy-subrc IS INITIAL.
WRITE sy-dbcnt.
ELSE.
WRITE 'Error'.
ENDIF.
如果因爲不知道要插入行的 Primary key 是否已經存在 ,從而不能確定是否可使用 UPDATE 語句,那麼 ,請使用 MODIFY 語句。MODIFY 語句既可以插入,也可以更新。
要從數據庫表中刪除行 ,請使用 DELETE 語句。DELETE 語句允許刪除單行或多行。個人覺得刪除記錄的操作,沒有必要使用工作區,可以直接通過條件來定位要刪除的行。
DELETE FROM zemployee1 WHERE empid = '003'.
IF sy-subrc IS INITIAL.
WRITE sy-dbcnt.
ELSE.
WRITE 'Error'.
ENDIF.
表維護生成器
爲了方便對數據表的數據維護,最好能提供維護的界面。表維護生成器 (Table maintenance generator) 是 SAP 對數據表提供的一種通用方法,在 SE1 界面,通過菜單 Utilities -> Table Maintenance Generator 進行設置。設置界面如下:
設置了表維護生成器的 table,可以使用事務碼 SM30 進行數據的維護(增刪改查)。SM30 界面可以通過事務碼 SE93 創建一個事務碼來維護表。使用 SE93 並結合 SM30 的功能來創建事務碼的方法如下:
使用事務碼 SE93 進入界面,在 Transaction Code 字段輸入 ZEMP,點擊創建按鈕。
選擇 Transaction with parameters
在下一屏幕中,Transaction 輸入 SM30,勾上 Skip initial screen:
在最下面的 Default Values 部分,給定 VIEWNAME 和 UPDATE 兩個參數:
VIEW_MAINTAINENCE_CALL 函數
如果某個表設置了表維護生成器,可以利用函數 VIEW_MAINTAINENCE_CALL
來對錶進維護,界面同 SM30 相同。
CALL FUNCTION 'VIEW_MAINTENANCE_CALL'
EXPORTING
action = 'U'
view_name = 'ZEMPLOYEE'.
RS_TABLE_LIST_CREATE 函數
RS_TABLE_LIST_CREATE
函數比 VIEW_MAINTENANCE_CALL
更加靈活,即使表沒有維護“表維護生成器”,也可以通過代碼來進行數據維護操作。
CALL FUNCTION 'RS_TABLE_LIST_CREATE'
EXPORTING
table_name = 'ZEMPLOYEE'
action = 'ANLE'.
action 參數有 ANLE 或 ANZE,將使用不同的界面來進行數據維護。
通過 ALV 控件
對於簡單的數據表,可以使用 ALV 表格作爲界面。下面介紹通過 ALV 控件來維護表數據的方法。
第一步,編寫一個程序,將數據在 ALV 中顯示。代碼如下:
REPORT z_table_crud.
TYPE-POOLS: slis.
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE.
DATA: gt_zemp TYPE STANDARD TABLE OF zemployee,
gs_zemp LIKE LINE OF gt_zemp.
START-OF-SELECTION.
PERFORM get_data.
PERFORM show_data.
FORM get_data.
SELECT * FROM zemployee
INTO CORRESPONDING FIELDS OF TABLE gt_zemp.
ENDFORM. "get_data
FORM set_fieldcat USING fldname desc editable.
DATA: ls_fieldcat TYPE slis_fieldcat_alv.
CLEAR ls_fieldcat.
ls_fieldcat-fieldname = fldname.
ls_fieldcat-seltext_m = desc.
ls_fieldcat-edit = editable.
APPEND ls_fieldcat TO gt_fieldcat.
ENDFORM. "set_fieldcat
FORM show_data.
PERFORM set_fieldcat USING 'EMPID' 'Employee ID' 'X'.
PERFORM set_fieldcat USING 'EMPNAME' 'Employee Name' 'X'.
PERFORM set_fieldcat USING 'EMPADDR' 'Employee Addr' 'X'.
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
it_fieldcat = gt_fieldcat[]
TABLES
t_outtab = gt_zemp[] .
ENDFORM. "show_data
第二步:ALV 關聯到自定義工具欄
ALV 內置的工具欄沒有與保存相關的按鈕,解決辦法是拷貝一個工具欄,讓 ALV 控件關聯拷貝的工具欄。使用事務碼 SE41 從程序 SAPLKKBL 拷貝 STANDARD 工具欄到本程序。
在程序中添加一個子例程,設置 GUI STATUS:
FORM set_pf_status USING rt_extab TYPE slis_t_extab.
SET PF-STATUS 'ZSTANDARD'.
ENDFORM.
添加另外一個子例程,用於將界面上的變更數據保存到數據表,代碼待會再編寫。
FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
ENDFORM.
將 ALV 關聯到 ZSTANDARD GUI Status:
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = sy-repid
i_callback_pf_status_set = 'SET_PF_STATUS'
i_callback_user_command = 'USER_COMMAND'
it_fieldcat = gt_fieldcat[]
TABLES
t_outtab = gt_zemp[].
在 ZSTANDARD 工具欄上新建一個 SAVE 按鈕,Function code 爲 SAVE, Function text 爲 Save。
第三步,編寫代碼處理數據從 ALV 到內表,內表到數據表:
FORM user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
DATA: r_ref_grid TYPE REF TO cl_gui_alv_grid.
IF r_ucomm = 'SAVE'.
" 更新的數據保存到內表
IF r_ref_grid IS INITIAL.
CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
IMPORTING
e_grid = r_ref_grid.
ENDIF.
IF NOT r_ref_grid IS INITIAL.
CALL METHOD r_ref_grid->check_changed_data.
ENDIF.
rs_selfield-refresh = 'X'.
" 更新的數據從內表到數據表
UPDATE zemployee FROM TABLE gt_zemp.
MESSAGE 'Data was saved successfully.' TYPE 'S'.
ENDIF.
ENDFORM.
Table Control
使用表格控件 (table control) 對數據進行 CRUD 操作,界面的友好性好於 ALV 控件。本文介紹嚮導方式的使用方法。
第一步,創建一個編號爲 2000 的 Screen,創建一個名爲 STANDARD 的 GUI Status, 在 Function Keys 部分,設置 4 個按鈕如下圖所示:
爲了程序能正常退出,激活 Screen 2000 默認的 PBO 和 PAI 事件,並編寫如下代碼:
REPORT z_table_crud.
DATA: ok_code LIKE sy-ucomm,
save_ok LIKE ok_code.
START-OF-SELECTION.
CALL SCREEN 2000.
MODULE status_2000 OUTPUT.
SET PF-STATUS 'STANDARD'.
ENDMODULE. "STATUS_2000 OUTPUT
MODULE user_command_2000 INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'EXIT' OR 'CANCEL'.
LEAVE PROGRAM.
ENDCASE.
ENDMODULE. "USER_COMMAND_2000 INPUT
此時,程序能夠運行並且退出,但程序顯示的是一個空界面。
第二步,在程序中定義兩個內表,與要維護的數據表 zemployee 結構一致,但爲了方便 table control 的使用,特意增加一列 chk,後面會用到 chk:
DATA: gs_emp1 LIKE zemployee.
DATA: BEGIN OF gt_emp OCCURS 0,
chk TYPE c.
INCLUDE STRUCTURE gs_emp1.
DATA: END OF gt_emp.
DATA: gt_emp_save LIKE STANDARD TABLE OF zemployee,
gs_emp LIKE LINE OF gt_emp_save.
第三步,利用嚮導生成數據維護的界面:
將程序所有對象激活之後,進入 Screen 2000 的 Layout 界面。利用嚮導來生成 zemployee 表的數據維護界面。在嚮導的步驟中,說明幾個要點。
指定 table control 的名稱:
指定程序用到的內表爲 gt_emp:
選擇字段,不要包括 chk:
定義字段屬性,按照下圖定義:
- Input control: 表示可以編輯
- With column headers : 定義默認的字段頭
- Line selection column: 選 CHK,選擇字段必須爲 C,長度爲 1
下一屏,按下圖設置:
下一屏,使用嚮導默認的值:
嚮導幫我們生成了很多代碼,激活後,程序可以運行,但數據表的數據不會加載到界面。
第四步:加載數據
我們只需要將數據加載到內表 gt_emp,數據即可以在界面中顯示。定義一個子例程:
FORM get_data.
SELECT * INTO CORRESPONDING FIELDS OF TABLE gt_emp
FROM zemployee.
ENDFORM.
在 start-of-selection 事件中加載:
START-OF-SELECTION.
PERFORM get_data.
CALL SCREEN 2000.
第五步:編寫數據保存的代碼
FORM save_data.
LOOP AT gt_emp.
CLEAR gs_emp.
gs_emp-mandt = '001'.
gs_emp-empid = gt_emp-empid.
gs_emp-empname = gt_emp-empname.
gs_emp-empaddr = gt_emp-empaddr.
APPEND gs_emp TO gt_emp_save.
ENDLOOP.
MODIFY zemployee FROM TABLE gt_emp_save.
MESSAGE 'Data was saved.' TYPE 'S'.
ENDFORM.
點擊 SAVE 按鈕運行 save_data:
MODULE user_command_2000 INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'BACK'.
LEAVE TO SCREEN 0.
WHEN 'EXIT' OR 'CANCEL'.
LEAVE PROGRAM.
WHEN 'SAVE'.
PERFORM save_data.
ENDCASE.
ENDMODULE.
ABAP 提供 Restful Service
利用 ABAP 提供 Restful Service,這樣可以使用其它編程語言作爲數據維護界面,靈活度較高。ABAP 提供 Restful Service 請參考我之前寫的博文: