Class Test.Duplicates Extends %Persistent
{

Index iText On (Text(KEYS), Text(ELEMENTS)) [ Type = bitmap ];

Property Text As %String(MAXLEN 2000);

ClassMethod TextBuildValueArray(
  v,
  ByRef arrAs %Status
{
  #define sizeOfChunk 400

  i v="" {
    arr("null")=v
  }else{
    hasDupl=$$$YES
    f i=1:1:$l(v)\$$$sizeOfChunk+($l(v)#$$$sizeOfChunk>0) {
      arr(i)=$e(v,1,$$$sizeOfChunk),$e(v,1,$$$sizeOfChunk)=""
      s:hasDupl&&'$d(^Test.DuplicatesI("iText"," "_i,##class(%Collation).SqlUpper(arr(i)))) hasDupl=$$$NO
    }
    s:hasDupl arr("hasDupl")=""
  }
  q $$$OK
}

ClassMethod Test()
{
  ;d ##class(Test.Duplicates).Test()

  ..%KillExtent()
  
  text=##class(%PopulateUtils).StringMin(2000,2000)
  &sql(insert into Test.Duplicates(Text)
  select 'ab'
  union all select 'abc' union all select 'abc'
  union all select 'abe' union all select 'abe' union all select 'abe'
  union all select null  union all select null
  union all select :text union all select :text)
  
  d $SYSTEM.SQL.PurgeForTable($classname()),
    $system.SQL.TuneTable($classname(),$$$YES),
    $system.OBJ.Compile($classname(),"cu-d")
    
  sql(1)="select %ID,$extract(Text,1,10) Text10 from Test.Duplicates",
    sql(2)="select * from Test.Duplicates where FOR SOME %ELEMENT(Text) (%KEY='null')",
    sql(3)="select %ID,$extract(Text,1,10) HasDupl_Text10_All from Test.Duplicates where FOR SOME %ELEMENT(Text) (%KEY='hasdupl')",
    sql(4)="select distinct $extract(%exact(Text),1,10) HasDupl_Text10 from Test.Duplicates where FOR SOME %ELEMENT(Text) (%KEY='hasdupl')"
  
  i=1:1:$o(sql(""),-1) !,sql(i),!! ##class(%SQL.Statement).%ExecDirect(,sql(i)).%Display() !,"---------",!
}

}

Result:

USER>##class(Test.Duplicates).Test()
 
select %ID,$extract(Text,1,10) Text10 from Test.Duplicates
 
ID      Text10
1       ab
2       abc
3       abc
4       abe
5       abe
6       abe
7
8
9       QfgrABXjbT
10      QfgrABXjbT
 
10 Rows(s) Affected
---------
 
select * from Test.Duplicates where FOR SOME %ELEMENT(Text) (%KEY='null')
 
ID      Text
7
8
 
2 Rows(s) Affected
---------
 
select %ID,$extract(Text,1,10) HasDupl_Text10_All from Test.Duplicates where FOR SOME %ELEMENT(Text) (%KEY='hasdupl')
 
ID      HasDupl_Text10_All
3       abc
5       abe
6       abe
10      QfgrABXjbT
 
4 Rows(s) Affected
---------
 
select distinct $extract(%exact(Text),1,10) HasDupl_Text10 from Test.Duplicates where FOR SOME %ELEMENT(Text) (%KEY='hasdupl')
 
HasDupl_Text10
abc
abe
QfgrABXjbT
 
3 Rows(s) Affected
---------

Notes:

  • not used hashing, so there's no risk of collisions
  • support for strings of unlimited length up to 3641144 ($zu(96,39))
  • customizable chunk size
  • minimum code
  • should work for older versions of Caché
  • high performance
  • possible else more optimize code ;)

See Indexing of non-atomic attributes

Another variants:

