It is better to check this with your license, as it is likely that some of its options, such as Web Add-on, may affect this (see $SYSTEM.License.PublicWebAppUser).
- Log in to post comments
It is better to check this with your license, as it is likely that some of its options, such as Web Add-on, may affect this (see $SYSTEM.License.PublicWebAppUser).
The %SYS namespace sources are open to study and often (but not always) serve as a coding etalon reference for application developers. This is a whole storehouse of knowledge for those who want to better understand certain mechanisms work of system classes.
If some of the commands found there are not documented, but effectively do useful work, then why can't they be used by application developers?
In addition, I do not rule out the fact that some of them are simply forgot to document.
What really needs to be hidden or potentially dangerous is already hidden in the deployed classes.
Hi Robert.
I also got carried away with this question and found two more ways to use indexes for a list of serial objects, and you can explicitly specify specific fields in the query, rather than $list (%Value,3).
The speed may be not always the best, but I did the best I could. I tested on Caché (perhaps something has been improved in IRIS in this regard?)
If you're interested, I can share it.
zen(id) works with the component object model, and document.getElementbyId(id) works with the document object model.
Try the following:
s status=$$DeleteSession^%SYS.cspServer("wuuZ2Gwgxw")
This is not documented or supported. Use at your own risk.
But since you specified Caché 2018.1, which is no longer being developed so not may change in the future (not counting security patches).
Topicstarter indicated Caché 2018.1, which is no longer being developed so not may change in the future (not counting security patches)
Unfortunately, %INLIST does not use indexes (at least it was in Caché, I do not know how it is now in IRIS), which I made a note about in my article.
$LISTFIND certainly does its job well, but there is a better solution.
As the data grows, the search speed will drop, since this solution does not use indexes in any way. Therefore, the best solution is to use the predicate FOR SOME %ELEMENT.
For more details with examples, see one of my articles: SQL Performance Resources (item k. Indexing of non-atomic attributes)
Only customers with the corresponding paid valid service have access to the download from WRC (see in the price list the section Services Fees: Software Updates, Technical Assistance).
Those who use the Community Edition or who have expired, can not download anything from there.
Therefore, in this case, open resources, such as Github or FTP, are more preferable.
Try the following:
SAMPLES>set sc=$$GetSecurityUserInfo^%SYS.SECURITY($username,.p)SAMPLES>zwrite p
p("AccountNeverExpires")=..
p("AutheEnabled")=..
p("ChangePassword")=..
p("Comment")=..
p("CreateDateTime")=..
..
p("FullName")=..
p("Roles")=..
p("PhoneProvider")=..
p("Routine")=..
p("SuperUser")=..
The interactive tutorials with exercises built into the documentation helped me a lot in my time:
Also included was a database "SAMPLES" (code and data) with examples for every taste. I often used it for performance testing.
In addition, in the <cachesys>\dev\ folder there were numerous demos with source code for various programming languages and connection technologies (С++, C#, Java, PHP, Python, ODBC, JDBC, ADO.NET, ActiveX, XEP, etc.):
Incomplete content
\dev\tutorials\
\dev\tutorials\csp
\dev\tutorials\java
\dev\tutorials\mv
\dev\tutorials\pojo
\dev\tutorials\security
\dev\tutorials\UnitTestEx
\dev\tutorials\webservices
\dev\tutorials\zen
\dev\Cache\
\dev\Cache\callin
\dev\Cache\callout
\dev\Cache\cctrlcpp
\dev\Cache\cctrlvb
\dev\Cache\ctrldemo
\dev\Cache\HAcluster
\dev\odbc\samples\
\dev\odbc\samples\php
\dev\odbc\samples\select
\dev\odbc\samples\sqlgateway
\dev\python\
\dev\python\samples
\dev\python\samples3
\dev\cdirect
\dev\cpp\samples
\dev\dblib\samples
\dev\dotnet\samples
\dev\java\samples
\dev\mv\samples
\dev\node.js\samples
\dev\perl\samples
And now it's right?
N<=9 (59 chr)
N>9 (62 chr)
Code
f n=1:1:n f j=n-1:-1:1,0:1:n w !?j f i=1:1:n-j,i-1:-1:1 w i#10 (62 chr)
Who is shorter? ;)
Sorry, I didn't notice. Updated
try{$$$ThrowOnError(##class(%XML.XPATH.Document).CreateFromString("<a><b><c>some content</c></b></a>", .doc))
$$$ThrowOnError(doc.EvaluateExpression("/a", "b", .field))
#dim obj As %XML.XPATH.DOMResult = field.GetAt(1)
while obj.Read() {
if obj.HasValue {
write obj.Path,": ",obj.Value,!
}
}
}catch(ex){
write "Error ", ex.DisplayString(),!
}
Result:
b\c\: some content
PS: Once upon a time (when was Caché) there was a wonderful DOCBOOK database that had the methods you needed.
Here's my old (2012 sic!) article on this topic: Extending the built-in documentationRU->EN
Here you can read a little more:
There is another way.
If you want any empty strings to always be treated as null/"" instead of "/$c(0), then there is an documented setting (within the scope of namespace), namely:
^%SYS("sql","sys","namespace",<YOUR_NAMESPACE>,"empty string")
Here is a small example:
Class dc.test Extends %Persistent
{ Property i As %Integer; Property str As %String; /// do ##class(dc.test).Test()
ClassMethod Test()
{
do ..%KillExtent()
try{
do $system.SQL.Purge()
set ^%SYS("sql","sys","namespace",$namespace,"empty string")=$c(0); '' -> $c(0)
do ##class(%SQL.Statement).%ExecDirect(,"insert into dc.test(i,str) values(1,'')")
; null -> ""
do ##class(%SQL.Statement).%ExecDirect(,"insert into dc.test(i,str) values(2,null)")
do $system.SQL.Purge()
set ^%SYS("sql","sys","namespace",$namespace,"empty string")=""; '' -> ""
do ##class(%SQL.Statement).%ExecDirect(,"insert into dc.test(i,str) values(11,'')")
; null -> ""
do ##class(%SQL.Statement).%ExecDirect(,"insert into dc.test(i,str) values(22,null)")zwrite ^dc.testD
kill ^%SYS("sql","sys","namespace",$namespace,"empty string")
}
catch(ex){
write ex.DisplayString(),!
}
}}
USER>do ##class(dc.test).Test()
^dc.testD=4
^dc.testD(1)=$lb("",1,$c(0))
^dc.testD(2)=$lb("",2,"")
^dc.testD(3)=$lb("",11,"")
^dc.testD(4)=$lb("",22,"")
Another option just for the fun:
Include %SYS.PTools.Stats Class dc.test [ Abstract ]
{ ClassMethod setValue(args...) As %Status
{
quit:args<2 $$$ERROR($$$DataMissing)$$$convertArrayToList(args,list)
quit:$listlength(list)'=args $$$ERROR($$$RequiredArgumentMissing)
set $list(list,*,*)="",
var=##class(%Utility).FormatString(list),
$extract(var,1,3)=$name(%sessionData), ##; or $name(%session.Data)
@var=args(args)
quit $$$OK
} /// do ##class(dc.test).Test()
ClassMethod Test()
{
new %sessionDatatry{
do $system.OBJ.DisplayError(..setValue("key1", "val1")),
$system.OBJ.DisplayError(..setValue("key1", "key2", "key3", "key4", "val2")),
$system.OBJ.DisplayError(..setValue("key1", "key2", , "key4", "val3")),
$system.OBJ.DisplayError(..setValue())
write !
zwrite %sessionData
}
catch(ex){
write ex.DisplayString(),!
}
}}
See also $SYSTEM.SQL.Schema.QueryToTable()
Try it with between 1 and 5 on the %VID. Just as slow.I ran your code with new index. count(prop1=2) = 2629833
%VID BETWEEN 1 AND 5 .000293 secs
%VID BETWEEN 2629829 AND 2629833 3.63472 secs
I can't create an index on every possible filter and order by combination.Waiting for @Kyle Baxter response.
Try adding a new index and don't forget make rebuild index/tunetable/recompile class
Index idx On (prop1, prop3) [ Type = bitmap ];
Here yet need the help of @Kyle.Baxter.
PS: by the way, check
select count(*) from mp.test where prop1=2
to insert the correct values in the code
%VID BETWEEN 3000000 AND 30000005
Because of this, is obtained
0 Rows(s) Affected
I don't think I quite understand you.
That is, you need to:
SELECT * FROM <table> WHERE <difficult condition> ORDER BY <some field> DESC
select * from (step1) where %VID between N1 and N2
If not, provide a ready-made example with data similar to the example by @MARK PONGONIS
Source code
f i=1:1:total s ^mp.testD(i)=$lb("","name","prop2",$r(30))
d sql.%Prepare("SELECT %ID,prop3 FROM mp.test WHERE %ID IN ("_
s rset=sql.%Execute(1,5)
w $$$FormatText("last 5 [%1:%2]",count-N+1,count),!
s rset=sql.%Execute(count-N+1,count)
}
USER>d ##class(mp.test).Fill(5000000)
USER>d ##class(mp.test).Query()
count=3833346
first 5 [1:5]
ID prop3
3 3
4 3
24 3
30 3
97 3
5 Rows(s) Affected
.000328 secs
last 5 [3833342:3833346]
ID prop3
4999798 1
4999817 1
4999836 1
4999866 1
4999947 1
5 Rows(s) Affected
2.884304 secs
PS: for those who put a minus. May I ask why?
There is at least one case where this encoding style is acceptable - it is a generator method. Just look at the code generated by &sql() or CSP, for example. No wonder there are two versions for javascript libraries: for the developer and for production (processed by the minimizer).
And what if the answer is given, but the author either does not want to accept the answer at all or does not make a more elegant decision?
https://community.intersystems.com/post/there-way-defermine-column-jsonobject#comment-128086 https://community.intersystems.com/post/creating-json-objects-objectscript-objects#comment-125371
My EAV implementation is the same as your Approach 3, so it will work fine even with fully filled 4.000.000 attributes. Since the string has a limit of 3,641,144, approaches with serial and %List are dropped.
All other things being equal, everything depends on the specific technical task: speed, support for Objects/SQL, the ability to name each attribute, the number of attributes, and so on.