星期四, 11月 02, 2023

2002-09-30 如何知道以 ODBC 或 JDBC 連接至 AS/400 擷取資訊的真正使用者?


如何知道以 ODBC 或 JDBC 連接至 AS/400 擷取資訊的真正使用者?

現在有許多軟體由於電子商務的需求使用 ODBC 或 JDBC 存取 AS/400 資訊,而 AS/400 的
Host Server 功能,會於啟動 QSERVER 子系統時,自動啟動一個名為 QZDASRVSD 的作業用
以等待遠端作業需求,當遠端以 ODBC 或 JDBC 發出連結 AS/400 需求時,系統會自行啟
動另一個名為 QZDASOINIT 的作業,用以服務遠端
PC 作業所提出的服務需求,例如執行
SQL 指令。由於系統是以 QUSER 啟動 QZDASOINIT 
作業,所以您無法以 WRKACTJOB 指令
直接得知目前 QZDASOINIT 作業正在服務哪一個使用者,但你可以於 WRKACTJOB 畫面選 5 

5      QZDASOINIT   QUSER       PJ       .0                   PSRW

進入 WRKJOB 畫面選 10 Display Job Log 檢視 Job Log,此時若此作業有服務過有執行
可以看到此作業有無正在服務哪一個使用者。但這個方法顯然麻煩多了,下述的範例直接
透過系統 API QUSLJOB 直接取得並顯示於畫面狀態行。詳細資訊參考 System API Refference SC41-5801-03 Chapter 94.


File  : QCLSRC
Member: LSTODBCUSR
Type  : CLP
Usage : CRTCLPGM LSTODBCUSR
        CALL LSTODBCUSR


/* Lists real connected ODBC users without C */
/* API QUSLJOB                               */

  pgm

/*                                                           */
/* *Usrspc variables...                                      */
/*                                                           */
   dcl   &usrspc        *char      20   /* Space name/lib    */

   dcl   &offslst       *char       4   /* Offset to list    */
   dcl   &sizlste       *char       4   /* Size list entries */
   dcl   &nbrlste       *dec   (  7 0 ) /* Number of entries */

   dcl   &us_hdr        *char     150   /* Space header      */

   dcl   &us_jobe       *char     512   /* A single entry    */

/*                                                           */
/* Job selection variables...                                */
/*                                                           */
   dcl   &jobname       *char      26   /* Select job name   */
   dcl   &dftuser       *char      10   value( 'QUSER     ' )
                                        /* Prestart user     */
/* Variable keys to select                                   */
   dcl   &nbrkeys       *char       4   value( x'00000002' )
                                        /* bin(   2 )        */
   dcl   &rtvcurusr     *char       4   value( x'00000131' )
                                        /* bin( 305 )        */
   dcl   &rtvsts        *char       4   value( x'00000065' )
                                        /* bin( 101 )        */
/* Variable key list...                                      */
   dcl   &varkeylst     *char     400

/*                                                           */
/* Retrieved values from job list...                         */
/*                                                           */
   dcl   &job           *char      10
   dcl   &user          *char      10
   dcl   &nbr           *char       6

   dcl   &curuser       *char      10   /* Current user      */
   dcl   &sts           *char       4   /* Job status        */


/*                                                           */
/* Global message monitor...                                 */
/*                                                           */

   monmsg   ( cpf0000 mch0000 )  exec( goto  Std_Err )

/*                                                           */
/* Create a *usrspc to work with...                          */
/*                                                           */

   chgvar    &usrspc       ( 'ODBCJOB   ' *cat 'QTEMP     ' )

   call  QUSCRTUS         ( +
                            &usrspc                 +
                            'TMPLST    '            +
                            x'00001000'             +
                            X'00'                   +
                            '*ALL      '            +
                            'Temp list ODBC jobs    ' +
                            '*YES      '            +
                            x'0000000000000000'     +
                          )


/*                                                           */
/* This sets up selection criteria for list jobs API...      */
/*                                                           */