#Dim sc As %Status $$$OK
s:SQLCODE sc ##class(%Exception.SQL).CreateFromSQLCODE(SQLCODE,%msg).AsStatus()
s:SQLCODE sc $system.Error.FromSQLCode(SQLCODE,%msg).Status

It should also be noted the %sqlcontext, so final code will look as follows:

if SQLCODE {
 set:$IsObject($get(%sqlcontext)) %sqlcontext.%SQLCODE=SQLCODE%sqlcontext.%Message=$get(%msg)
 set sc=$$$ERROR($$$SQLCode,SQLCODE,$g(%msg))
else set sc=$$$OK }

Isn't it easier to use the built function StringMin, especially when its the code does exactly the same thing?

USER>w $length(##class(%PopulateUtils).StringMin(100,100))
100

Source code:

ClassMethod StringMin(
  minlen As %Integer 1,
  maxlen As %Integer 1As %String ProcedureBlock = 1 ]
{
 if maxlen '< minlen {
   set len=$$$PRand(maxlen-minlen+1)+minlen,
       string=""
   for i=1:1:len {
     Set charn=$s($$$PRand(2):$$$PRand(26)+65,1:$$$PRand(26)+97),
         string=string_$s(charn<123:$c(charn),1:" ")
   }
   quit string
 else quit "" }
}
Class dc.demo Extends %Persistent
{

Property ChildPrice As %Library.Float;

ClassMethod Test()
{
  ;d ##class(dc.demo).Test()

  ..%KillExtent()
  obj=..%New()
  obj.ChildPrice=2.56
  obj.%Save()
  
  &sql(select ChildPrice into :ChildPrice from dc.demo where %ID=1)
  ChildPrice,!
}

}

My result:
USER>##class(dc.demo).Test()
2.56

What will be the result you have?
Also check the settings for the format of the data types in your tool (DbVisualizer, Caché Monitor, WinSQL, SQuirreL SQL, etc.), in which you make a selection.

