Return just the results from %SYS.ProcessQuery using $SYSTEM.SQL.Shell() in Intersystems Caché on a Unix server

578 views Asked by At

Background

Hi,

I work with a Unix-based application that uses an Intersystems Caché database. Since I'm not that familiar with Caché, it wasn't until recently that I found out I could type...

$ cache

...to enter the database. From here, I found out I could access a number of things like the %FREECNT report, the ^DATABASE routine (to view/modify the size and other properties of the database), and $SYSTEM.SQL.Shell().

Since I found the $SYSTEM.SQL.Shell(), I've found a number of things I can use it for to obtain info about the database, specifically running processes using the %SYS.ProcessQuery table.

I'm able to run queries successfully - for example:

USER>ZN "%SYS"
%SYS>D $SYSTEM.SQL.Shell()
SQL Command Line Shell             #Comment - Sql Shell Intro text
--------------------------------
Enter q to quit, ? for help.
%SYS>Select PID As Process_ID, State As Process_Status From %SYS.ProcessQuery

The above query will return results in this format:

Process_ID        Process_State
--------------------------------
528352            READ
2943582           HANG
707023            RUN

3 Rows(s) Affected
--------------------------------

Question

Considering the background identified above, I'm looking for a way to return just the results without the "SQL Command Line Shell" intro text, the column names, or the row count footer. When I write a .ksh script in Unix to connect to Caché and run a query, like above, I return the results, along with the following text that I don't want included:

SQL Command Line Shell
--------------------------------
Enter q to quit, ? for help.

Process_ID        Process_State
--------------------------------

3 Rows(s) Affected
--------------------------------

Additional Info

I realize I could use Unix commands to filter out some of the text using awk and sed, but I'm looking for something a little easier/cleaner way that might be built-in. Maybe something that has a silent or no_column_names flag, like the example in this LINK.

My end game is to have a script run that will obtain info from a query, then use that info to make changes to the database when certain thresholds are met. Ultimately, I want to schedule the script to run at regular intervals, so I need all the processing to occur on the server instead of creating a separate Client app that binds to the database.

2

There are 2 answers

6
Brandon Horst On

You want to create a Cache Routine for this. You can do this in Cache Studio. http://docs.intersystems.com/ens20131/csp/docbook/DocBook.UI.Page.cls?KEY=GSTD_Routines

In the Routine, you want to use either Embedded SQL or Dynamic SQL to run the query, and iterate through the results, and print them using WRITE. I would recommend Dynamic SQL, as it will be more flexible in the future.

Introduction to SQL: http://docs.intersystems.com/ens20131/csp/docbook/DocBook.UI.Page.cls?KEY=GSQL_intro#GSQL_intro_embeddedsql

Dynamic SQL Information: http://docs.intersystems.com/ens20131/csp/documatic/%CSP.Documatic.cls?APP=1&LIBRARY=%SYS&CLASSNAME=%SQL.Statement

Embedded SQL Information: http://docs.intersystems.com/ens20131/csp/docbook/DocBook.UI.Page.cls?KEY=GSQL_esql

0
chandru On

You can create duplicate class of %SQL.Shell in your own namespace and you can edit it..If you want as Rountine means you can call this method ...%Go() from your routine.