/* The jobname we're after...                                */

   chgvar    &jobname      ( 'QZDASOINIT' *cat +
                             &dftuser     *cat +
                             '*ALL   '         +
                           )

/* Include current job user and active job status...         */

   chgvar    &varkeylst    ( &rtvcurusr *cat &rtvsts )

/*                                                           */
/* This lists active jobs with the job name specified.       */
/*                                                           */

   call  QUSLJOB          ( +
                            &usrspc                 +
                            'JOBL0200'              +
                            &jobname                +
                            '*ACTIVE   '            +
                            x'0000000000000000'     +
                            'B'                     +
                            &nbrkeys                +
                            &varkeylst              +
                          )



/*                                                           */
/* Get the *usrspc header for the list attributes...         */
/*                                                           */

   call  QUSRTVUS         ( +
                            &usrspc                 +
                            x'00000001'             +
                            x'00000096'             +
                            &us_hdr                 +
                          )

/*                                                           */
/* Get the offset to the list within the space, the number   */
/*   of list entries and size of each entry from the header. */
/*                                                           */
   chgvar    &offslst        %sst( &us_hdr    125 4 )
   chgvar    &nbrlste        %bin( &us_hdr    133 4 )
   chgvar    &sizlste        %sst( &us_hdr    137 4 )

/* If no entries, then get out of here...                    */

   if  ( &nbrlste *eq 0 )     do
      sndpgmmsg  msgid( CPF9898 ) msgf( QCPFMSG ) +
                   msgdta( 'No ODBC jobs found.' )
      goto   Clean_up
   enddo


/* Set the offset to the list within the space...            */

   chgvar    %bin( &offslst ) ( %bin( &offslst ) + 1 )


Nxt_JobE:

/* Get an entry from the list...                             */

   call  QUSRTVUS         ( +
                            &usrspc                 +
                            &offslst                +
                            &sizlste                +
                            &us_jobe                +
                          )

/* Extract job info from list entry...                       */

   chgvar    &job            %sst( &us_jobe     1  10 )
   chgvar    &user           %sst( &us_jobe    11  10 )
   chgvar    &nbr            %sst( &us_jobe    21   6 )

   chgvar    &curuser        %sst( &us_jobe    81  10 )
   if  ( &curuser *eq &dftuser )     do
      chgvar    &curuser        '*DEFAULT'
   enddo

   chgvar    &sts            %sst( &us_jobe   109   4 )


/* Display the result...                                     */

   sndpgmmsg  msgid( CPF9898 ) msgf( QCPFMSG ) +
                msgdta( 'Job<' *cat &nbr *tcat +
                '/' *cat &user *tcat +
                '/' *cat &job  *tcat +
                '> Current user<' *cat &curuser *tcat +
                '> Status<' *cat &sts *tcat '>')


/* Perform loop testing...                                   */

   chgvar    &nbrlste      ( &nbrlste - 1 )

   if  ( &nbrlste *gt 0 )     do

      chgvar    %bin( &offslst ) ( %bin( &offslst ) + +
                                   %bin( &sizlste ) )
      goto      Nxt_JobE

   enddo



/*                                                           */
/* Exit processing...                                        */
/*                                                           */


Clean_up:

   dltusrspc   %sst( &usrspc 11 10 )/%sst( &usrspc 1 10 )

   return

Std_Err:

   /* Move any *DIAG messages up the stack...        */

   Qsys/call  pgm( QSYS/QMHMOVPM ) parm( +
                                         '    '          +
                                         '*DIAG     '    +
                                         x'00000001'     +
                                         '*         '    +
                                         x'00000001'     +
                                         x'00000000'     +
                                       )
   Qsys/monmsg     ( CPF0000 MCH0000 )

   /* Resend any *ESCAPE messages up the stack...     */

   Qsys/call  pgm( QSYS/QMHRSNEM ) parm( +
                                         '    '          +
                                         x'00000000'     +
                                       )
   Qsys/monmsg     ( CPF0000 MCH0000 )

   return

endpgm





沒有留言: