Vitaliy Serdtsev · Aug 4, 2022 go to post
..
sql=0
sql($i(sql))="select *"
sql($i(sql))=",%external(DOB)||' '||%external(DOBTime) DOBString"
sql($i(sql))=",TO_CHAR(DOB||','||DOBTime,'MM/DD/YYYY HH24:MI:SS') DOBString2"
sql($i(sql))="from dc.test"
st.%ExecDirect(.st,.sql).%Display()
..
Result:
USER>##class(dc.test).Test()
ID
(INTEGER)
DOB
(DATE)
DOBTime
(TIME)
DOBString
(VARCHAR)
DOBString2
(VARCHAR)
1 01.01.2020 23:59:59 01.01.2020 23:59:59 01/01/2020 23:59:59
2 31.12.2022 10:10:10 31.12.2022 10:10:10 12/31/2022 10:10:10
Vitaliy Serdtsev · Aug 4, 2022 go to post

I like @Yaron Munz version better

<FONT COLOR="#000080">Class dc.test </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Abstract </FONT><FONT COLOR="#000000">]
{

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">=0,     </FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$i</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">))=</FONT><FONT COLOR="#0000ff">$lb</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"2021-11-27"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"2022-08-04"</FONT><FONT COLOR="#000000">),     </FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$i</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">))=</FONT><FONT COLOR="#0000ff">$lb</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"2020-02-28"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"2023-02-27"</FONT><FONT COLOR="#000000">),     </FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$i</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">))=</FONT><FONT COLOR="#0000ff">$lb</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"2020-02-28"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"2023-03-01"</FONT><FONT COLOR="#000000">),     </FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$i</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">))=</FONT><FONT COLOR="#0000ff">$lb</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"2017-03-01"</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"2020-02-28"</FONT><FONT COLOR="#000000">)        </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#0000ff">$o</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">),-1) </FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">d1 </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$li</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">),1),       </FONT><FONT COLOR="#800000">d2 </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$li</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">v</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">),2),       </FONT><FONT COLOR="#800000">age1 </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$e</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d2</FONT><FONT COLOR="#000000">,1,4)-</FONT><FONT COLOR="#0000ff">$e</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d1</FONT><FONT COLOR="#000000">,1,4)-(</FONT><FONT COLOR="#0000ff">$e</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d1</FONT><FONT COLOR="#000000">,6,10)]</FONT><FONT COLOR="#0000ff">$e</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d2</FONT><FONT COLOR="#000000">,6,10)),       </FONT><FONT COLOR="#800000">age2 </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$number</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$zabs</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$zdh</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d2</FONT><FONT COLOR="#000000">,3)-</FONT><FONT COLOR="#0000ff">$zdh</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d1</FONT><FONT COLOR="#000000">,3))/365.25,0),       </FONT><FONT COLOR="#800000">age3 </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$zdh</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d2</FONT><FONT COLOR="#000000">,3)-</FONT><FONT COLOR="#0000ff">$zdh</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">d1</FONT><FONT COLOR="#000000">,3)\365.25            </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">d1</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">" "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">d2</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">" (age1 = "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">age1</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">", age2 = "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">age2</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">", age3 = "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">age3</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">")"</FONT><FONT COLOR="#000000">,!   </FONT><FONT COLOR="#800080">} </FONT><FONT COLOR="#000000">}

}</FONT>

Result:
USER><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">dc.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">Test</FONT><FONT COLOR="#000000">()</FONT>
2021-11-27 2022-08-04 (age1 = 0, age2 = 1, age3 = 0)
2020-02-28 2023-02-27 (age1 = 2, age2 = 3, age3 = 2)
2020-02-28 2023-03-01 (age1 = 3, age2 = 3, age3 = 3)
2017-03-01 2020-02-28 (age1 = 2, age2 = 3, age3 = 2)

Vitaliy Serdtsev · Aug 4, 2022 go to post

A simple example of combining:

