Try this example

See Defining Custom Class Queries

 
Example of a stored procedure

The result of calling a stored procedure in the Management Portal:

SELECT * FROM dc.Intervals({ts '2024-01-01 10:00:00'},{ts '2024-01-01 11:00:00'},15)
Display/ODBC Mode
intStart intEnd
2024-01-01 10:00:00 2024-01-01 10:14:59.999999
2024-01-01 10:15:00 2024-01-01 10:29:59.999999
2024-01-01 10:30:00 2024-01-01 10:44:59.999999
2024-01-01 10:45:00 2024-01-01 11:00:00.000000

Logical Mode

intStart intEnd
1154625607806846976 1154625608706846975
1154625608706846976 1154625609606846975
1154625609606846976 1154625610506846975
1154625610506846976 1154625611406846976


Accordingly, your query needs to be rewritten, for example:

SELECT
intStart,
intEnd,
COALESCE((SELECT SUM(CASE WHEN value_after_changing 'GENERATE' THEN ELSE ENDFROM service_log WHERE id = 11 AND created_at BETWEEN intStart AND intEnd), 0) generatedCount,
COALESCE((SELECT SUM(CASE WHEN value_after_changing 'FINISH' THEN ELSE ENDFROM service_log WHERE id = 11 AND created_at BETWEEN intStart AND intEnd), 0) finishedCount,
COALESCE((SELECT SUM(CASE WHEN value_after_changing 'DROPOUT' THEN ELSE ENDFROM service_log WHERE id = 11 AND created_at BETWEEN intStart AND intEnd), 0) dropoutCount,
COALESCE((SELECT SUM(CASE WHEN value_after_changing 'CANCEL' THEN ELSE ENDFROM service_log WHERE id = 11 AND created_at BETWEEN intStart AND intEnd), 0) cancelledCount
FROM dc.Intervals({ts '2024-01-01 10:00:00'},{ts '2024-01-01 11:00:00'},15)

You can convert a list to a string (and vice versa), regardless of the number of nestings. Unfortunately, I can't test this code for Caché 5.x, but I think it should work.
Here is a small example of searching for a string in a list:

#include %systemInclude

 n
 
 s list=$lb(
   "test",
   "for",
   "searching unknown strings here is a very long piece with enough characters to get a lowercase alpha as a $list marker",
   "items",
   "in",
   "aaatArGetwaaaa",
   "lists",
     $lb(
     "/subs",
     "/values",
     "nested list",
     "did you see that ""w"" before the third piece?",
     "Stuart Strickland",
     "Yaron Munz")
 )
 
 str=$$$UPPER(##class(%Utility).FormatString(list,,.overflow))
 'overflow {
   ;s @("LIST="_str) zw LIST
   
   !,$f(str,$$$UPPER("Targetw"))
 }

Result: 162

The problem can be solved in two ways:

  1. use OPTIONS="popup,sortbox"
  2. make a correction to the %CSP.PageLookup
    Write "&nbsp;<a href=""javascript:searchSort("_..QuoteJS(value)_");"" title=""Sort Results by "_alias_""">"
    |
    V
    Write "&nbsp;<a href=""javascript:searchSort("_i_");"" title=""Sort Results by "_alias_""">"

In both case, the query will take the form "ORDER BY <the ordinal number of the field>", instead of "ORDER BY <field name>"

One of the possible options:

ClassMethod odbcTest() As %Integer ReturnResultsetsSqlName PersonSets2SqlProc ]
{
  #dim %sqlcontext As %ProcedureContext
  if '$isobject($Get(%sqlcontext)) set %sqlcontext ##class(%ProcedureContext).%New() } 

  tReturn = 0

  conn=##class(%SQLGatewayConnection).%New()
  sc=conn.Connect("TEST Samples","_system","SYS"//datasource
  if $$$ISOK(sc{
    conn.AllocateStatement(.h1)
    conn.Prepare(h1,"select name,dob,spouse from sample.person where name %STARTSWITH 'A'")
    conn.Execute(h1)
    %sqlcontext.AddResultSet(conn.getResultSet(h1))
    conn.AllocateStatement(.h2)
    conn.Prepare(h2,"select name,age,home_city,home_state from sample.person where home_state = 'MA'")
    conn.Execute(h2)
    %sqlcontext.AddResultSet(conn.getResultSet(h2))
    tReturn = 1
  }else{
    sqlcode=$system.Status.StatusToSQLCODE(sc,.msg)
    %sqlcontext.%SQLCODE sqlcode%sqlcontext.%Message msg
  }
  tReturn
}

Output:

SAMPLES>##class(%SQL.Statement).%ExecDirect(,"call Sample.PersonSets2()").%Display()
...

Surely there is a way to make it even easier.