go to post Vitaliy Serdtsev · Mar 3, 2020 Defining Stored Procedures Source code Class dc.test [ Abstract ] { Query numbers(count As %Integer = 4) As %Query(ROWSPEC = "n:%Integer") [ SqlName = numbers, SqlProc ] { } ClassMethod numbersExecute( ByRef qHandle As %Binary, count As %Integer = 4) As %Status { s qHandle=$lb(0,count) q $$$OK } ClassMethod numbersFetch( ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = numbersExecute ] { s n=$li(qHandle,1)+1 i n>$li(qHandle,2) { s AtEnd=1 } else { s Row=$lb(n) s $li(qHandle,1)=n } q $$$OK } ClassMethod numbersClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = numbersExecute ] { q $$$OK } } Result: select * from dc.numbers(107) n 1 2 ... 105 106 107
go to post Vitaliy Serdtsev · Feb 28, 2020 Forget. Now %STARTSWITH all other things being equal is slightly faster than LIKE. This point is deeply hidden in the documentation, and it seems that this applies only to FOR SOME %ELEMENT. If manage to speed up the special case for LIKE, then still need to correct/supplement the documentation.
go to post Vitaliy Serdtsev · Feb 27, 2020 Through %ZEN.proxyObject is unlikely to work, since the q parameter cannot be disabled in this case q - output numeric values unquoted even when they come from a non-numeric property Use your own class, for example: Class dc.test Extends %RegisteredObject { Property articlenumber As %String; }s object = ##class(dc.test).%New() s object.articlenumber = "15049950" s x = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(.json,object,,,,"aelotw")Output: { "articlenumber":"15049950" }
go to post Vitaliy Serdtsev · Feb 27, 2020 Hi Evgeny! I can't check for technical reasons. Docker version does not suit me.
go to post Vitaliy Serdtsev · Feb 27, 2020 Conclusion: the quote will be removed from the documentation since it's no longer true. Then besides this, in the documentation for %STARTSWITH need to add the note DEPRECATED and the recommendation "use LIKE 'XXX%'" I also did an analysis for Caché 2018.1 Class del.t Extends %Persistent { Index ip On p; Property p As %VarString; /// d ##class(del.t).Fill() ClassMethod Fill(N = 1000000) { d DISABLE^%NOJRN k ^del.tD,^del.tI f i=1:1:N s ^del.tD(i)=$lb("","test"_i) s ^del.tD=N d ENABLE^%NOJRN d ..%BuildIndices(,,,$$$NO) d $system.SQL.TuneTable($classname(),$$$YES) d $system.OBJ.Compile($classname(),"cu-d") } }Although the plans are exactly the same in SMP the results of the metrics differ: select count(*) from del.t where p like 'test7%' Row count: 1 Performance: 0.291 seconds 333340 global references 2000537 lines executed select count(*) from del.t where p %startswith 'test7' Row count: 1 Performance: 0.215 seconds 333340 global references 1889349 lines executed For the next two queries, the INT code matches: &sql(select * from del.t where p like 'test7%') &sql(select * from del.t where p %startswith 'test7')But for these - is already different, so the metrics in SMP are different: &sql(select * from del.t where p like :a) &sql(select * from del.t where p %startswith :a)In IRIS 2020.1, the work with embedded queries was changed, but I can't check it.
go to post Vitaliy Serdtsev · Feb 26, 2020 Quote from the documentation: For performance reasons, the predicate %STARTSWITH 'abc' is preferable to the equivalent predicate LIKE 'abc%'. proof
go to post Vitaliy Serdtsev · Feb 26, 2020 I think that the author meant that the simplest queries of the form like 'text%' automatically worked as/converted to %startswith 'text'
go to post Vitaliy Serdtsev · Feb 25, 2020 I would look towards modern frameworks like React, Vue, etc., especially considering that CSP/ZEN/Mojo no longer develops.
go to post Vitaliy Serdtsev · Feb 25, 2020 The CSPBIND value is required at the compile-time to generate code on the client and server side. You try to change this value at runtime. See: CSP Page Lifecycle CSP Elements: Expressions
go to post Vitaliy Serdtsev · Feb 25, 2020 See: JSON Representation of a global structure Cogs Library Introducing InterSystems IRIS Document Database (DocDB)
go to post Vitaliy Serdtsev · Feb 24, 2020 If you have old version of Caché, you can use %ZEN.Auxiliary.jsonProvider or %ZEN.Auxiliary.altJSONProvider, which have a bunch of useful methods, for example: %ArrayToJSON %WriteJSONFromArray %WriteJSONStreamFromArray etc. Here are two small examples: set array=##class(%ListOfDataTypes).%New() for i=1:1:4000000 d array.Insert("item"_i) write "count = ",array.Count(),! do ##class(%ZEN.Auxiliary.altJSONProvider).%WriteJSONStreamFromObject(.stream,array,,,1,"aeloq") ; here you can save stream to a file or send it to the clientset meta=$lb("nameA","nameB","nameC") for i=1:1:4000000 set data(i)=$lb("itemA"_i,"itemB"_i,"itemC"_i) do ##class(%ZEN.Auxiliary.altJSONProvider).%ArrayToJSON(.meta,.data)
go to post Vitaliy Serdtsev · Feb 24, 2020 To Dmitry's words I will add a few links from the documentation: write [listname] (Caché List structured data displays in encoded form) List-Structure String Operations In your case, be the $LISTTOSTRING function is useful, for example: USER>set first=$lb("words","more","words") USER>write first words-morewords USER>write $listtostring(first) words,more,words USER>write $listtostring(first,"^") words^more^words USER>write $listtostring(first,"") wordsmorewordsI think that the result of "dogcatfish" in the book was due to copying/pasting, which caused the service characters to be lost. By the way, here on the forum it’s also not so easy to insert this gibberish ;)
go to post Vitaliy Serdtsev · Jan 30, 2020 Are you sure that the "cdate" type is a string ? Maybe %Date or %PosixTime? Even if leave a string, the result is highly dependent on ExtentSize. For example, if ExtentSize=10, the plans match.
go to post Vitaliy Serdtsev · Jan 30, 2020 See Users, Roles, and Privileges. In addition, you can optionally enable auditing.
go to post Vitaliy Serdtsev · Jan 24, 2020 It should be noted that this applies not only to the try/catch block, but also to other blocks, for example: f i=1:1:2 { q 1 ; runtime error, but the line is highlighted } do { q 2 ; compilation error }while(0) while 0 { q 3 ; compilation error }
go to post Vitaliy Serdtsev · Jan 23, 2020 And more food for thought: Class dc.test [ Abstract ] { /// d ##class(dc.test).test() ClassMethod test(N As %Integer = 10) { d ..Run1(N),..Run2(N),..Run3(N),..Run4(N) } ClassMethod Run1(N As %Integer) { f i=1:1:4 { s time(i,"start")=$zh f j=1:1:N { i i=2 { s a=20 } ElseIf i=3 { s a=30 } ElseIf i=1 { s a=10 } Else { s a=-4 } } s time(i,"end")=$zh } w "If i=2: ",?12,time(2,"end")-time(2,"start")," seconds",!, "ElseIf i=3: ",?12,time(3,"end")-time(3,"start")," seconds",!, "ElseIf i=1: ",?12,time(1,"end")-time(1,"start")," seconds",!, "Else: ",?12,time(4,"end")-time(4,"start")," seconds",!! } ClassMethod Run2(N As %Integer) { f i=2,3,1,4 { s time(i,"start")=$zh f j=1:1:N s a=$case(i,1:10,2:20,3:30,:-4) s time(i,"end")=$zh } w "i=1: ",time(1,"end")-time(1,"start")," seconds",!, "i=2: ",time(2,"end")-time(2,"start")," seconds",!, "i=3: ",time(3,"end")-time(3,"start")," seconds",!, "i=4: ",time(4,"end")-time(4,"start")," seconds",!! } ClassMethod Run3(N As %Integer) { f i=1,2,3,4 { s time(i,"start")=$zh f j=1:1:N s a=$case(i,2:20,3:30,1:10,:-4) s time(i,"end")=$zh } w "i=1: ",time(1,"end")-time(1,"start")," seconds",!, "i=2: ",time(2,"end")-time(2,"start")," seconds",!, "i=3: ",time(3,"end")-time(3,"start")," seconds",!, "i=4: ",time(4,"end")-time(4,"start")," seconds",!! } ClassMethod Run4(N As %Integer) [ ProcedureBlock = 0 ] { n i,time,j,a f i=2,3,1,4 { s time(i,"start")=$zh f j=1:1:N d $case(i,1:a1,2:a2,3:a3,:a4) s time(i,"end")=$zh } w "i=1: ",time(1,"end")-time(1,"start")," seconds",!, "i=2: ",time(2,"end")-time(2,"start")," seconds",!, "i=3: ",time(3,"end")-time(3,"start")," seconds",!, "i=4: ",time(4,"end")-time(4,"start")," seconds",!! q a1 s a=10 q a2 s a=20 q a3 s a=30 q a4 s a=-4 q } } USER>d ##class(dc.test).test(1000000) If i=2: .027962 seconds ElseIf i=3: .043612 seconds ElseIf i=1: .073138 seconds Else: .068023 seconds i=1: .035705 seconds i=2: .035941 seconds i=3: .03498 seconds i=4: .033288 seconds i=1: .078231 seconds i=2: .052477 seconds i=3: .066045 seconds i=4: .07372 seconds i=1: .051371 seconds i=2: .052017 seconds i=3: .050972 seconds i=4: .052397 seconds USER>d ##class(dc.test).test(1e6) If i=2: .060933 seconds ElseIf i=3: .071999 seconds ElseIf i=1: .094509 seconds Else: .096684 seconds i=1: .058554 seconds i=2: .058182 seconds i=3: .059299 seconds i=4: .054863 seconds i=1: .09973 seconds i=2: .074734 seconds i=3: .087673 seconds i=4: .097123 seconds i=1: .082372 seconds i=2: .084538 seconds i=3: .081647 seconds i=4: .079353 seconds
go to post Vitaliy Serdtsev · Jan 23, 2020 Hi Peter. Ok. w "Time for If (i=2): ",time(2,"end")-time(2,"start")," seconds",!, "Time for ElseIf #1 (i=3): ",time(3,"end")-time(3,"start")," seconds",!, "Time for ElseIf #2 (i=1): ",time(1,"end")-time(1,"start")," seconds",!, "Time for Else (i=4): ",time(4,"end")-time(4,"start")," seconds",!! 1e6 Time for If (i=2): .030974 seconds Time for ElseIf #1 (i=3): .045126 seconds Time for ElseIf #2 (i=1): .07144 seconds Time for Else (i=4): .087353 seconds 1e9 Time for If (i=2): 28.59286 seconds Time for ElseIf #1 (i=3): 43.044261 seconds Time for ElseIf #2 (i=1): 82.277535 seconds Time for Else (i=4): 69.212718 seconds