Question Mikhail (VetsEZ) Akselrod · Mar 2

Code example to build a %Library.DynamicObject or a %Library.DynamicArray from Resultset followed by converting to JSON

Please, provide Code example to build a %Library.DynamicObject or a %Library.DynamicArray from Resultset followed by converting to JSON

Product version: IRIS 2023.1
$ZV: HealthShare Unified Care Record 2023.1.0 Build: 1006 Adhoc: 23407 [HealthShare Modules: Core:25.0] -

Comments

DC AI Bot · Mar 2 Bot

To build a %Library.DynamicObject or %Library.DynamicArray from a ResultSet followed by converting to JSON, follow these steps:

  1. Loop through the ResultSet, constructing either a %Library.DynamicObject or %Library.DynamicArray as needed.
  2. Use the %ToJSON() method to convert the constructed dynamic object or array into JSON format.

Below is an example code snippet illustrating this process:

ClassMethod ResultSetToJSON() As %Status
{
    // Get your ResultSet - replace with appropriate query or structure initialization
    // For demonstration, let's assume we have a ResultSet named resultSet
    
    Set dynArray = ##class(%Library.DynamicArray).%New()

    // Example loop to process resultSet rows
    While resultSet.%Next()
    {
        // Extract data from the ResultSet row
        Set dynObj = ##class(%Library.DynamicObject).%New()
        Do dynObj.%Set("Column1", resultSet.Column1)
        Do dynObj.%Set("Column2", resultSet.Column2)
        Do dynArray.%Push(dynObj)
    }

    // Convert to JSON string
    Write dynArray.%ToJSON()
    
    Quit $$$OK
}

In this example:

  • Data is processed row by row from resultSet.
  • A %Library.DynamicObject is created for each row, and properties are populated with column data.
  • Each dynamic object is added to a %Library.DynamicArray.
  • The %Library.DynamicArray is converted to JSON using its %ToJSON() method.

Remember, similar steps can be followed for a %Library.DynamicObject if your JSON structure requires objects instead of arrays 1.


Sources:

Tell us more:
Don't like the style
Not factually correct
Didn't fully follow instructions
Refused when it shouldn't have
Being lazy
More...
Submit
0 0

I have a ResultSet but I don't know what are column names. How to substitute it's names in the example below?

0
Enrico Parisi  Mar 2 to Mikhail (VetsEZ) Akselrod

What type of ResultSet? Can you please provide the exact class name of the ResultSet you use?

0
Vitaliy Serdtsev  Mar 5 to Mikhail (VetsEZ) Akselrod

See

Here is a small example:

Class dc.test Extends %Persistent
{

Property pClob As %Stream.GlobalCharacter;

Property pBlob As %Stream.GlobalBinary;

ClassMethod RSToDynamicArray(ByRef rs As %SQL.StatementResultAs %DynamicArray
{
  #dim metaData as %SQL.StatementMetadata rs.%GetMetadata()
  ;d metaData.%Display()
  
  i=1:1:metaData.columns.Count() {
    #dim column As %SQL.StatementColumn metaData.columns.GetAt(i)
    colInfo(i,"label") = column.label,
      colInfo(i,"ODBCType") = $$$GetOdbcTypeName(column.ODBCType)
  }
  colInfo=i
    
  arr []
  while rs.%Next() {
    row {}
    = 1:1:colInfo {
      label=colInfo(i,"label"),
        odbcType=colInfo(i,"ODBCType"),
        val rs.%GetData(i)
        
      val="" {
        row.%Set(label,"","null")
      }elseif odbcType="BIT" {
        row.%Set(label,$num(val),"boolean")
      }elseif odbcType="DATE" {
        row.%Set(label,$zd(val,3))
      }elseif (odbcType="LONGVARCHAR")||(odbcType="LONGVARBINARY"{
        row.%Set(label,##class(%Stream.Object).%Open(val),"stream")
      }elseif $IsValidNum(val{
        row.%Set(label,$num(val),"number")
      }else {
        row.%Set(label,val,"string")
      }
    }
    arr.%Push(row)
  }    
  
  arr
}

ClassMethod Test()
{
  ..%KillExtent()
  
  tmp=..%New()
  tmp.pClob.Write("Hello")
  tmp.pBlob.Write($c(0,1,7))
  tmp.%Save()
  
  sql="select 'hello' fStr" _
  ",2 fInt" _
  ",current_date fDate" _
  ",cast(1 as BIT) fBool" _
  ",null fNull" _
  ",(select top 1 pClob from dc.test) fClob" _
  ",(select top 1 pBlob from dc.test) fBlob"

  #dim rs As %SQL.StatementResult=##class(%SQL.Statement).%ExecDirect(,sql)
  ..RSToDynamicArray(.rs).%ToJSON()
}

}

Result:

USER>##class(dc.test).Test()
[{"fStr":"hello","fInt":2,"fDate":"2026-03-05","fBool":true,"fNull":null,"fClob":"Hello","fBlob":"\u0000\u0001\u0007"}]

PS: By the way, in version 2016.3, this could be done much more easily:

write rs.$compose("%Array").$toJSON()

Unfortunately, I have not found a way to replicate this code in version 2025.3

0
Mikhail (VetsEZ) Akselrod  Mar 6 to Vitaliy Serdtsev

Thank you. Is there any "similar" utility to convert JSON back into ResultSet? 

0
Mikhail (VetsEZ) Akselrod  Mar 6 to Enrico Parisi

Thank you. Is there any "similar" utility to convert JSON back into ResultSet? 

0
Mikhail (VetsEZ) Akselrod  Mar 11 to Robert Cemper

Sorry - I didn't find a code correlated to my  question. 

I am looking for code EXAMPLE to convert JSON string into ResultSet (%SQL.StatementResult).

Thank you

0
David Hockenbroch  Mar 11 to Mikhail (VetsEZ) Akselrod

I'm just curious why you would want to convert from JSON to a result set? Everything I could think of that would make you want to do that would be better served by using a %Library.DynamicArray.

0
Mikhail (VetsEZ) Akselrod  Mar 11 to David Hockenbroch

Per ISC documentation (don't remember correlated section), query ResultSet (%SQL.StatementResult) , executed in one namespace, can not be directly viewed/parsed in a different namespace. Upon ZN to the original namespace, ResultSet is empty.

I am trying to resolve it, by the following steps:

  1. ZN form original namespace (ONS) to execution namespace (ENS)
  2. Execute query in ENS and get ResultSet 
  3. While in ENS, convert ResultSet to JSON
  4. ZN to ONS.
  5. JSON is still valid and not empty
  6. While in the original ONS, convert JSON to ResultSet to use it.

 Steps 1 - 5 are done and tested. 

I am looking for a code (step 6) to convert JSON to ResultSet.

Did I select a wrong approach?

Thank you

0
Robert Cemper  Mar 11 to Mikhail (VetsEZ) Akselrod

Once upon a time, there was no JSON support!
But your challenge could be resolved by these steps:

  1. ZN form original namespace (ONS) to execution namespace (ENS)
  2. Execute query in ENS and get ResultSet 
  3. While in ENS, let %Display print the Resultset into SPOOL
  4. ZN to ONS.
  5. Loop over the spooled ResultSet to get your data line by line

A simplified example:

USER>ZN "SAMPLES"
SAMPLES>set sql="SELECT top 5 name, ssn from sample.employee"
SAMPLES>set sta=##class(%SQL.Statement).%New()
SAMPLES>write sta.%Prepare(.sql)
1
SAMPLES>set res=sta.%Execute()
SAMPLES>kill ^SPOOL($j)
SAMPLES>open 2:$JOB
SAMPLES>use 2 do res.%Display()
SAMPLES>close 2
SAMPLES>ZN "USER"

USER>Zwrite ^|"SAMPLES"|SPOOL($JOB)
^|"SAMPLES"|SPOOL(13488,1)="Name"_$c(9)_"SSN"_$c(13,10)
^|"SAMPLES"|SPOOL(13488,2)="Emerson,Xavier O."_$c(9)_"217-28-9642"_$c(13,10)
^|"SAMPLES"|SPOOL(13488,3)="Malkovich,Bob V."_$c(9)_"226-71-5540"_$c(13,10)
^|"SAMPLES"|SPOOL(13488,4)="Joyce,Juanita V."_$c(9)_"396-77-7486"_$c(13,10)
^|"SAMPLES"|SPOOL(13488,5)="Ingleman,Josephine Q."_$c(9)_"558-18-5848"_$c(13,10)
^|"SAMPLES"|SPOOL(13488,6)="Page,Valery R."_$c(9)_"943-90-5082"_$c(13,10)
^|"SAMPLES"|SPOOL(13488,7)=$c(13,10)
^|"SAMPLES"|SPOOL(13488,8)="5 Rows(s) Affected"
^|"SAMPLES"|SPOOL(13488,2147483647)="{67640,77930{9{"
 
USER> 

The content here is:

Name    SSN
Emerson,Xavier O.       217-28-9642
Malkovich,Bob V.        226-71-5540
Joyce,Juanita V.        396-77-7486
Ingleman,Josephine Q.   558-18-5848
Page,Valery R.  943-90-5082
5 Rows(s) Affected
Now you can loop over your result as on any other Global
as you need

0
David Hockenbroch  Mar 11 to Mikhail (VetsEZ) Akselrod

You could do as Robert said, or you could create an SQL gateway connection to the execution namespace and query it from the original namespace.

0
Evgeny Shvarov  Mar 12 to Mikhail (VetsEZ) Akselrod

It's not a matter of ResultSet availability in another namespace; it's a matter of the data you have access to in one namespace and not in another. 

if you need the access to data that is available in namespace A to namespace B, there are many ways to make it work:

  1. map the data for namespace B  via global mappings and run the query and work with the ResultSet in namespace B directly.
  2. Parse the resultset in namespace A, put all the results into a global that is visible in namespace B via extended syntax Access the global in namespace B directly.
  3. Put the results into a file on a disc or %Stream and work with them in namespace B.
  4. any other way that is more suitable to your task. 

But reconstructing the ResultSet, which is just an object in memory suitable to access the data that is still in Namespace A, I wouldn't follow the idea.

0
Mikhail (VetsEZ) Akselrod  Mar 12 to Evgeny Shvarov

Thank you @Evgeny Shvarov. Transferring result from namespace A to namespace B is not a single action to handle. It is an application-wide utility to allow query execution in one namespace and handling a result in another for new and ALREADY exist queries. So, options 2,3,4 above can not be implemented.

But option 1 seems promising if it could be done programmatically. Please, provide code example to TEMPORARILY "map the data for namespace B  via global mappings.." and kill such mapping upon getting a result. Thank you.

0
Robert Cemper  Mar 12 to Evgeny Shvarov

Hi @Evgeny Shvarov 
I created a mix from #1 and #2 without global mapping.
Temporary tables are excellent for this challenge 
as they drop at the end of the process. No clean-up needed !
It's kind of a Snapshot
 

0
Robert Cemper  Mar 12 to Mikhail (VetsEZ) Akselrod

A totally different approach, excluding JSON, pure SQL

  1. create temporary table
  2. Insert your result
  3. consume it within the same process
  4. eventually drop the table definition for a different query

I use the same query for my small code example

SELECT TOP 5 ssn, home_state,name from Sample.employee

USER>
USER>ZN "SAMPLES"

SAMPLES>:sql
SQL Command Line Shell
-----------------------------
[SQL]SAMPLES>>  << entering multiline statement
       1>>CREATE GLOBAL TEMPORARY TABLE %ZZ.resultset as
       2>>SELECT TOP 5 ssn, home_state,name from Sample.employee
       3>>go
       
17.    CREATE GLOBAL TEMPORARY TABLE %ZZ.resultset as
       SELECT TOP 5 ssn, home_state,name from Sample.employee
5 Rows Affected
[SQL]SAMPLES>>quit

SAMPLES>zn "USER"
USER>:sql
SQL Command Line Shell
-----------------------------
[SQL]USER>>SELECT * from %ZZ.resultset
18.     SELECT * from %ZZ.resultset

| SSN | Home_State | Name |
| -- | -- | -- |
| 217-28-9642 | NC | Emerson,Xavier O. |
| 226-71-5540 | CO | Malkovich,Bob V. |
| 396-77-7486 | UT | Joyce,Juanita V. |
| 558-18-5848 | IA | Ingleman,Josephine Q. |
| 943-90-5082 | TN | Page,Valery R. |

5 Rows(s) Affected

Now it's all in your hands
Eventually run DROP TABLE %ZZ.resultset
before next use with different columns.
Or just use different temp table for repeated use with other SELECT

0
Mikhail (VetsEZ) Akselrod  Mar 12 to Robert Cemper
Does the statement CREATE GLOBAL TEMPORARY TABLE %ZZ.resultset imply that the table will be accessible from any namespace?
0
Robert Cemper  Mar 12 to Mikhail (VetsEZ) Akselrod

YES Sir!

  • Process private globals live in IRISTEMP and are strictly bound to the process and its lifetime.
  • The package with %ZZ.* makes sure it is visible from ALL namespaces
  • At process start it is always empty
    • you fill it implicitely by CREATE at definiftion time
    • or if reused by 
      INSERT INTO %ZZ.resultset SELECT .......
    • this SELECT must be the same as in CREATE ...
      to  fit  column names
  • Either CREATE once + INSERT later works
  • Or DROP TABLE %ZZ..... and fresh CREATE ...
  • It's a matter of taste, I tried both

Warning: 
Test from MGMT Portal (SQL) doesn't work as the process 
(and its ID) in background changes. The process stops and the content is gone.

IF your table must survive several processes, you need some 
other tricky solution based on the same basic idea of %ZZ*
combined with a manually tuned Class definition.

0
Robert Cemper  Mar 12 to Robert Cemper

A very dirty hack:  possible not really a recommendation

IF Source table is not mapped to ONS

  1. copy class definition including <Storage> from ENS to ONS
  2. in <STORAGE> you see
  3. <DataLocation>^Sample.EmployeeD</DataLocation>
    <IdLocation>^Sample.EmployeeD</IdLocation>
    <IndexLocation>^Sample.EmployeeI</IndexLocation>
    <StreamLocation>^Sample.EmployeeS</StreamLocation> 
  4. Now replace all  ^  by ^|"ENS"|  looks similar 
    For my example, it's ^|"SAMPLES"|
  5. <DataLocation>^|"SAMPLES"|Sample.EmployeeD</DataLocation>
    <IdLocation>^"|SAMPLES"|Sample.EmployeeD</IdLocation>
    <IndexLocation>^|"SAMPLES"|Sample.EmployeeI</IndexLocation>
    <StreamLocation>^|"SAMPLES"|Sample.EmployeeS</StreamLocation> 
  6. Extended Global references allow access to the other namespace. Nothing new, but risky
0
Mikhail (VetsEZ) Akselrod  Mar 17 to Robert Cemper

@Robert Cemper 

Thank you—this looks promising. However, when I attempt to reproduce it in Caché ObjectScript, I’m running into syntax errors. Could you please provide a complete ObjectScript example that implements all the steps described above? Thank you.

0
Robert Cemper  Mar 17 to Mikhail (VetsEZ) Akselrod

I fail to understand your question.

For the %ZZ*case it is all SQL.  no Objectscript involved
as you see in this reply
 

The dirty hack is based on editing a copy of the class you want to query
as described in my other reply.
For a description of extended global reference syntax, see Extended Global References.
 

0
Mikhail (VetsEZ) Akselrod  Mar 18 to Robert Cemper

@Robert Cemper I understand about extended global reference - it is not an issue. 

I have issue to execute "..CREATE GLOBAL TEMPORARY TABLE %ZZ.resultset.." related steps from QobjectScript. 

Creating a temp (%ZZ..)  table, following by it's population and finally dropping it (as you described in your post) must be done programmatically from ObjectScript. 

Thank you for guidance.

0
Robert Cemper  Mar 18 to Mikhail (VetsEZ) Akselrod

I composed a variant that doesn't require any code in ENS.
It can all run from your ONS namespace.
All you need is a valid SQL SELECT statement
First, the utility class:

Class User.ZZ [ Abstract ]
 {

ClassMethod Export(nspace = "", query = "") As %Integer
{
	new $namespace
	zn:$l(nspace) nspace
	&SQL(DROP TABLE %ZZ.resultset)
	; default just for demo
		set:'$l(query) query="SELECT TOP 5 ssn, home_state,name from Sample.employee"

    ;
	set sql=2,
		sql(1)="CREATE GLOBAL TEMPORARY TABLE %ZZ.resultset as ",
		sql(2)=query
	set statement=##class(%SQL.Statement).%New()
	set result=statement.%ExecDirect(.statement,.sql)
	quit result.%SQLCODE
} }

a quick demo:

USER>set select="SELECT TOP 3 home_state,name,SSN from Sample.employee"
USER>w ##class(ZZ).Export("SAMPLES",select)
0
USER>:sql
SQL Command Line Shell
----------------------------------------------------
[SQL]USER>>select * from %ZZ.resultset
5.      select * from %ZZ.resultset 
| Home_State | Name | SSN |
| -- | -- | -- |
| NC | Emerson,Xavier O. | 217-28-9642 |
| CO | Malkovich,Bob V. | 226-71-5540 |
| UT | Joyce,Juanita V. | 396-77-7486 |
 
3 Rows(s) Affected
statement prepare time(s)/globals/cmds/disk: 0.0579s/39,198/181,087/0ms
 execute time(s)/globals/cmds/disk: 0.0002s/4/815/0ms
 query class: %sqlcq.USER.cls73
----------------------------------------------------------

[SQL]USER>>cos ZN "SAMPLES"
[SQL]SAMPLES>>select * from %ZZ.resultset
6.      select * from %ZZ.resultset

| Home_State | Name | SSN |
| -- | -- | -- |
| NC | Emerson,Xavier O. | 217-28-9642 |
| CO | Malkovich,Bob V. | 226-71-5540 |
| UT | Joyce,Juanita V. | 396-77-7486 |
 
3 Rows(s) Affected
statement prepare time(s)/globals/cmds/disk: 0.0552s/39,198/181,087/0ms
 execute time(s)/globals/cmds/disk: 0.0002s/4/815/0ms
 query class: %sqlcq.SAMPLES.cls92
--------------------------------------------------
[SQL]SAMPLES>>q
 
SAMPLES>

hope this helps:
The temporary table is visible from both namespaces
And the utiltiy is not tied to a specific query or table
All just runs and exists in your process.
Also no traces in the Journal 
 

0
Mikhail (VetsEZ) Akselrod  Mar 20 to Robert Cemper

@Robert Cemper 

What am I missing? Thank you

=======

ClassMethod SelectNS

{

ZN "HSACCESS"
&SQL(DROP TABLE %ZZ.resultset
Set sql=2,
sql(1)="CREATE GLOBAL TEMPORARY TABLE %ZZ.resultset as ",
sql(2) ="SELECT * FROM Ens.MessageHeader"
Set statement=##class(%SQL.Statement).%New()
Set result=statement.%ExecDirect(.statement,.sql)
Set = result.%SQLCODE // a = 0 
ZN "HSCUSTOM"
// Attempt to verify via MP>"HSACCESS">SQL:
// SELECT * FROM Ens.MessageHeader  > Row count: 8..
// SELECT * FROM %ZZ.resultset  > Row count: 0 ...
// Pay attention that there is NO error "Table '%ZZ.RESULTSET' not found"
// Attempt to verify via MP>"HCUSTOM">SQL:
// SELECT * FROM %ZZ.resultset  > Row count: 0 ...
// Pay attention that there is NO error "Table '%ZZ.RESULTSET' not found"

}

0
Robert Cemper  Mar 20 to Mikhail (VetsEZ) Akselrod
  • This example is using a TEMPORARY Table based on Process Private Globals.
  • You can access the content of the table just from the process that created the table. 
    Not from any other process.
  • From SMP you see the Table Definition from any Namespace because ot the %ZZ. package.
    so the table is FOUND but EMPTY
  • Though your SELECT from SMP runs in a totally different process with anything but your Process Private Global
  • You have to get your final SELECT and generating your temporary table into the same Process,
  • To achieve this in SMP, declare your ClassMethod As SqlProcedure like this:

    ClassMethod Export(nspace = "", query As %String = "") As %Integer [ SqlName = ZZEXPORT, SqlProc ]
    {
    	new $namespace
    	;; and so on
  • Then you can run it from SMP using this SQLprocedure as Static WHERE condition.

    SELECT * from %ZZ.resultset
    WHERE ZZEXPORT('SAMPLES',
    'SELECT TOP 5 Description, ErrorStatus, Priority from ENS.MessageHeader')=0
  • For Static WHERE Conditions see my article just 6 years back.
  • Using a TEMPORARY table avoids problems if running in more than 1 instance in parallel. 

    Sorry, 
    The new Editor is not so well-suited for long line replies. I dislike it.

0
Mikhail (VetsEZ) Akselrod  Mar 24 to Robert Cemper

@Robert Cemper While all steps are verified, I am failing to use a variable table name in  &SQL(DROP..

Set tStamp = $REPLACE($ZTIME($PIECE($HOROLOG,",",2),1),":","") // in hhmmss format
Set tTable = "%ZZ.resultset"_ tStamp

// Note tTable works for "CREATE GLOBAL TEMPORARY TABLE "_tTable_" as " as well as in SELECT * FROM "_tTable

//Failure
&SQL(DROP TABLE tTable)

Can variable be used in such content? Am I missing something? Thank you

0
Robert Cemper  Mar 24 to Mikhail (VetsEZ) Akselrod

Embedded SQL  &SQL(.-.-.-)
doesn't allow variables for Table names.
You should use %SQL.Statement instead
 

Set tTable = "%ZZ.resultset"_ tStamp
set sql=1
set sql(1)="DROP TAQBLE "_tTable
set statement=##class(%SQL.Statement).%New()
set result=statement.%ExecDirect(.statement,.sql) 
write  result.%SQLCODE
0
Vitaliy Serdtsev  Mar 23 to Mikhail (VetsEZ) Akselrod

From the description of your task, it will be easier to use the %ScrollableResultSet class.

Here is a small example:

try{
  n $namespace
  s $namespace="ENS"
  rs=##class(%ScrollableResultSet).%New()
  rs.Prepare("query in ENS")
  rs.Execute()
  rs.%Save()
  rsId=rs.%Id()
  "rsId=",rsId,!
  rs

  s $namespace="ONS"
  
  rs=##class(%ScrollableResultSet).%OpenId(rsId)
  while rs.Next() {
    rs.Data("your data"),!
  }
}catch(ex){
}
0
Mikhail (VetsEZ) Akselrod  Mar 30 to Vitaliy Serdtsev

@Vitaliy Serdtsev  Thank you. I still need a bit more clarification.
• In which namespace is ^IRIS.TempRSet located?
• Am I correct in assuming that this mechanism relies on Process Private Globals (similar to Robert’s option)? If not, how can I view the global values in the SMP?
• Does each “rs” value get stored directly in ^IRIS.TempRSet, or does each "rs" data have its own node within ^IRIS.TempRSet? If it saved in separate node, how a name for such a node can be determine?
• Are the stored data/nodes removed automatically, or do they require a manual KILL operation?

0
Vitaliy Serdtsev  Mar 31 to Robert Cemper

Merge ^|"ONS"|IRIS.TempRSet=^|"ENS"|IRIS.TempRSet

Why do this if ^IRIS.Temp* is accessible from any namespace?

0
Robert Cemper  Mar 31 to Vitaliy Serdtsev

Thanks for the enlightenment. 
That has never passed my ways 

0
Vitaliy Serdtsev  Mar 31 to Mikhail (VetsEZ) Akselrod

Did you open the documentation links I provided above?

In which namespace is ^IRIS.TempRSet located?

System Use of IRISTEMP

These globals are automatically mapped to IRISTEMP and include:

  • ^IRIS.Temp*
  • ^CacheTemp*
  • ^mtemp*

Am I correct in assuming that this mechanism relies on Process Private Globals (similar to Robert’s option)?

No.

If not, how can I view the global values in the SMP?

Using the Globals Page

Does each “rs” value get stored directly in ^IRIS.TempRSet, or does each "rs" data have its own node within ^IRIS.TempRSet? If it saved in separate node, how a name for such a node can be determine?

USER>zwrite ^IRIS.TempRSet
^IRIS.TempRSet=counter
^IRIS.TempRSet(rsId)=...
^IRIS.TempRSet(rsId,...)=...

Are the stored data/nodes removed automatically, or do they require a manual KILL operation?

%Library.ScrollableResultSet

Note that if you open a %ScrollableResultSet and do not call %Save on it then when you close this object the data stored in the global will be removed and so you will not be able to open this resultset again. So if you open a scrollable resultset and you wish to use this again call %Save on it, but you must always make sure that when you are finished with it you do not call %Save so the temporary global used is cleaned up when you are done. Alterntively you can call %DeleteId passing the id to remove the saved data.

0
Josephus Flav  Mar 11 to Mikhail (VetsEZ) Akselrod

step by step:

  1. after understanding the example you create a temporary table
    • by own hands
  2. then you compose a SQL query to feed your Resultset
    • by own hands
  3. with your query you create a %SQL.Statement
    • by own hands
  4.  running %Execute generates %SQLStatementResult

BINGO
 You may publish your code on OpenExchange as an example.

0