· Jan 25, 2018

List of Business Services

Is there a way to get the list of Business Services from a command line call? We are trying to see if there is a way we can automate bring down our Inbound Business Services during a fail over.


Scott Roth

The Ohio State University Wexner Medical Center

Discussion (12)1
Log in or sign up to continue

SQL way (query docs, 1 means BS):

FROM Ens_Config.Production_EnumerateConfigItems('Your.Production', 1)

Object way:

set rs = ##class(Ens.Config.Production).EnumerateConfigItemsFunc("Your.Production", 1)
do rs.%Display()

Constants for Business Host Type (defined in

#define eHostTypeUnknown   0
#define eHostTypeService   1
#define eHostTypeProcess   2
#define eHostTypeOperation 3
#define eHostTypeActor     4

Hello Scott,

I was playing around with the EnumerateConfigItems query in the Ens.Config.Production class, and it seems like it might do what you're asking.  Below is some basic example code to demonstrate, but of course you should test this out yourself and add proper status checking and error handling before putting it to use.

If you are interested in other fields returned by this query, you can take a closer look at its class reference documentation.

#include Ensemble

ListBusinessServices() PUBLIC {
                Set productionName = "Demo.Loan.FindRateProduction"
                Set tStatement = ##class(%SQL.Statement).%New()
                Set pStatus = tStatement.%PrepareClassQuery("Ens.Config.Production","EnumerateConfigItems")
                Set tResult = tStatement.%Execute(productionName,$$$eHostTypeService)
                While tResult.%Next() {
                                Write !,tResult.%Get("ConfigName")


Check the following code:

Set tProduction="Demo.HL7.MsgRouter.Production"

// Types:
// Empty: Retrieve all items 
// 1: Business Service
// 2: Business Process
// 3: Business Operation

Set tType="1"

Set tRS = ##class(%ResultSet).%New("Ens.Config.Production:EnumerateConfigItems")

Set tStatus = tRS.%Execute(tProduction, tType)

While tRS.%Next(.tStatus) {

   write tRS.%Get("BusinessType")_" : "_tRS.%Get("ConfigName"),!


II hope it's useful

Best regards,

Francisco Lopez

For cross-namespace queries the easiest way is to map packages/globals but that might not be a recommended approach for an audit table.

You can do this:

  1. In your production namespace create a new table with the same structure as your audit select query backed by PPG storage.
  2. Switch to the audit namespace.
  3. Run audit query, iterate the results and write them into the PPG.
  4. Switch into a production namespace.
  5. Run query against your PPG table, joining any local tables.

%SYS.Audit already projects to each namespace, but the data is in a privileged database and requires %Admin_Secure:USE privileges, so better not try to circumvent / confuse that through mappings.

I would not create additional temp tables or mappings to try and cling to SQL as that is meant to run in a single namespace as a query language. This sounds more like a procedural thing for ObjectScript, so a stored procedure that loops through the Production namespaces, retrieves all config items in a local variable and then uses that for querying the audit table after switching to %SYS sounds more appropriate. Rather than a PPG, I'd just collect it in the qHandle local variable passed between Execute() and Fetch() methods for your custom query, unless it risks getting too big