<FONT COLOR="#000080">Class dc.test Extends %Persistent
</FONT><FONT COLOR="#000000">{

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">DOB </FONT><FONT COLOR="#000080">As %Date</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">DOBTime </FONT><FONT COLOR="#000080">As %Time</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">%KillExtent</FONT><FONT COLOR="#000000">()      </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">DOB</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">DOBTime</FONT><FONT COLOR="#000000">)     </FONT><FONT COLOR="#0000ff">select </FONT><FONT COLOR="#000000">{</FONT><FONT COLOR="#000080">d </FONT><FONT COLOR="#008080">'2020-01-01'</FONT><FONT COLOR="#000000">},{</FONT><FONT COLOR="#000080">t </FONT><FONT COLOR="#008080">'23:59:59'</FONT><FONT COLOR="#000000">}     </FONT><FONT COLOR="#000080">union all     </FONT><FONT COLOR="#0000ff">select </FONT><FONT COLOR="#000000">{</FONT><FONT COLOR="#000080">d </FONT><FONT COLOR="#008080">'2022-12-31'</FONT><FONT COLOR="#000000">},{</FONT><FONT COLOR="#000080">t </FONT><FONT COLOR="#008080">'10:10:10'</FONT><FONT COLOR="#000000">}</FONT><FONT COLOR="#800080">)      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">st</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%SQL.Statement</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">()   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">st</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">%SelectMode</FONT><FONT COLOR="#000000">=2      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">=5   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">(1)=</FONT><FONT COLOR="#008000">"select *"   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">(2)=</FONT><FONT COLOR="#008000">",%odbcout(DOB)||' '||%odbcout(DOBTime) DOBString"   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">(3)=</FONT><FONT COLOR="#008000">",CAST(%odbcout(DOB)||' '||%odbcout(DOBTime) as DATETIME) DOBDateTime"   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">(4)=</FONT><FONT COLOR="#008000">",UNIX_TIMESTAMP(DOB||','||DOBTime) DOBUnixTimeStamp"   </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">(5)=</FONT><FONT COLOR="#008000">"from dc.test"   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#800000">st</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">%ExecDirect</FONT><FONT COLOR="#000000">(.</FONT><FONT COLOR="#800000">st</FONT><FONT COLOR="#000000">,.</FONT><FONT COLOR="#800000">sql</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%Display</FONT><FONT COLOR="#000000">() }

}</FONT>

Result:
USER><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">dc.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">Test</FONT><FONT COLOR="#000000">()</FONT>

ID
(INTEGER)
DOB
(DATE)
DOBTime
(TIME)
DOBString
(VARCHAR)
DOBDateTime
(TIMESTAMP)
DOBUnixTimeStamp
(NUMERIC)
1 01.01.2020 23:59:59 2020-01-01 23:59:59 2020-01-01 23:59:59 1577923199.00
2 31.12.2022 10:10:10 2022-12-31 10:10:10 2022-12-31 10:10:10 1672481410.00
2 Rows(s) Affected
Vitaliy Serdtsev · Aug 4, 2022 go to post

Instead of two separate fields, it would be easier to use the %TimeStamp (or %PosixTime) type, where the date and time are paired at once. For this type of data, you can make your own indexes for different parts and/or combinations of them: a separate date, a separate time, a separate year, a separate year and month, etc. You can also use these separate parts in the query (in SELECT and WHERE).

