SQL prêt-à-porter è una raccolta di istruzioni SQL pronte all’uso.
Il DB2 offre numerosi funzioni, viste, procedure raccolte nella grande famiglia “DB2 for i Service” che ad ogni release e technology refresh vengono ampliate ed arricchite.
Una fonte ricca di preziose informazioni per il database è il catalogo del DB2, che consiste in una collezione di viste che descrivono ogni oggetto presente nel DB2.
Oltre a tutto ciò ci si trova spesso nella situazione di aver bisogno di alcuni istruzioni “modello” da avere sempre a portata di mano.
Si potrebbe (e si dovrebbe) leggere attentamente i manuali e soprattutto il sito IBM developerworks per scoprire nei dettagli tutte le potenzialità dell’SQL per DB2 for i.
Ma se colti da pigrizia si vuole passare subito all’azione e invece di preoccuparsi di confezionare un vestito su misura, si opta per la soluzione più economica dei modelli standardizzati, ecco qua che viene in aiuto SQL prêt-à-porter.
Le istruzioni sono raggruppate per argomento:
- sequenze
- esecuzione comandi
- check-up DB2
- catalogo DB2
- rete
- check-up sistema
- PTF sistema operativo
- grafici
Alcuni degli esempi seguenti sono basati sulle tabelle del database di esempio fornito da IBM. Per creare il database di esempio eseguire la procedura:
call CREATE_SQL_SAMPLE('DB2SAMPLE');
Quindi l’istruzione seguente per impostarlo come schema predefinito:
set current schema = 'DB2SAMPLE';
Per ottenere un elenco completo delle funzioni, procedure e viste presenti in DB2 for i Service si può interrogare la vista SERV_INFO. In IBM i 7.3 ne esistono ben 99! In 7.1 sono 79 (al 21/02/19). Questo per evidenziare che ad ogni release e ad ogni TR questi servizi vengono sempre incrementati.
Per ogni servizio viene indicato anche il prerequisito necessario.
-- DB2 for i SERVICE INFO select SERVICE_CATEGORY "Categoria", SERVICE_NAME "Nome servizio", SERVICE_SCHEMA_NAME "Libreria", SYSTEM_OBJECT_NAME "Nome sistema", SQL_OBJECT_TYPE "Tipo", EARLIEST_POSSIBLE_RELEASE concat ' PTF DB2 liv. ' concat INITIAL_DB2_GROUP_LEVEL "Prerequisito", replace(substr(EXAMPLE, 1, position(x'0D', EXAMPLE) -1), '-- Description: ', '') "Descrizione breve" --, EXAMPLE "Descrizione completa" from SERV_INFO order by SERVICE_CATEGORY, SERVICE_NAME;
Scarica l’elenco completo per la versione 7.3.
Sequenze ▲
Tabella fittizia con una sequenza di numeri (da V5R4)
with NbrTab (NBR) as (select 1 NBR from sysibm/sysdummy1 union all select NBR + 1 from NbrTab where NBR + 1 <= 10) -- modificare per estendere il limite superiore della serie select NBR from NbrTab;
Scovare i buchi nelle sequenze.
Si supponga di avere una tabella degli impiegati il cui codice è un progressivo e si voglia individuare se esistono dei codici mancanti nella sequenza dei dati esistenti. Nell’esempio il campo codice impiegato della tabella EMPLOYEE è alfanumerico ma contiene di fatto solo stringhe numeriche. Quindi può essere convertito agevolmente con la funzione int
per effettuare le operazioni matematiche. In una tabella dove il codice da controllare è un campo numerico questa conversione non è necessaria.
select T1.EMPNO as "Codice1", (select min(T2.EMPNO) from EMPLOYEE as T2 where T2.EMPNO > T1.EMPNO) as "Codice2", ((select min(T2.EMPNO) from EMPLOYEE as T2 where T2.EMPNO > T1.EMPNO) - int(T1.EMPNO) -1) as "Gap" from EMPLOYEE as T1 where ((select min(T2.EMPNO) from EMPLOYEE as T2 where T2.EMPNO > T1.EMPNO) - int(T1.EMPNO)) > 1 order by T1.EMPNO;
Sempre nella nostra tabella impiegati abbiamo bisogno di trovare il primo codice libero da usare per creare un nuovo impiegato
select T1.EMPNO + 1 as "Codice libero" from EMPLOYEE as T1 exception join EMPLOYEE as T2 on int(T1.EMPNO) + 1 = T2.EMPNO fetch first 1 rows only;
Generare un ID univoco
-- restituisce bit data character string 13 bytes long - CHAR(13) FOR BIT DATA select generate_unique() from sysibm/sysdummy1; -- restituisce l'ID univoco formattato come timestamp select timestamp(generate_unique()) from sysibm/sysdummy1;
Esecuzione comandi ▲
Eseguire un comando CL da uno script SQL
call qcmdexc('CHGCURLIB $$LIBFS2 ', 20); -- da 7.1 non è più necessario il parametro con la lunghezza del comando call qcmdexc('DSPLIBL *PRINT');
Check-up DB2 ▲
Esistono alcune funzioni/procedure che visualizzano informazioni utili per analizzare lo stato di “salute” e le performance del DB2
-- Retrieve the activity information for all objects within the DB2SAMPLE schema, using a maximum of 10 objects per each activity call Health_Activity(1, 0, 'DB2SAMPLE', '%', 10, null, null, null);
-- Retrieve the overview for the entire database. call Health_Database_Overview(1, '%', null, null, null);
- Restituisce un conteggio dei vari tipi di oggetti di database:p.es. schemi, tabelle, file fisici, file logici, indici binari, indici EVI…
-- Retrieve the size limit information for all object names which start with the letter E, within the DB2SAMPLE schema, using a maximum of 2 objects per each design limit call Health_Size_Limits(1, 0, 'DB2SAMPLE', 'E%', 2, null, null, null);
- Informazioni sui record allocati (da 7.1 TR11 / 7.2 TR3)
select table_schema, table_name, table_partition, relative_record_number, lock_state, lock_status, lock_scope, job_name, (select JOB_STATUS from TABLE(ACTIVE_JOB_INFO('NO', '', substr(job_name, locate('/', job_name, 8)+1), '')) AJ where AJ.JOB_NAME = job_name) as JOB_STATUS, (select FUNCTION from TABLE(ACTIVE_JOB_INFO('NO', '', substr(job_name, locate('/', job_name, 8)+1), '')) AJ where AJ.JOB_NAME = job_name) as FUNCTION from RECORD_LOCK_INFO where table_schema = 'DB2SAMPLE' and table_name = 'EMPLOYEE';
- informazioni statistiche oggetti (proprietario, data creazione, ultimo utilizzo, giorni di utilizzo, ultima modifica, ultimo salvataggio, registrato su giornale…)
-- statistiche degli oggetti di tipo *FILE della libreria DB2SAMPLE select * from table(OBJECT_STATISTICS('DB2SAMPLE', 'FILE')) as T;
Catalogo DB2 ▲
- elenco database definiti (WRKRDBDIRE)
select * from SYSCATALOGS;
- elenco tabelle (file fisici)
select TABLE_NAME "File", SYSTEM_TABLE_NAME "Nome sistema", TABLE_TYPE "Tipo", TABLE_TEXT "Descrizione" from SYSTABLES where TABLE_TYPE not in('L', 'V', 'A') and TABLE_SCHEMA = 'DB2SAMPLE' order by TABLE_NAME;
- elenco viste e indici (file logici)
select TABLE_NAME "File", SYSTEM_TABLE_NAME "Nome sistema", TABLE_TYPE "Tipo", TABLE_TEXT "Descrizione" from SYSTABLES where TABLE_TYPE in('L', 'V') and TABLE_SCHEMA = 'DB2SAMPLE' order by TABLE_NAME;
- elenco indici
select INDEX_NAME "Indice", SYSTEM_INDEX_NAME "Nome sistema", TABLE_SCHEMA "Lib.file dip.", TABLE_NAME "File dip.", SYSTEM_TABLE_NAME "File dip. (nome sistema)", INDEX_TEXT "Descrizione", IS_UNIQUE "Chiave un." from SYSINDEXES where table_schema = 'DB2SAMPLE' order by INDEX_NAME;
- elenco viste
select TABLE_NAME, VIEW_DEFINITION, CHECK_OPTION, IS_UPDATABLE from VIEWS where TABLE_SCHEMA = 'DB2SAMPLE' order by TABLE_NAME;
- definizione file
select COLUMN_NAME, ORDINAL_POSITION, COLUMN_DEFAULT, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE from COLUMNS where TABLE_SCHEMA = 'DB2SAMPLE' and TABLE_NAME = 'EMPLOYEE' order by ORDINAL_POSITION; -- oppure select ORDINAL_POSITION as "Pos", COLUMN_NAME "Nome", SYSTEM_COLUMN_NAME "Nome sis.", DDS_TYPE as "Tipo (DDS)", DATA_TYPE as "Tipo", DATA_TYPE_LENGTH as "Lungh.", NUMERIC_SCALE as "Dec.", IS_NULLABLE as "Cons.nulli", COLUMN_HEADING as "Descrizione", COLUMN_TEXT as "Descrizione (TEXT)", CCSID from table(qsys2/qsqsyscol2(char(ucase('DB2SAMPLE'), 10), char(ucase('EMPLOYEE'), 10))) as DefFile;
select ORDINAL_POSITION as "Ord.", SYSTEM_COLUMN_NAME as "Col.sist.", COLUMN_NAME as "Col.", DATA_type as "Tipo", sum(STORAGE) over(partition by 1 order by ORDINAL_POSITION) - STORAGE + 1 as "Pos.", LENGTH as "Lungh.", NUMERIC_SCALE as "Dec.", COLUMN_TEXT as "Descrizione (testo)", COLUMN_HEADING as "Descrizione" from QSYS2/SYSCOLUMNS where TABLE_SCHEMA = 'DB2SAMPLE' and TABLE_NAME = 'EMPLOYEE' order by ORDINAL_POSITION;
- ricerca campo campo per descrizione su tutti i file fisici di una libreria
select C.SYSTEM_TABLE_NAME, SYSTEM_COLUMN_NAME, trim(COLUMN_TEXT) as COLUMN_TEXT, COLUMN_HEADING, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE from SYSCOLUMNS c inner join SYSTABLES T on (C.SYSTEM_TABLE_SCHEMA, C.SYSTEM_TABLE_NAME) = (T.SYSTEM_TABLE_SCHEMA, T.SYSTEM_TABLE_NAME) and TABLE_TYPE = 'T' where C.SYSTEM_TABLE_SCHEMA = 'DB2SAMPLE' and (ucase(COLUMN_HEADING) like '%JOB%') order by C.SYSTEM_TABLE_NAME, SYSTEM_COLUMN_NAME;
- riepilogo regole di integrità referenziale di una libreria
select CST.TABLE_NAME, CST.CONSTRAINT_NAME, CST.CONSTRAINT_TYPE, CST.CONSTRAINT_KEYS as "Key number", CST.CONSTRAINT_STATE as "State", CST.ENABLED, CST.CHECK_PENDING, CST.CONSTRAINT_TEXT, COL.COLUMN_NAME, REF.UNIQUE_CONSTRAINT_NAME as "Parent", REF.UPDATE_RULE, REF.DELETE_RULE from SYSCST as CST left join SYSREFCST as REF on CST.CONSTRAINT_SCHEMA = REF.CONSTRAINT_SCHEMA and CST.CONSTRAINT_NAME = REF.CONSTRAINT_NAME left join SYSCSTCOL as COL on CST.CONSTRAINT_SCHEMA = COL.CONSTRAINT_SCHEMA and CST.CONSTRAINT_NAME = COL.CONSTRAINT_NAME left join SYSKEYCST as key on COL.CONSTRAINT_SCHEMA = KEY.CONSTRAINT_SCHEMA and COL.CONSTRAINT_NAME = KEY.CONSTRAINT_NAME and COL.COLUMN_NAME = KEY.COLUMN_NAME where CST.CONSTRAINT_SCHEMA = 'DB2SAMPLE' order by CST.TABLE_NAME, CST.CONSTRAINT_TYPE, CST.CONSTRAINT_NAME, KEY.ORDINAL_POSITION;
- elenco trigger su tabelle
select TRIGGER_NAME as "Nome trigger", EVENT_OBJECT_SCHEMA "Libreria", EVENT_OBJECT_TABLE as "File", ACTION_ORDER as "Sequenza", EVENT_MANIPULATION as "Evento", ACTION_TIMING as "Time", trim(TRIGGER_PROGRAM_LIBRARY) concat '/' concat trim(TRIGGER_PROGRAM_NAME) as "Programma", ENABLED as "Attivo", ALLOW_REPEATED_CHANGE as "Mod.ripetute" from SYSTRIGGER where EVENT_OBJECT_SCHEMA = 'DB2SAMPLE' order by EVENT_OBJECT_TABLE, ACTION_ORDER;
- relazione file dipendenti
with VISTEDEP (SYSTEM_VIEW_SCHEMA, SYSTEM_VIEW_NAME, LEVEL, OBJECT) as (select T1.SYSTEM_VIEW_SCHEMA, T1.SYSTEM_VIEW_NAME, 1, T1.OBJECT_NAME from SYSVIEWDEP as T1 where T1.SYSTEM_VIEW_SCHEMA = 'DB2SAMPLE' and T1.OBJECT_NAME = 'EMPLOYEE' union all select T2.SYSTEM_VIEW_SCHEMA, T2.SYSTEM_VIEW_NAME, O.LEVEL + 1, T2.OBJECT_NAME from SYSVIEWDEP as T2 join VISTEDEP as O on O.SYSTEM_VIEW_NAME = T2.OBJECT_NAME and O.SYSTEM_VIEW_SCHEMA = T2.OBJECT_SCHEMA) select distinct SYSTEM_VIEW_SCHEMA "Libreria", SYSTEM_VIEW_NAME "Dipendenza", level "Liv.", OBJECT "Oggetto" from VISTEDEP order by level desc, SYSTEM_VIEW_NAME;
Rete ▲
- reperimento informazioni configurazione TCP del client
-- TCP/IP info client (vista) select * from TCPIP_INFO; -- TCP/IP info client (procedura) select * from table(TCPIP_INFO()) as IP;
- interfacce di rete attive:
NETSTAT OPTION(*IFC)
-- TCP/IP interfacce (NETSTAT OPTION(*IFC)) select CONNECTION_TYPE, INTERNET_ADDRESS, NETWORK_ADDRESS, SUBNET_MASK, LINE_DESCRIPTION, INTERFACE_STATUS, AUTOSTART from NETSTAT_INTERFACE_INFO where INTERFACE_STATUS = 'ACTIVE' order by INTERNET_ADDRESS;
- porte TCP/IP in ascolto:
NETSTAT OPTION(*CNN)
-- NetStat (porte in ascolto) (NETSTAT OPTION(*CNN)) select CONNECTION_TYPE, LOCAL_ADDRESS, LOCAL_PORT, LOCAL_PORT_NAME, TCP_STATE, NETWORK_CONNECTION_TYPE, IDLE_TIME, BIND_USER, NUMBER_OF_ASSOCIATED_JOBS from NETSTAT_INFO where LOCAL_ADDRESS = '0.0.0.0' order by LOCAL_PORT;
- quale è l’indirizzo IP con cui IBM i si presenta in rete?
select MYIP from (values(systools.httpgetclob('https://api.ipify.org',''))) WS(MYIP);
- connessioni di rete aperte
-- NetStat (connessioni aperte) (NETSTAT OPTION(*CNN)) select CONNECTION_TYPE, REMOTE_ADDRESS, REMOTE_PORT, LOCAL_ADDRESS, LOCAL_PORT, LOCAL_PORT_NAME, TCP_STATE, IDLE_TIME, BIND_USER, BYTES_SENT_REMOTELY, BYTES_RECEIVED_LOCALLY, NUMBER_OF_ASSOCIATED_JOBS from NETSTAT_INFO where LOCAL_ADDRESS not in('0.0.0.0', '127.0.0.1') order by LOCAL_PORT, REMOTE_ADDRESS;
- connessioni di rete aperte dal client corrente
-- NetStat (connessioni aperte) (NETSTAT OPTION(*CNN)) dal client corrente select CONNECTION_TYPE, REMOTE_ADDRESS, REMOTE_PORT, LOCAL_ADDRESS, LOCAL_PORT, LOCAL_PORT_NAME, TCP_STATE, IDLE_TIME, BIND_USER, BYTES_SENT_REMOTELY, BYTES_RECEIVED_LOCALLY, NUMBER_OF_ASSOCIATED_JOBS from NETSTAT_INFO where REMOTE_ADDRESS = (select CLIENT_IP_ADDRESS from TCPIP_INFO) order by LOCAL_PORT, REMOTE_ADDRESS;
- connessioni di rete aperte dal client corrente: job info
-- NetStat: job info delle connessioni aperte dal cliente corrente select CONNECTION_TYPE, REMOTE_ADDRESS, REMOTE_PORT, LOCAL_ADDRESS, LOCAL_PORT, AUTHORIZATION_NAME as USER, JOB_NAME as JOB from NETSTAT_JOB_INFO where REMOTE_ADDRESS = (select CLIENT_IP_ADDRESS from TCPIP_INFO) and JOB_NAME is not null order by LOCAL_PORT, JOB_NAME;
- instradamenti:
NETSTAT OPTION(*RTE)
-- NetStat (instradamenti) (NETSTAT OPTION(*RTE)) select CONNECTION_TYPE, ROUTE_DESTINATION, SUBNET_MASK, NEXT_HOP, ROUTE_STATUS as ROUTE_AVAILABLE, LOCAL_BINDING_INTERFACE, LOCAL_BINDING_NETWORK_ADDRESS, LOCAL_BINDING_SUBNET_MASK, LOCAL_BINDING_LINE_DESCRIPTION, LOCAL_BINDING_VIRTUAL_LAN_ID from NETSTAT_ROUTE_INFO where ROUTE_STATUS = 'YES' order by ROUTE_DESTINATION;
Check-up sistema ▲
- riepilogo informazioni sul sistema (alcune delle informazioni restituite richiedono IBM i 7.3 TR6)
select current server as "Nome partizione", (select NUMBER_OF_PARTITIONS from table(QSYS2/SYSTEM_STATUS('NO'))) as "Num.tot.partizioni", (select HOST_NAME from sysibmadm.env_sys_info) as "Nome host", (select CONFIGURED_CPUS from sysibmadm.env_sys_info) as "CPU config.", (select CURRENT_CPU_CAPACITY from table(QSYS2/SYSTEM_STATUS('NO'))) as "CPU attive", (select CONFIGURED_MEMORY from sysibmadm.env_sys_info) as "Memoria config.", (select TOTAL_AUXILIARY_STORAGE from table(QSYS2/SYSTEM_STATUS('NO'))) as "ASP tot.", (select SYSTEM_ASP_STORAGE from table(QSYS2/SYSTEM_STATUS('NO'))) as "ASP sis.", (select cast(current_numeric_value as dec(5, 0)) from QSYS2.SYSTEM_VALUE_INFO where SYSTEM_VALUE_NAME = 'QCCSID') as "CCSID sistema", (select FW_MACHINE_TYPE_MODEL from systools/FIRMWARE_CURRENCY) as "Tipo/Modello", (select OS_NAME concat ' ' concat OS_VERSION concat '.' concat OS_RELEASE as release from sysibmadm/env_sys_info) as "Release OS", (select count(*) from SYSTOOLS/GROUP_PTF_CURRENCY where PTF_GROUP_CURRENCY = 'UPDATE AVAILABLE') as "Gruppi PTF da aggiornare", (select FW_CURRENTFIXPACK from systools/FIRMWARE_CURRENCY) as "Rel.firmware", (select FW_RECOMMENDED_UPDATE from systools/FIRMWARE_CURRENCY) as "Rel.firmware da aggiornare", (select MAXIMUM_JOBS_IN_SYSTEM from table(QSYS2/SYSTEM_STATUS('NO'))) as "Num.max.lavori", (select SERVER_IP_ADDRESS from QSYS2/TCPIP_INFO) as "Indirizzo IP", (select count(*) from QSYS2/NETSTAT_INTERFACE_INFO where INTERFACE_STATUS = 'ACTIVE' and LINE_DESCRIPTION <> '*LOOPBACK') as "Interfacce attive" from SYSIBM.SYSDUMMY1;
- informazioni generali sul sistema (versione sistema operativo, host name, numero processori, memoria RAM)
-- info ambiente select * from SYSIBMADM/ENV_SYS_INFO;
- Valori di sistema (
WRKSYSVAL
)
select SYSTEM_VALUE_NAME "Valore di sistema", coalesce(char(CURRENT_NUMERIC_VALUE), trim(CURRENT_CHARACTER_VALUE)) "Valore corrente" from SYSTEM_VALUE_INFO;
- System status (
WRKSYSSTS
/WRKSYSACT
)
select HOST_NAME "Nome sistema", TOTAL_JOBS_IN_SYSTEM "Num.lavori tot.", (MAXIMUM_JOBS_IN_SYSTEM - TOTAL_JOBS_IN_SYSTEM) "Lavori disponibili", ACTIVE_JOBS_IN_SYSTEM "Lav.attivi", INTERACTIVE_JOBS_IN_SYSTEM "Lav.interattivi", CONFIGURED_CPUS "Num.proc.", ELAPSED_CPU_USED "% CPU corrente", AVERAGE_CPU_UTILIZATION "% CPU media", MAXIMUM_CPU_UTILIZATION "% CPU max", TOTAL_AUXILIARY_STORAGE "Storage tot.", SYSTEM_ASP_USED "% storage occ.", CURRENT_TEMPORARY_STORAGE "Storage temp. corrente", MAXIMUM_TEMPORARY_STORAGE_USED "Storage temp. max", PERMANENT_ADDRESS_RATE "% ind.perm.", TEMPORARY_ADDRESS_RATE "% ind.temp.", RESTRICTED_STATE "Stato limitato" from SYSTEM_STATUS_INFO;
- Lotti di memoria (
WRKSHRPOOL
/WRKSYSSTS
)
select SYSTEM_POOL_ID "ID lotto", POOL_NAME "Lotto", DESCRIPTION "Descrizione", CURRENT_SIZE "Dim. (Mb)", RESERVED_SIZE "Dim.riserv. (Mb)", PAGING_OPTION "Opz.paging", MAXIMUM_ACTIVE_THREADS "Lav.att.max", CURRENT_THREADS "Lav.att.corrente", CURRENT_INELIGIBLE_THREADS "Lav.inel.", ELAPSED_DATABASE_FAULTS "DB err", ELAPSED_DATABASE_PAGES "DB pag.", ELAPSED_NON_DATABASE_FAULTS "Non DB err", ELAPSED_NON_DATABASE_PAGES "Non DB pag.", ELAPSED_ACTIVE_TO_WAIT "Act.->Att.", ELAPSED_WAIT_TO_INELIGIBLE "Wait inel.", ELAPSED_ACTIVE_TO_INELIGIBLE "Act.inel." from MEMORY_POOL_INFO;
- informazioni stato dischi (
WRKDSKSTS
)
select ASP_NUMBER, DISK_TYPE, DISK_MODEL, UNIT_NUMBER, dec(UNIT_STORAGE_CAPACITY/1073741824,0, 13, 2) as UNIT_STORAGE_CAPACITY_GB, dec(UNIT_SPACE_AVAILABLE/1073741824,0, 13, 2) as UNIT_SPACE_AVAILABLE_GB, PERCENT_USED, LOGICAL_MIRRORED_PAIR_STATUS, MIRRORED_UNIT_STATUS from SYSDISKSTAT;
- programmi su licenza (
WRKLICINF
): visualizza le informazioni solo dei prodotti che richiedono una licenza
select * from LICENSE_INFO order by PRODUCT_ID, FEATURE_ID;
- software installato (
DSPSFWRSC
):
call qsys2.qcmdexc('QSYS/DSPSFWRSC OUTPUT(*OUTFILE) OUTFILE(QTEMP/PROD_INFO) OUTMBR(*FIRST *REPLACE)'); select lcprdi "Prodotto", lcpfgi "Id caricamento", lcsfgi "Opzione", ltrim(lcvrsl, '0') concat (case when lcrlsl <> '00' then '.' else '' end) concat ltrim(lcrlsl, '0') concat (case when lcmodl <> '00' then '.' else '' end) concat ltrim(lcmodl, '0') "Versione", message_text "Descrizione" from qtemp.prod_info inner join qsys2.message_file_data on message_file_library = (case when lcdtml = '*LIBL' then 'QSYS' else lcdtml end) and message_file = lcdtmf and message_id = lcdtmi where LCPFGI <> '2932' -- senza dettaglio lingua installata order by LCPRDI;
- informazioni su profili utenti
select AUTHORIZATION_NAME "Utente", TEXT_DESCRIPTION "Descrizione", PREVIOUS_SIGNON "Ult.collegamento", SIGN_ON_ATTEMPTS_NOT_VALID "Coll.non validi", STATUS "Stato", PASSWORD_CHANGE_DATE "Data/Ora mod.pwd", DAYS_UNTIL_PASSWORD_EXPIRES "gg a scadenza password", SET_PASSWORD_TO_EXPIRE "Pwd a scad.", USER_CLASS_NAME "Classe", SPECIAL_AUTHORITIES "Aut.spec.", LIMIT_CAPABILITIES "Capac.lim.", GROUP_PROFILE_NAME "Profilo di gruppo", OWNER "Propr.", trim(INITIAL_MENU_LIBRARY_NAME) concat '/' concat trim(INITIAL_MENU_NAME) "Menu", trim(INITIAL_PROGRAM_LIBRARY_NAME) concat '/' concat trim(INITIAL_PROGRAM_NAME) "Menu", trim(JOB_DESCRIPTION_LIBRARY_NAME) concat '/' concat trim(JOB_DESCRIPTION_NAME) "Desc.lavoro", trim(OUTPUT_QUEUE_LIBRARY_NAME) concat '/' concat trim(OUTPUT_QUEUE_NAME) "Coda emissione", PRINT_DEVICE "Stampante", HOME_DIRECTORY "Indirizzario corrente" from USER_INFO order by AUTHORIZATION_NAME;
- informazioni lavoro corrente (stato, priorità, sottosistema, CPU e RAM utilizzata, nome del client, utente del client…)
select * from table(get_job_info('*')) as Job;
- joblog lavoro corrente (
DSPJOBLOG
)
select MESSAGE_ID, MESSAGE_TYPE, SEVERITY, MESSAGE_TIMESTAMP, MESSAGE_FILE, trim(MESSAGE_TEXT) as MESSAGE_TEXT, trim(MESSAGE_SECOND_LEVEL_TEXT) as MESSAGE_SECOND_LEVEL_TEXT from table(JOBLOG_INFO('*')) as JOBLOG order by MESSAGE_TIMESTAMP desc;
- estrazione dei soli messaggi di eccezione dalla stampa di un joblog (da 7.3 TR6). Sostituire
numero/utente/nome
con il numero, utente e nome del lavoro che contiene la stampa del joblog.
with CPF as ( select ORDINAL_POSITION, SPOOLED_DATA from table(SYSTOOLS/SPOOLED_FILE_DATA('numero/utente/nome', 'QPJOBLOG')) where substr(SPOOLED_DATA, 12, 6) = 'Uscita'), CPF_MSG as ( select ORDINAL_POSITION, SPOOLED_DATA from table(SYSTOOLS/SPOOLED_FILE_DATA('numero/utente/nome', 'QPJOBLOG')) where SPOOLED_DATA not like '%Visual. registrazione lavoro%' and SPOOLED_DATA not like '%Nome lavoro . . . . . . . . :%' and SPOOLED_DATA not like '%Descrizione lavoro . . . . . :%' and SPOOLED_DATA not like '%IDMSG TIPO%') select substr(CPF.SPOOLED_DATA, 41, 8) "Data", substr(CPF.SPOOLED_DATA, 51, 8) "Ora", substr(CPF.SPOOLED_DATA, 1, 7) "ID MSG", substr(CPF.SPOOLED_DATA, 36, 2) "Gravità", trim(substr(CPF.SPOOLED_DATA, 114, 10)) concat '/' concat trim(substr(CPF.SPOOLED_DATA, 102, 10)) "Programma", substr(SP.SPOOLED_DATA, posstr(SP.SPOOLED_DATA, '. . . :') + 10) "Messaggio" from CPF inner join CPF_MSG as SP on CPF.ORDINAL_POSITION = SP.ORDINAL_POSITION - 1 order by CPF.ORDINAL_POSITION;
- lista librerie, current schema e current path del lavoro corrente
select 'LL' as "Gruppo", ORDINAL_POSITION as "Pos.", SYSTEM_SCHEMA_NAME "Lib.", TYPE as "Tipo", TEXT_DESCRIPTION as "Descrizione" from LIBRARY_LIST_INFO union all select 'CS', 0, CURRENT SCHEMA as "CurLib", 'CURRENT', ' ' from SYSDUMMY1 union all select 'CP', 0, CURRENT PATH as "CurLib", 'PATH', ' ' from SYSDUMMY1 order by 1, 2;
- elenco lavori in errore (stato MSGW)
select SUBSYSTEM "Sottosistema", JOB_NAME "Lavoro", AUTHORIZATION_NAME "Utente", JOB_TYPE "Tipo lavoro", FUNCTION_TYPE "Tipo funzione", FUNCTION "Funzione", CPU_TIME "Tempo ut.CPU", TOTAL_DISK_IO_COUNT "Tot. I/O" from TABLE(ACTIVE_JOB_INFO('NO', -- reset statistics '', -- subsystem filter '', -- job name filter (* current, *ALL tutti, *CURRENT tutti i lavori con nome uguale al corrente, *SBS all active subsystems, *SYS all active system jobs) '' -- current user filter (comma delimited list) )) ACT_JOBS where JOB_STATUS = 'MSGW' order by SUBSYSTEM, JOB_NAME;
- info lavori schedulati (
WRKJOBSCDE
)
select SCHEDULED_JOB_NAME, STATUS, SCHEDULED_TIME, SCHEDULED_DATE, SCHEDULED_DAYS, FREQUENCY, RELATIVE_DAYS_OF_MONTH, DATES_OMITTED, NEXT_SUBMISSION_DATE, DESCRIPTION, COMMAND_STRING, USER_PROFILE_FOR_SUBMITTED_JOB, JOB_DESCRIPTION_LIBRARY_NAME concat '/' concat JOB_DESCRIPTION_NAME as JOB_DESCRIPTION, JOB_QUEUE_LIBRARY_NAME concat '/' concat JOB_QUEUE_NAME as JOB_QUEUE, LAST_SUCCESSFUL_SUBMISSION_JOB, LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP from SCHEDULED_JOB_INFO order by SCHEDULED_JOB_NAME;
- info lavori schedulati con ora inizio e fine dell’ultima immissione e calcolo della durata del tempo di esecuzione (N.B. questa query può richiedere anche parecchio tempo se si selezionano molti record. Circa 1 minuto per ogni record)
select SCHEDULED_JOB_NAME, STATUS, SCHEDULED_TIME, SCHEDULED_DATE, SCHEDULED_DAYS, FREQUENCY, RELATIVE_DAYS_OF_MONTH, DATES_OMITTED, NEXT_SUBMISSION_DATE, DESCRIPTION, COMMAND_STRING, USER_PROFILE_FOR_SUBMITTED_JOB, JOB_DESCRIPTION_LIBRARY_NAME concat '/' concat JOB_DESCRIPTION_NAME as JOB_DESCRIPTION, JOB_QUEUE_LIBRARY_NAME concat '/' concat JOB_QUEUE_NAME as JOB_QUEUE, LAST_SUCCESSFUL_SUBMISSION_JOB, LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP, case when LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP is null then null else (select timestamp(MESSAGE_TIMESTAMP, 0) from table(HISTORY_LOG_INFO(LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP, timestamp(LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP) + 24 hours)) as HL where FROM_JOB = LAST_SUCCESSFUL_SUBMISSION_JOB and MESSAGE_ID = 'CPF1164') end as LAST_SUCCESSFUL_SUBMISSION_END, case when LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP is null then null else round(timestampdiff(4, char((select MESSAGE_TIMESTAMP from table(HISTORY_LOG_INFO(LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP, timestamp(LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP) + 24 hours)) as HL where FROM_JOB = LAST_SUCCESSFUL_SUBMISSION_JOB and MESSAGE_ID = 'CPF1164') - LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP))/60,0, 2) end as DURATA_HH, case when LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP is null then null else timestampdiff(4, char((select MESSAGE_TIMESTAMP from table(HISTORY_LOG_INFO(LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP, timestamp(LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP) + 24 hours)) as HL where FROM_JOB = LAST_SUCCESSFUL_SUBMISSION_JOB and MESSAGE_ID = 'CPF1164') - LAST_SUCCESSFUL_SUBMISSION_TIMESTAMP)) end as DURATA_MM from SCHEDULED_JOB_INFO where STATUS = 'SCHEDULED' -- solo schedulati order by SCHEDULED_JOB_NAME;
- elenco di risposte del sistema (
WRKRPYLE
)
select * from REPLY_LIST_INFO;
- informazioni su allocazione di un oggetto
select MEMBER_LOCK_TYPE, LOCK_STATE, LOCK_STATUS, LOCK_SCOPE, JOB_NAME from table(OBJECT_LOCK_INFO('DB2SAMPLE', 'EMPLOYEE', '*FILE', 0)) as OBJECT_LOCK;
- informazioni su allocazione di un gruppo di oggetti (ATTENZIONE: può richiedere parecchio tempo, è preferibile utilizzare la function table su un singolo oggetto)
select SYSTEM_OBJECT_NAME "Oggetto", MEMBER_LOCK_TYPE, LOCK_STATE, LOCK_STATUS, LOCK_SCOPE, JOB_NAME from OBJECT_LOCK_INFO where OBJECT_SCHEMA = 'DB2SAMPLE' and SQL_OBJECT_TYPE = 'TABLE';
- lista spool file per utente (da 7.1)
select * from OUTPUT_QUEUE_ENTRIES where USER_NAME = 'QSYSOPR';
IPL
Informazioni sull’ultimo spegnimento e accensione del sistema:
PTF sistema operativo ▲
- stato installazione PTF (
WRKPTFGRP
)
select PTF_GROUP_NAME, PTF_GROUP_DESCRIPTION, PTF_GROUP_LEVEL, PTF_GROUP_STATUS from GROUP_PTF_INFO order by PTF_GROUP_NAME, PTF_GROUP_LEVEL desc;
- cumulativo più recente installato
select max(PTF_GROUP_LEVEL) as "Most recently install CUM" from GROUP_PTF_INFO where PTF_GROUP_DESCRIPTION like 'CUMULATIVE PTF PACKAGE%' and PTF_GROUP_STATUS = 'INSTALLED';
- stato installazione PTF e disponibilità aggiornamenti da installare da sito IBM
select * from SYSTOOLS/GROUP_PTF_CURRENCY order by PTF_GROUP_CURRENCY desc, PTF_GROUP_ID;
- dettaglio PTF installate (
DSPPTF
)
select PTF_GROUP_NAME "Gruppo", trim(PTF_GROUP_DESCRIPTION) "Descrizione", PTF_PRODUCT_ID "Prodotto", trim(PTF_PRODUCT_DESCRIPTION) "Descrizione prodotto", PTF_IDENTIFIER "PTF ID", PTF_STATUS "Stato inst.", PTF_LOADED_STATUS "Stato", varchar_format(PTF_STATUS_TIMESTAMP, 'DD/MM/IYYY') "Data stato", PTF_ACTION_PENDING "In attesa", PTF_ACTION_REQUIRED "Az.richiesta", PTF_IPL_ACTION "Az.IPL", PTF_IPL_REQUIRED "Rich.IPL", APAR_NAME "APAR", PTF_INCLUDED_IN_GROUP_DATE "Incluso in gruppo", PTF_CUM_PACKAGE "Incluso in cumulativo", PTF_IS_RELEASED "Rilasciata", PTF_SUPERCEDED_BY_PTF "Superata da", varchar_format(PTF_CREATION_TIMESTAMP, 'DD/MM/IYYY') "Data creaz." from SYSTOOLS/GROUP_PTF_DETAILS where PTF_STATUS <> 'PTF MISSING' order by PTF_GROUP_NAME, PTF_IDENTIFIER;
- dettaglio PTF in attesa di un’azione
select PTF_GROUP_NAME "Gruppo", trim(PTF_GROUP_DESCRIPTION) "Descrizione", PTF_PRODUCT_ID "Prodotto", trim(PTF_PRODUCT_DESCRIPTION) "Descrizione prodotto", PTF_IDENTIFIER "PTF ID", PTF_STATUS "Stato inst.", PTF_LOADED_STATUS "Stato", varchar_format(PTF_STATUS_TIMESTAMP, 'DD/MM/IYYY') "Data stato", PTF_ACTION_PENDING "In attesa", PTF_ACTION_REQUIRED "Az.richiesta", PTF_IPL_ACTION "Az.IPL", PTF_IPL_REQUIRED "Rich.IPL", APAR_NAME "APAR", PTF_INCLUDED_IN_GROUP_DATE "Incluso in gruppo", PTF_CUM_PACKAGE "Incluso in cumulativo", PTF_IS_RELEASED "Rilasciata", PTF_SUPERCEDED_BY_PTF "Superata da", varchar_format(PTF_CREATION_TIMESTAMP, 'DD/MM/IYYY') "Data creaz." from SYSTOOLS/GROUP_PTF_DETAILS where PTF_STATUS <> 'PTF MISSING' and (PTF_ACTION_PENDING <> 'NO' or PTF_ACTION_REQUIRED not in('NONE', 'IPL') or PTF_IPL_ACTION <> 'NONE') order by PTF_GROUP_NAME, PTF_IDENTIFIER;
Altre istruzioni sono disponibili in https://gist.github.com/mk1tools/83a01cd4044909ca2c99f31ca304e80b.
Grafici ▲
Per quanto inusuale potrebbe a volte tornare comodo rappresentare un campo numerico in forma grafica.
- grafico a lunghezza imprevedibile
select EMPNO, SALARY, repeat('*', int(SALARY/1000)) as Grafico from EMPLOYEE where SALARY <> 0 order by EMPNO;
- grafico a lunghezza massima fissa (da V5R4)
with temp1 (EMPNO, SALARY) as (select EMPNO, SALARY from EMPLOYEE where SALARY <> 0), temp2 (MaxSalary) as (select int(max(SALARY))/25 -- 25 è la lunghezza massima del campo grafico from EMPLOYEE where SALARY <> 0) select EMPNO, SALARY, repeat('*', int(SALARY/MaxSalary)) as Grafico from temp1, temp2 order by SALARY desc;
Bibliografia ▲
- DB2 for i Service: https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/IBM%20i%20Technology%20Updates/page/DB2%20for%20i%20-%20Services
- DB2 for i Service view: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqtableservices_info.htm
- Funzione generate_unique(): https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/db2/rbafzscagenerateunique.htm
- Procedura qcmdexc: https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_73/rzajq/rzajqprocqcmdexc.htm
- Putting multiple SQL Selects together to make one row, di Simon Hutchinson, 9-ott-2019, https://www.rpgpgm.com/2019/10/putting-multiple-sql-selects-together.html
- Display software resources, di Scott Forstie, 28-set-2019, https://gist.github.com/forstie/51592c752310843a96eecc2475d68dab
- Gestione del sistema IBM i: FAQ e Howto, 3-ago-2019, di Roberto De Pedrini, https://blog.faq400.com/system-administration/ibmi-system-admin-faq-and-howto/
- Come leggere i file di spool con l’SQL, di Massimo Duca, 13-ott-2019, https://blog.faq400.com/programmazione/varie-programmazione-ibm-i/leggere-spool-file-con-sql/