Synchronous and Asynchronous Methods

  1. ClientMethod onunloadHandler() [ Language = javascript ]
    {
      this.SomeZenMethod();
    }
    
    ClassMethod SomeZenMethod() As %Status ZenMethod ]
    {
      // to do some work
      quit $$$OK
    }
  2. ClientMethod onunloadHandler() [ Language = javascript ]
    {
      var old zenSynchronousMode;
      zenSynchronousMode true;
      this.SomeZenMethod();
      zenSynchronousMode old;
    }
    
    ClassMethod SomeZenMethod() [ ZenMethod ]
    {
      // to do some work
    }

    The following code has been tested on versions 2015.2 and 2017.2:

    Class dc.demo Extends %RegisteredObject
    {
    
    Property f1 As %String;
    
    Property f2 As %Integer;
    
    Property f3 As %ListOfDataTypes;
    
    Method GetTarget(
      ByRef pParms As %String,
      Output pObj As %RegisteredObjectAs %Status
    {
      pObj = ..%New()
      
      i $g(pParms(1))="a" {
        pObj.f1 "Peter"
        pObj.f2 = 21
      }else{
        pObj.f1 "Bob"
        pObj.f2 = 12
        pObj.f3 ##class(%ListOfDataTypes).%New()
        pObj.f3.InsertList($lb("a","b","c"))
      }
      q $$$OK
    }
    
    ClassMethod Obj2Json()
    {
      ;d ##class(dc.demo).Obj2Json()
      
      parms(1)="a"
      ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(.stream,..%New(),"GetTarget",.parms,$$$YES,"aeloq")
      "1) ",stream.Read($$$MaxLocalLength),!
      
      parms
      ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(.stream,..%New(),"GetTarget",.parms,$$$YES,"aeloq")
      "2) ",stream.Read($$$MaxLocalLength),!
    }
    
    ClassMethod Json2Obj()
    {
      ;d ##class(dc.demo).Json2Obj()
      
      ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject("{""f1"":""Peter"",""f2"":21,""f3"":[]}",$classname(),.obj)
      obj.f1," : ",obj.f3.Count(),!
    
      ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject("{""f1"":""Bob"",""f2"":12,""f3"":[""a"",""b"",""c""]}",$classname(),.obj)
      obj.f1," : ",obj.f3.Count(),!
    }
    
    }

    Result:

    USER>##class(dc.demo).Obj2Json()
    1) {"f1":"Peter","f2":21,"f3":[]}
    2) {"f1":"Bob","f2":12,"f3":["a","b","c"]}
     
    USER>##class(dc.demo).Json2Obj()
    Peter : 0
    Bob : 3
    Class dc.SomeClass
    {
    
    Parameter SOMENAME = "Name1";
    
    Query SomeQuery(SOMENAME = {..#SOMENAME}) As %SQLQuery
    {
      SELECT ID || :SOMENAME || Name FROM Table1
    }
    
    Query SomeQuery1() As %SQLQuery
    {
      #define SOMENAME ##Expression("'"_$parameter("dc.SomeClass","SOMENAME")_"'")
      SELECT ID || $$$SOMENAME || Name FROM Table1
    }
    
    Query SomeQuery2() As %SQLQuery
    {
      #define SOMENAME ##Expression("'"_##class(dc.SomeClass).#SOMENAME_"'")
      SELECT ID || $$$SOMENAME || Name FROM Table1
    }
    
    ClassMethod Test()
    {
      ;d ##class(dc.SomeClass).Test()
      
      rs=##class(%ResultSet).%New("dc.SomeClass:SomeQuery")
      sc=rs.Execute()
      i $$$ISERR(sc{
        d $System.Status.DisplayError(sc)
      else {
        rs.%Display()
      }
    }
    }

    It also can be solved.

    The behavior of zenPage.launchPopupWindow depends on the setting useSoftModal.

    Play around with %OnUseSoftModals in the following example:

    Class dc.demo Extends %ZEN.Component.page
    {
    
    XData Style
    {
    <style type="text/css">
    .modalGroupCloseButton {
      background-colorgreen;
      filteralpha(opacity=20);
      opacity: 0.2;
    }
    .modalGroupCloseButtonHover {
      background-colorgreen;
    }
    </style>
    }
    
    XData CSS3Style
    {
    <style type="text/css">
    .modalGroupCloseButton {
      background-colorred;
      opacity: 0.2;
    }
    .modalGroupCloseButtonHover {
      background-colorred;
    }
    </style>
    }
    
    XData Contents [ XMLNamespace "http://www.intersystems.com/zen" ]
    {
    <page xmlns="http://www.intersystems.com/zen">
    <button caption="Show modal" onclick="zenPage.showModal()"/>
    </page>
    }
    
    ClientMethod showModal() [ Language = javascript ]
    {
      if (!this.isPopup) {
        zenPage.launchPopupWindow(window.location.href,'DEMO MODAL','center=yes,resizable=no,width=320,height=240');
        
        var els=document.body.getElementsByClassName('modalGroupClose');
        if (els.length>0) els[0].onclick=zenPage.onhideGroupHandler;
      }
    }
    
    ClientMethod onhideGroupHandler() [ Language = javascript ]
    {
      if (confirm('[1] Are you sure you want to leave?')) {
        var modalGroup=zenPage.modalStack[zenPage.modalStack.length - 1];
        modalGroup.hideGroup();
      }
    }
    
    ClientMethod onunloadHandler(e) [ Language = javascript ]
    {
      var message "[2] Are you sure you want to leave?";
    
      if (typeof == "undefined") {
          e window.event;
      }
      if (e) {
          e.returnValue message;
      }
      return message;
    }
    
    /// Return whether the current page should use soft modal divs.
    /// The default behaviour is to return 1 for the current instance, but users may set the
    /// ^%ISC.ZEN.useSoftModals global change this system-wide.
    /// In some cases, it may be worth modifying the value of the flag based on
    /// the user agent, particularly if users are expected to access the application
    /// from mobile devices where new windows behave differently.
    ClassMethod %OnUseSoftModals() As %Boolean CodeMode = expression ]
    {
    $$$YES
    }
    
    /// This callback method determines lets a page specify level of CSS support is used by this page.
    /// The default is to return "", which indicates that the built-in ZEN CSS level
    /// detection is used. A page can override this and return 2 or 3.
    Method %OnDetermineCSSLevel() As %Integer CodeMode = expression ]
    {
    3
    }
    
    }

    Yes, checked and it works in IE11 (see screenshot).
    In addition, you can find in the file zenutils.js the following code:

    if (zenIsIE && (!(((typeof zenIsHTML5 != 'undefined'&& zenIsHTML5) && ((typeof document.documentMode != 'undefined'&& document.documentMode==9)))) {
      <...>
      window.document.body.onload function(event) { return zenPageEventHandler('onload',event); }
      window.document.body.onbeforeunload function(event) { return zenPageEventHandler('onunload',event); }
      <...>
    }

    Googling "onbeforeunload не работает" or "onbeforeunload javascript not working".

    Client Side Callback Methods for the Page

    ///  This client event, if present, is fired when the page is unloaded.
    ///  If this method returns a string value, then that is used as the
    ///  return value of the HTML page's onbeforeunload handler (if more than
    ///  one component returns a string, the first one encountered is used).
    ClientMethod onunloadHandler() [ Language = javascript ]
    {
      return 'Are you sure you want to leave?';
    }

    The following query produces zero results:

    select bar.name from foo join bar on bar.id %INLIST MyBars

    This is because MyBars is stored as a $lb($lb(id1),$lb(id2),...,$lb(idN)), and you try to query the data stored in the form $lb(id1,id2,...,idN).

    Your query need some change to make it work, namely:

    select name from foo join bar b on $listbuild(b.%ID) %INLIST MyBars

    For passing array by reference try to use the class $system.WorkMgr instead of job.

    Sample:

    Class demo.test Abstract ]
    {
    
    ClassMethod Test(arrayAs %Status
    {
      ^CacheTempUser.dbg
      ^CacheTempUser.dbg($zp)=array
      ^CacheTempUser.dbg($zp,"$j")=$j
      q $$$OK
    }
    
    }
    
    demo()
      queue,arr
    
      arr(1)="qwe"
      arr(2)="asd"
      
      "$j = ",$j,!
      queue=$system.WorkMgr.Initialize("/multicompile=1",,1)
      queue.Queue("##class(demo.test).Test",.arr)
      queue.WaitForComplete()
      
      zw ^CacheTempUser.dbg
      q

    Result:

    USER>^demo
    $j = 7600
    ^CacheTempUser.dbg(8488,1)="qwe"
    ^CacheTempUser.dbg(8488,2)="asd"
    ^CacheTempUser.dbg(8488,"$j")=8348
    "$ZTZ=",$ztz,!
    
    #define 2utc(%t) $tr($zdt($zdt($zdth($system.SQL.TOTIMESTAMP(%t,"YYYYMMDDHHMISS"),3),-3),8,1)," :")
    
    s t="20160105125915"
    "Winter time: ",t," -> ",$$$2utc(t),!
    
    t="20160705125915"
    "Summer time: ",t," -> ",$$$2utc(t)

    Result (GMT+02:00, Chisinau):

    USER>^test
    $ZTZ=-120
    Winter time: 20160105125915 -> 20160105105915
    Summer time: 20160705125915 -> 20160705095915

    Note:

    • Takes into account summer/winter time
    • Is taken into account to option of OS for automatic daylight saving time

    For example, if in the OS to disable automatic daylight saving time, the result will be different:

    USER>^test
    $ZTZ=-120
    Winter time: 20160105125915 -> 20160105105915
    Summer time: 20160705125915 -> 20160705105915