select datediff('yy',DOB,current_dateAge from yourtable
Vitaliy Serdtsev · Aug 3, 2022 go to post

The very first message contains a link from where you can download the ODBC-2022.1.0.209.0 driver for different operating systems.

Vitaliy Serdtsev · Aug 3, 2022 go to post

What does the JDBC driver have to do with the question about the ODBC driver?

Unlike JDBC, the ODBC driver still yet needs to be registered in the OS (at least for Windows), which is what the installer does.

Vitaliy Serdtsev · Jul 19, 2022 go to post

Made some minor changes to your code and now everything works as expected.

ClassMethod ActivateSQL(customerIdAs %Status
{
  ...
  Quit $$$OK
}

ClassMethod ActivateOO(customerIdAs %Status
{
  ...
  Quit $$$OK
}

If mode=0 {
  Do $system.OBJ.DisplayError(objCust.ActivateOO(id))
else {
  Do $system.OBJ.DisplayError(objCust.ActivateSQL(id))
  Set objCust.Active = objCust.ActiveGetStored(id)
}

Or

If mode=0 {
 Do $system.OBJ.DisplayError(objCust.ActivateOO(id))
else {
 Do $system.OBJ.DisplayError(objCust.ActivateSQL(id))
 Do objCust.%Reload()
}
Vitaliy Serdtsev · Jul 19, 2022 go to post

If this feature is not available in the Community Edition, then it makes no sense for me to try it. I just thought that in the preview version, all the features for testing are available. But thanks anyway for the quick response.

Vitaliy Serdtsev · Jul 19, 2022 go to post
Let's say you need to write a classmethod that updates a single property.
Update where: in memory or on disk?

Using SQL, you cannot update the value of a field in memory, but only on disk. On the other hand, OpenId() reads data from disk and knows nothing about the changes on disk that occurred after its call.

To avoid confusion, I would look to the side Version Checking (Alternative to Concurrency Argument) or/and <propertyname>GetStored()

Vitaliy Serdtsev · Jul 19, 2022 go to post

I decided to try Columnar Storage (IRIS CE):

Property As %String(STORAGEDEFAULT "columnar");

When compiling a class, I get the following error:

ERROR #15804: Columnar Storage (STORAGEDEFAULT=COLUMNAR) is not available with this license

I turn to the documentation to find out what's the matter:

Vitaliy Serdtsev · Jul 8, 2022 go to post
 

size = 201 (single line)

ClassMethod Convert(As %String) As %String
{
 x=$lfs("A,4,@,B,|3,8,C,(,<,E,3,€,G,9,6,I,|,],K,|<,|{,L,1,£,O,0,*,S,5,$,T,7,+,X,><,}{,Z,2,~/_") i=1:1:$l(a){c=$e(a,i),p=$lf(x,$$$UPPER(c)) s:p k(p)=3-$g(k(p),2),c=$li(x,p+k(p)) r=$g(r)_cr
}
Vitaliy Serdtsev · Jul 1, 2022 go to post

See RuntimeMode:

<FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%ResultSet</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"%DynamicQuery:SQL"</FONT><FONT COLOR="#000000">)
</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">RuntimeMode</FONT><FONT COLOR="#000000">=1 </FONT><FONT COLOR="#008000">;or 2</FONT>

Vitaliy Serdtsev · Jun 30, 2022 go to post
parameter INDEXNULLMARKER;

Override this parameter value to specify what value should be used as a null marker when a property of the type is used in a subscript of an index map. The default null marker used is -1E14, if none is specfied for the datatype. However %Library.PosixTime and %Library.BigInt datatypes could have values that collate before -1E14, and this means null values would not sort before all non-NULL values.

For beauty, I would also use the value of this parameter, for example:

<FONT COLOR="#000080">Class dc.test Extends %Persistent
</FONT><FONT COLOR="#000000">{

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">idp </FONT><FONT COLOR="#000080">As dc.test</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">idpC </FONT><FONT COLOR="#000080">As %Integer</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#000080">INDEXNULLMARKER </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800080">"$c(0)"</FONT><FONT COLOR="#000000">) [ </FONT><FONT COLOR="#000080">Calculated</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">Private</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">Required</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">SqlComputeCode </FONT><FONT COLOR="#000000">= {</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800080">{*}</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$s</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800080">{idp}</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#0000ff">$c</FONT><FONT COLOR="#000000">(0),1:</FONT><FONT COLOR="#800080">{idp}</FONT><FONT COLOR="#000000">)}, </FONT><FONT COLOR="#000080">SqlComputed </FONT><FONT COLOR="#000000">];

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">Name </FONT><FONT COLOR="#000080">As %String </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Required </FONT><FONT COLOR="#000000">];

</FONT><FONT COLOR="#000080">Index </FONT><FONT COLOR="#000000">iUnq On (idpC, Name) [ </FONT><FONT COLOR="#000080">Unique </FONT><FONT COLOR="#000000">];

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">%KillExtent</FONT><FONT COLOR="#000000">()      </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">Name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">idp</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'n1'</FONT><FONT COLOR="#000000">,1)</FONT><FONT COLOR="#800080">) </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">SQLCODE</FONT><FONT COLOR="#000000">,! </FONT><FONT COLOR="#008000">;0   </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">Name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">idp</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'n2'</FONT><FONT COLOR="#000000">,1)</FONT><FONT COLOR="#800080">) </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">SQLCODE</FONT><FONT COLOR="#000000">,! </FONT><FONT COLOR="#008000">;0   </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">Name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">idp</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'n2'</FONT><FONT COLOR="#000000">,1)</FONT><FONT COLOR="#800080">) </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">SQLCODE</FONT><FONT COLOR="#000000">,!! </FONT><FONT COLOR="#008000">;-119

  </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">Name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">idp</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'n1'</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#000080">null</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#800080">) </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">SQLCODE</FONT><FONT COLOR="#000000">,! </FONT><FONT COLOR="#008000">;0   </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">Name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">idp</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'n2'</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#000080">null</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#800080">) </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">SQLCODE</FONT><FONT COLOR="#000000">,! </FONT><FONT COLOR="#008000">;0   </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">test</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">Name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">idp</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'n2'</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#000080">null</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#800080">) </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">SQLCODE</FONT><FONT COLOR="#000000">,!! </FONT><FONT COLOR="#008000">;-119      </FONT><FONT COLOR="#0000ff">zw </FONT><FONT COLOR="#000000">^dc.testD,^dc.testI }

}</FONT>

Output:
USER><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">dc.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">Test</FONT><FONT COLOR="#000000">()</FONT>
0
0
-119

0 0 -119

^dc.testD=4 ^dc.testD(1)=$lb("",1,"n1") ^dc.testD(2)=$lb("",1,"n2") ^dc.testD(3)=$lb("","","n1") ^dc.testD(4)=$lb("","","n2") ^dc.testI("iUnq",1," N1",1)="" ^dc.testI("iUnq",1," N2",2)="" ^dc.testI("iUnq",$c(0)," N1",3)="" ^dc.testI("iUnq",$c(0)," N2",4)=""

Or
<FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">idpC </FONT><FONT COLOR="#000080">As %Integer </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Calculated</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">Private</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">Required</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">SqlComputeCode </FONT><FONT COLOR="#000000">= {</FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800080">{*}</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$s</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800080">{idp}</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">""</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#0000ff">$$$NULLSubscriptMarker</FONT><FONT COLOR="#000000">,1:</FONT><FONT COLOR="#800080">{idp}</FONT><FONT COLOR="#000000">)}, </FONT><FONT COLOR="#000080">SqlComputed </FONT><FONT COLOR="#000000">];</FONT>
Output:
USER><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">dc.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">Test</FONT><FONT COLOR="#000000">()</FONT>
0
0
-119

0 0 -119

^dc.testD=4 ^dc.testD(1)=$lb("",1,"n1") ^dc.testD(2)=$lb("",1,"n2") ^dc.testD(3)=$lb("","","n1") ^dc.testD(4)=$lb("","","n2") ^dc.testI("iUnq",-100000000000000," N1",3)="" ^dc.testI("iUnq",-100000000000000," N2",4)="" ^dc.testI("iUnq",1," N1",1)="" ^dc.testI("iUnq",1," N2",2)=""

Vitaliy Serdtsev · Jun 30, 2022 go to post
Class dc.test Extends (%RegisteredObject%JSON.Adaptor)
{

Parameter %JSONENABLED = 1;

Property AppointmentID As %String(%JSONFIELDNAME "AppointmentID"%JSONINCLUDE "inout");
Property AppointmentType As %String(%JSONINCLUDE "inout");
Property AppointmentTypeID As %String(%JSONINCLUDE "inout");
Property Date As %String(%JSONINCLUDE "inout");
Property DepartmentID As %String(%JSONINCLUDE "inout");
Property Duration As %Integer(%JSONINCLUDE "inout");
Property PatientAppointmentTypeName As %String(%JSONINCLUDE "inout");
Property LocalProviderID As %String(%JSONINCLUDE "inout");
Property ProviderID As %String(%JSONINCLUDE "inout");
Property StartTime As %String(%JSONINCLUDE "inout");
Property Reason As %String(%JSONINCLUDE "inout");

XData AthenaAppointment
{
<Mapping xmlns="http://www.intersystems.com/jsonmapping">
  <Property Name="AppointmentID" FieldName="appointmentid" />
  <Property Name="AppointmentType" FieldName="appointmenttype" />
  <Property Name="AppointmentTypeID" FieldName="appointmenttypeid" />
  <Property Name="Date" FieldName="date" />
  <Property Name="DepartmentID" FieldName="departmentid" />
  <Property Name="Duration" FieldName="duration" />
  <Property Name="PatientAppointmentTypeName" FieldName="patientappointmenttypename" />
  <Property Name="LocalProviderID" FieldName="localproviderid" />
  <Property Name="ProviderID" FieldName="providerid" />
  <Property Name="StartTime" FieldName="starttime" />
  <Property Name="Reason" FieldName="reasonid" />
</Mapping>
}

/// d ##class(dc.test).Test()
ClassMethod Test()
{
  json="{""date"":""06/27/2022"",""appointmentid"":""1214525"",""departmentid"":""195"",""localproviderid"":""187"",""appointmenttype"":""NEW PATIENT 45"",""providerid"":""187"",""starttime"":""14:00"",""duration"":45,""appointmenttypeid"":""1188"",""reasonid"":""-1"",""patientappointmenttypename"":""New Patient""}"
  
  try{

    tmp=..%New()
    
    $$$ThrowOnError(tmp.%JSONImport(json,"AthenaAppointment"))

    $$$ThrowOnError($system.OBJ.Dump(tmp))
  
  }catch(ex){
    #dim ex As %Exception.AbstractException
    ex.DisplayString()
  }
}

}
Output:
USER>##class(dc.test).Test()

+----------------- general information --------------- | oref value: 3 | class name: dc.test | reference count: 1 +----------------- attribute values ------------------ | AppointmentID = 1214525 | AppointmentType = "NEW PATIENT 45" | AppointmentTypeID = 1188 | Date = "06/27/2022" | DepartmentID = 195 | Duration = 45 | LocalProviderID = 187 |PatientAppointmentTypeName = "New Patient" | ProviderID = 187 | Reason = -1 | StartTime = "14:00" +-----------------------------------------------------

PS: pay special attention to the reason field: is it a string or an array of strings?

Vitaliy Serdtsev · Jun 30, 2022 go to post

The new version of IRIS 2022.2 has a new feature Columnar Storage, about which the documentation says the following:

Choosing a storage layout is not an exact science. You might need to experiment with multiple layouts and run multiple query tests to find the optimal one.
Therefore, you are unlikely to find an exact answer to your question.

Usually, the more efficient the query is and there are "correct" indexes, the smaller the GREF and, accordingly, the shorter the execution time. But this is influenced by many factors, not just the above: see InterSystems SQL Optimization Guide

Vitaliy Serdtsev · Jun 30, 2022 go to post

This can be done much easier, for example:

<FONT COLOR="#000080">Include </FONT><FONT COLOR="#ff0000">%occUtility

</FONT><FONT COLOR="#000080">Class dc.test Extends %Persistent </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">ClassType </FONT><FONT COLOR="#000000">= persistent, </FONT><FONT COLOR="#000080">ProcedureBlock</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">SqlTableName </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#008000">demo </FONT><FONT COLOR="#000000">] {

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">Foo </FONT><FONT COLOR="#000080">As %String </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">SqlFieldName </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#008000">FooBar </FONT><FONT COLOR="#000000">];

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">Bar </FONT><FONT COLOR="#000080">As %Boolean</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {      </FONT><FONT COLOR="#008000">; d ##class(dc.test).Test()   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">%KillExtent</FONT><FONT COLOR="#000000">()      </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">demo</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">FooBar</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">Bar</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'f1'</FONT><FONT COLOR="#000000">,0)</FONT><FONT COLOR="#800080">)   &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">demo</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">FooBar</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">Bar</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'f2'</FONT><FONT COLOR="#000000">,1)</FONT><FONT COLOR="#800080">)   &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">demo</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">FooBar</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">Bar</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'f3'</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#000080">null</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#800080">)      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">tablename</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$$$comClassKeyGet</FONT><FONT COLOR="#000000">(..</FONT><FONT COLOR="#0000ff">%ClassName</FONT><FONT COLOR="#000000">(1),</FONT><FONT COLOR="#0000ff">$$$cCLASSsqlqualifiednameQ</FONT><FONT COLOR="#000000">)      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%ResultSet</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%New</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"%DynamicQuery:SQL"</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Prepare</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"select * from "</FONT><FONT COLOR="#000000">_</FONT><FONT COLOR="#800000">tablename</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Execute</FONT><FONT COLOR="#000000">()   </FONT><FONT COLOR="#0000ff">while </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">Next</FONT><FONT COLOR="#000000">() </FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#000000">! </FONT><FONT COLOR="#0000ff">f </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=1:1:</FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">GetColumnCount</FONT><FONT COLOR="#000000">() </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">GetColumnHeader</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">" = "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#0000ff">$$</FONT><FONT COLOR="#ff0000">quote</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">GetData</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">)),</FONT><FONT COLOR="#008000">" "   </FONT><FONT COLOR="#800080">}      </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#800000">rs</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">%Close</FONT><FONT COLOR="#000000">() }

}</FONT>

Output:
USER><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">dc.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">Test</FONT><FONT COLOR="#000000">()</FONT>

ID = 1 Bar = 0 FooBar = "f1" ID = 2 Bar = 1 FooBar = "f2" ID = 3 Bar = "" FooBar = "f3"

Vitaliy Serdtsev · Jun 28, 2022 go to post

Caché 5.0.21:

<FONT COLOR="#000080">Class DC.DemoPropertyQuery Extends %Persistent </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">ClassType </FONT><FONT COLOR="#000000">= persistent, </FONT><FONT COLOR="#000080">ProcedureBlock </FONT><FONT COLOR="#000000">]
{

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">Foo </FONT><FONT COLOR="#000080">As %String</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">Bar </FONT><FONT COLOR="#000080">As %Boolean</FONT><FONT COLOR="#000000">;

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Benchmark() {   <FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">Job</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#000080">##CLASS</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%SYSTEM.Process</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%OpenId</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$job</FONT><FONT COLOR="#000000">)      </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">start </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$zhorolog   set </FONT><FONT COLOR="#800000">startGlobalRefs </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">Job</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">GlobalReferences   set </FONT><FONT COLOR="#800000">startLines </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">Job</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">LinesExecuted   for </FONT><FONT COLOR="#800000">i</FONT><FONT COLOR="#000000">=1:1:1000 </FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">kill </FONT><FONT COLOR="#800000">properties     </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">GetPropertiesAsQuickly</FONT><FONT COLOR="#000000">(.</FONT><FONT COLOR="#800000">properties</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#800080">}   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">endLines </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">Job</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">LinesExecuted   set </FONT><FONT COLOR="#800000">endGlobalRefs </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#800000">Job</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">GlobalReferences   write </FONT><FONT COLOR="#008000">"Elapsed time (1000x): "</FONT><FONT COLOR="#000000">,(</FONT><FONT COLOR="#0000ff">$zhorolog</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#800000">start</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">" seconds; "</FONT><FONT COLOR="#000000">,(</FONT><FONT COLOR="#800000">endGlobalRefs</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#800000">startGlobalRefs</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">" global references; "</FONT><FONT COLOR="#000000">,(</FONT><FONT COLOR="#800000">endLines</FONT><FONT COLOR="#000000">-</FONT><FONT COLOR="#800000">startLines</FONT><FONT COLOR="#000000">),</FONT><FONT COLOR="#008000">" routine lines"</FONT><FONT COLOR="#000000">,!      </FONT><FONT COLOR="#0000ff">do </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">Print</FONT><FONT COLOR="#000000">(.</FONT><FONT COLOR="#800000">properties</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#0000ff">write </FONT><FONT COLOR="#000000">! }

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Print(</FONT><FONT COLOR="#000080">ByRef </FONT><FONT COLOR="#ff00ff">properties</FONT><FONT COLOR="#000000">) {   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">key </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#008000">""   </FONT><FONT COLOR="#0000ff">for </FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">key </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$order</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">properties</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">),1,</FONT><FONT COLOR="#800000">data</FONT><FONT COLOR="#000000">)     </FONT><FONT COLOR="#0000ff">quit</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">""     </FONT><FONT COLOR="#0000ff">set $listbuild</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">type</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">origin</FONT><FONT COLOR="#000000">) = </FONT><FONT COLOR="#800000">data     </FONT><FONT COLOR="#0000ff">write </FONT><FONT COLOR="#000000">!,</FONT><FONT COLOR="#008000">"property: "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"; type: "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">type</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"; origin: "</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">origin   </FONT><FONT COLOR="#800080">} </FONT><FONT COLOR="#000000">}

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">GetPropertiesAsQuickly(</FONT><FONT COLOR="#000080">Output </FONT><FONT COLOR="#ff00ff">properties</FONT><FONT COLOR="#000000">) {   </FONT><FONT COLOR="#008000">// Getting properties via macro-wrapped direct global references is harder to read,   // but is the fastest way to do it.   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">key </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#008000">""   </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">class </FONT><FONT COLOR="#000000">= ..</FONT><FONT COLOR="#0000ff">%ClassName</FONT><FONT COLOR="#000000">(1)   </FONT><FONT COLOR="#0000ff">for </FONT><FONT COLOR="#800080">{     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">key </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$$$comMemberNext</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">class</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#0000ff">$$$cCLASSproperty</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">)     </FONT><FONT COLOR="#0000ff">quit</FONT><FONT COLOR="#000000">:</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">""     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">type </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$$$comMemberKeyGet</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">class</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#0000ff">$$$cCLASSproperty</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#0000ff">$$$cPROPtype</FONT><FONT COLOR="#000000">)     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">origin </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#0000ff">$$$comMemberKeyGet</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">class</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#0000ff">$$$cCLASSproperty</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#0000ff">$$$cPROPorigin</FONT><FONT COLOR="#000000">)     </FONT><FONT COLOR="#0000ff">set </FONT><FONT COLOR="#800000">properties</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">key</FONT><FONT COLOR="#000000">) = </FONT><FONT COLOR="#0000ff">$listbuild</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#800000">type</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#800000">origin</FONT><FONT COLOR="#000000">)   </FONT><FONT COLOR="#800080">} </FONT><FONT COLOR="#000000">}

}</FONT>

Result:

USER>do ##class(DC.DemoPropertyQuery).Benchmark()
Elapsed time (1000x): .018047 seconds; 25003 global references; 40000 routine lines
 
property: %Concurrency; type: %Library.CacheString; origin: %Library.Persistent
property: %IsInSave; type: %Library.CacheString; origin: %Library.Persistent
property: Bar; type: %Library.Boolean; origin: DC.DemoPropertyQuery
property: Foo; type: %Library.String; origin: DC.DemoPropertyQuery
Vitaliy Serdtsev · Jun 23, 2022 go to post

See $SYSTEM.SQL.SetServerInitCode() (there are differences for IRIS)

Simple example:

<FONT COLOR="#000080">Class dc.test
</FONT><FONT COLOR="#000000">{

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {      </FONT><FONT COLOR="#0000ff">s </FONT><FONT COLOR="#800000">programname</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#0000ff">$zcvt</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">%SYS.ProcessQuery</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%OpenId</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#0000ff">$j</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">ClientExecutableName</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">"L"</FONT><FONT COLOR="#000000">)

  </FONT><FONT COLOR="#0000ff">i </FONT><FONT COLOR="#800000">programname</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"blablabla.exe" </FONT><FONT COLOR="#800080">{

    </FONT><FONT COLOR="#008000">;useful work

    </FONT><FONT COLOR="#0000ff">s $EC</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"ERROR"     ;or     </FONT><FONT COLOR="#0000ff">s $ROLES</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#008000">"r1"   </FONT><FONT COLOR="#800080">} </FONT><FONT COLOR="#000000">}

}</FONT>

USER><FONT COLOR="#0000ff">d $SYSTEM</FONT><FONT COLOR="#008080">.SQL</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#0000ff">SetServerInitCode</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"d ##class(dc.test).Test()"</FONT><FONT COLOR="#000000">)</FONT>

Now, when connecting from a specific program via ODBC/JDBC to namespace "USER", an error will occur. You can configure something another.

Vitaliy Serdtsev · Jun 23, 2022 go to post

See Parent-Child Relationships and Storage

Demonstration:

  1. <FONT COLOR="#000080">Class dc.child Extends %Persistent
    </FONT><FONT COLOR="#000000">{
    </FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">name;
    </FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">parent </FONT><FONT COLOR="#000080">As dc.parent</FONT><FONT COLOR="#000000">;
    </FONT><FONT COLOR="#008000">// Relationship parent As dc.parent [ Cardinality = parent, Inverse = child ];
    </FONT><FONT COLOR="#000000">}</FONT>

    <FONT COLOR="#000080">Class dc.parent Extends %Persistent </FONT><FONT COLOR="#000000">{ </FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">name; </FONT><FONT COLOR="#008000">// Relationship child As dc.child [ Cardinality = children, Inverse = parent ]; </FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">%KillExtent</FONT><FONT COLOR="#000000">()   </FONT><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">child</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">%KillExtent</FONT><FONT COLOR="#000000">()      </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">parent</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">name</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'parent1'</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#800080">)   &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">parent</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">name</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'parent2'</FONT><FONT COLOR="#000000">)</FONT><FONT COLOR="#800080">)

      &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">child</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">parent</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'child11'</FONT><FONT COLOR="#000000">,1)</FONT><FONT COLOR="#800080">)   &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">child</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">parent</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'child12'</FONT><FONT COLOR="#000000">,1)</FONT><FONT COLOR="#800080">)   &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">child</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">parent</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'child21'</FONT><FONT COLOR="#000000">,2)</FONT><FONT COLOR="#800080">)   &sql(</FONT><FONT COLOR="#0000ff">insert </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#008000">dc</FONT><FONT COLOR="#000000">.</FONT><FONT COLOR="#008000">child</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">name</FONT><FONT COLOR="#000000">,</FONT><FONT COLOR="#008000">parent</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">values</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'child22'</FONT><FONT COLOR="#000000">,2)</FONT><FONT COLOR="#800080">)      </FONT><FONT COLOR="#0000ff">zw </FONT><FONT COLOR="#000000">^dc.parentD,^dc.childD } }</FONT>

    USER>##class(dc.parent).Test()
    ^dc.parentD=2
    ^dc.parentD(1)=$lb("","parent1")
    ^dc.parentD(2)=$lb("","parent2")
    ^dc.childD=4
    ^dc.childD(1)=$lb("","child11",1)
    ^dc.childD(2)=$lb("","child12",1)
    ^dc.childD(3)=$lb("","child21",2)
    ^dc.childD(4)=$lb("","child22",2)
  2. Important: do not touch the existing Storages in both classes!!!
    Class dc.child Extends %Persistent
    {
    Property name;
    //Property parent As dc.parent;
    Relationship parent As dc.parent Cardinality = parent, Inverse = child ];
    Storage Default
    {
    ...
    }
    }
    

    <FONT COLOR="#000080">Class dc.parent Extends %Persistent </FONT><FONT COLOR="#000000">{ </FONT><FONT COLOR="#000080">Property </FONT><FONT COLOR="#000000">name; </FONT><FONT COLOR="#000080">Relationship </FONT><FONT COLOR="#000000">child </FONT><FONT COLOR="#000080">As dc.child </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Cardinality </FONT><FONT COLOR="#000000">= children, </FONT><FONT COLOR="#000080">Inverse </FONT><FONT COLOR="#000000">= parent ]; </FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {  ... } </FONT><FONT COLOR="#000080">Storage </FONT><FONT COLOR="#000000">Default { ... } }</FONT>

    USER>##class(dc.parent).Test()
    ^dc.parentD=2
    ^dc.parentD(1)=$lb("","parent1")
    ^dc.parentD(2)=$lb("","parent2")
    ^dc.childD=4
    ^dc.childD(1,1)=$lb("","child11",1)
    ^dc.childD(1,2)=$lb("","child12",1)
    ^dc.childD(2,3)=$lb("","child21",2)
    ^dc.childD(2,4)=$lb("","child22",2)
  3. Important: now remove Storage from dc.child class and recompile both classes. Note that now the Storage of the dc.child class has changed.
    USER>##class(dc.parent).Test()
    ^dc.parentD=2
    ^dc.parentD(1)=$lb("","parent1")
    ^dc.parentD(1,"child",1)=$lb("","child11")
    ^dc.parentD(1,"child",2)=$lb("","child12")
    ^dc.parentD(2)=$lb("","parent2")
    ^dc.parentD(2,"child",3)=$lb("","child21")
    ^dc.parentD(2,"child",4)=$lb("","child22")
    ^dc.childD=4
    ^dc.childD(1,1)=$lb("","child11",1)
    ^dc.childD(1,2)=$lb("","child12",1)
    ^dc.childD(2,3)=$lb("","child21",2)
    ^dc.childD(2,4)=$lb("","child22",2)
    Now the data in ^dc.childD from the previous test/step is hanging in the air and cannot be accessed via SQL

Based on the above, the answer to your question will depend on what and how exactly you changed in your classes.

PS: for simplicity, I would advise you to create a clone of your dc.child class (without Relationship) and already take the "disappeared" data from it. After linking the tables (possibly with subsequent copying of data from the old Storage to the new one), the clone with the data can be deleted.

Vitaliy Serdtsev · Jun 23, 2022 go to post

See MultiValue Basic | Caché Alternative Exists for SOUNDEX()

Workaround:

<FONT COLOR="#000080">Class dc.test </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Abstract </FONT><FONT COLOR="#000000">]
{

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">Test() {      </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#000000">..</FONT><FONT COLOR="#0000ff">SOUNDEX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008000">"M"</FONT><FONT COLOR="#000000">),!

  </FONT><FONT COLOR="#008000">;or

  </FONT><FONT COLOR="#800080">&sql(</FONT><FONT COLOR="#0000ff">select </FONT><FONT COLOR="#008000">SOUNDEX</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">'McD'</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">into </FONT><FONT COLOR="#800000">:r</FONT><FONT COLOR="#800080">)   </FONT><FONT COLOR="#0000ff">w </FONT><FONT COLOR="#800000">r</FONT><FONT COLOR="#000000">,! }

</FONT><FONT COLOR="#000080">ClassMethod </FONT><FONT COLOR="#000000">SOUNDEX(</FONT><FONT COLOR="#ff00ff">s</FONT><FONT COLOR="#000000">) </FONT><FONT COLOR="#000080">As %String </FONT><FONT COLOR="#000000">[ </FONT><FONT COLOR="#000080">Language </FONT><FONT COLOR="#000000">= mvbasic, </FONT><FONT COLOR="#000080">SqlName </FONT><FONT COLOR="#000000">= </FONT><FONT COLOR="#008000">SOUNDEX</FONT><FONT COLOR="#000000">, </FONT><FONT COLOR="#000080">SqlProc </FONT><FONT COLOR="#000000">] {  </FONT><FONT COLOR="#0000ff">RETURN SOUNDEX</FONT><FONT COLOR="#000000">(s) }

}</FONT>

Result:

USER><FONT COLOR="#0000ff">d </FONT><FONT COLOR="#000080">##class</FONT><FONT COLOR="#000000">(</FONT><FONT COLOR="#008080">dc.test</FONT><FONT COLOR="#000000">).</FONT><FONT COLOR="#0000ff">Test</FONT><FONT COLOR="#000000">()</FONT> M000 M230