go to post Robert Cemper · Dec 8, 2017 See details here:http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...especially:Sample Global Names and Their Uses The following are examples of the various kinds of global names and how each is used: ^globalname — a standard global ^|"environment"|globalname — environment syntax for an extended global reference ^||globalname — a process-private global ^|"^"|globalname — a process-private global ^[namespace]globalname — bracket syntax for an explicit namespace in an extended global reference ^[directory,system]globalname — bracket syntax for an implied namespace in an extended global reference ^["^"]globalname — a process-private global ^["^",""]globalname — a process-private globalyour case2) is a broken call for a label in a routine and has nothing to to with globalsprobably do a^myroutine3) looks like a broken condition on variable a also no globals arounda| could be the beginning of a OR ....see Symbols Used in ObjectScript
go to post Robert Cemper · Nov 30, 2017 You may take this approach:create an object based on Schema1: My.Schema1create an object based on Schema2: My.Schema2HowTo: => XML Schema Wizzard http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...Then you may use this method.Method GetCustomerInfo(schema1 as My.Schema1) As My.Schema2 [WebMethod]My.Schema1 is checked as input parameter according tothe generated classinside your Method you transform it to My.Schema2and return it. The most tricky thing might be how to reply to a request that doesn't match Schema1.
go to post Robert Cemper · Nov 30, 2017 Rebuild takes time - ONCEand gives you the unique chance to fill the created index in contiguous global content blocks.That pays back at ever access by less global pointer blocks whatever storage technology you use.
go to post Robert Cemper · Nov 28, 2017 Nicole,thanks for your input. I had my experience with CTRL+O by accident just a few minutes before your answer .It would be great if normal OUTLINE could do this as well.
go to post Robert Cemper · Nov 27, 2017 I'd suggest to use $LB() if you are not hit by the LongString limit.why: all packaging, selection,.... is already done and "hard wired" in C++ with $C() you may re-invent $LB() or $Piece() or similar. And you have to do it in COS.Same applies to local array where you may iterate over the structure in COS again.Nothing against COS but C++ (in COS Functions) IS faster
go to post Robert Cemper · Nov 26, 2017 A few recommendations:#2) save you original Global as you do otherwise. [Just to be Save]#1) In Studio Copy class has a checkbox to copy Storage Definition (=Globals) . Set it. In the new class add ClassParameter MANAGEDEXTENT=0 ; /// The <var>MANAGEDEXTENT</var> parameter can be set to 0 (zero) to cause the Extent Manager/// to ignore this class. If set to 1 then the Extent Manager will register globals used by/// the class and detect collisions. Unmanaged extents (MANAGEDEXTENT = 0) are not checked./// Currently, only classes using default storage (%Library.CacheStorage) can be managed.Parameter MANAGEDEXTENT As INTEGER [ Constraint = "0,1", Flags = ENUM ] = 1; So the old and the new class use the same Globals.Now go on with #3 to #6If you miss something in refactoring the damage should be limited as you just change names not the Storage in Globals.Assuming the change of ClassName is all you do.
go to post Robert Cemper · Nov 24, 2017 For %BuildIndices you may provide a list or use default. it doesn't affect sequenceexample from Sample.Person.1.Int %BuildIndices(pIndexList="",pAutoPurge=1,pLockFlag=0,pJournalFlag=1,pStartID="",pEndID="",pIgnoreIndexList="") public {if ($listlength(pIndexList)=1)&&($listget(pIndexList,1)="") { return 1 }Set class=$classname(),tBuildFlags=1,tBuildFlags(class)=$c(0,0,0,0,0,0)Set tPtr=0,tStatus=1,pJournalFlag=''pJournalFlagWhile $listnext(pIndexList,tPtr,tIndex) {continue:tIndex=""If '$d(^oddCOM(class,"i",tIndex)) {Set tStatus=$select(+tStatus:$$Error^%apiOBJ(5066,class_"::"_tIndex),1:$$AppendStatus^%occSystem(tStatus,$$Error^%apiOBJ(5066,class_"::"_tIndex)))}}If ('tStatus) RETURN tStatusif $listfind(pIndexList,"$Person") { set $Extract(tBuildFlags(class),1)=$c(1) }if ((pIndexList="")||($listfind(pIndexList,"FCOL"))),'$listfind(pIgnoreIndexList,"FCOL") { set $Extract(tBuildFlags(class),2)=$c(1) }if ((pIndexList="")||($listfind(pIndexList,"NameIDX"))),'$listfind(pIgnoreIndexList,"NameIDX") { set $Extract(tBuildFlags(class),3)=$c(1) }if ((pIndexList="")||($listfind(pIndexList,"SSNKey"))),'$listfind(pIgnoreIndexList,"SSNKey") { set $Extract(tBuildFlags(class),4)=$c(1) }if ((pIndexList="")||($listfind(pIndexList,"ZipCode"))),'$listfind(pIgnoreIndexList,"ZipCode") { set $Extract(tBuildFlags(class),5)=$c(1) }if ((pIndexList="")||($listfind(pIndexList,"dobx"))),'$listfind(pIgnoreIndexList,"dobx") { set $Extract(tBuildFlags(class),6)=$c(1) }If ((pIndexList="")||($Ascii(tBuildFlags(class),5))) && '$listfind(pIgnoreIndexList,"$Person") { set $extract(tBuildFlags(class),1)=$c($select((pStartID'="")||(pEndID'=""):1,1:2)) }Quit ..%BuildIndexInternal(.pLockFlag,.pAutoPurge,.pStartID,.pEndID,.pIndexList,.tBuildFlags,"^Sample.PersonD",1,.pJournalFlag,0) } %Save does it straight by ASSCII sorting of index names (lower after Upper case)See %SaveData(id) in the generated .int
go to post Robert Cemper · Nov 23, 2017 as documented inhttp://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...DATEPART delivers a %Integer value.Differently to %Date which has different display, logical and ODBC presentation %Integer does not follow any specific presentation but is just Integer and nothing else.And your input to DATEPART function is in any example the same: the logical value of TimeCreated.To cover your expectations you would need to adapt your input yourself. eg by %ODBCOUT() function.or the related LogicalToDisplay function.Your expectation that a data type %Integer does a revers research how it was calculated is just un-realistic.
go to post Robert Cemper · Nov 19, 2017 A Total different idea.if Transaction.Account is defined as Account object (could also be calculated) [ Property Account as Account ; ]then you may use implicit join for your query. it looks like this:select Account.Name, Account.State, Transaction.Amt, Transaction.Date, Transaction.Servicefrom Transaction left join Account on Account.Id = Transaction.Account where Transaction.Account in ( Select Account.Id from Account where Transaction.Account ->Type is not null and Transaction.Account->Id>123456789 and Transaction.Account->Id <=323456789 ) and Transaction.Date >= ?and Transaction.Date <= ?
go to post Robert Cemper · Nov 19, 2017 OK, that looks better now go to Mgmt Portal /SQL and verify for both tables that you see values in column Selectivity (marked)IF THERE IS NO SELECTIVITY ANY QUERY PLAN IS JUST GUESSWORK.if this is empty Query Generator just can guess and do a lot of unnecessary extra work.so got Tune Table click itand this you get there information that the Query Generator allows to make useful optimizations (marked)Next enter your specific query and click to "Show Plan"that marked information tells you what is happening and Relative Cost qualifies the expected performance. This query plan tells you what is really happening.
go to post Robert Cemper · Nov 19, 2017 At first sight I'd say the Query Generator is right as your Sub Select Just adds some more WHERE conditions.Your range on Transction.Date with related index might be much more limiting than your range on Account.Id.A index on Account.Type might also speed up your query. where Account.Id in ( Select Account.Name from Account?? Is Account.Name the same as Account.Id ??? IN ( ) expects EXACT VALUES !Suggestion if no done yet: Run tune Table for both tablesNext: publish the generated Query plan.
go to post Robert Cemper · Nov 15, 2017 A dirty hack:- make a new class extending %SerialObject with VALIDIFNULL set.- export your serial classes (to XML)- replace %SerialObject by your MySerialObject- reload the changed classes.Not so nice but I had the same issue with some 100 Serial Objects.The more sophisticated way would be do it programatically over %Dictionary.DefinedProperty ..... Very interesting and very time consuming
go to post Robert Cemper · Nov 15, 2017 You have to set $ZTRAP again at the begin:Or start with do infile^myroutine ....at the 1. run it is set i line 3you my also pass the filename as parameter
go to post Robert Cemper · Nov 15, 2017 Welcome back!infile ; simple file read set filename="C\mydir\myfile.txt" set $ZTRAP="end" open filename:("R"):0 else Write "file error" for line=1:1 use filename read text use 0 write text,! end close filename set $ZTRAP="" use 0 write "Done", quitit's not so sophisticated and I used the end-of-file error to exitThis is also available in class %Library.File with lot more comfort http://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?P...HTH
go to post Robert Cemper · Nov 15, 2017 Taskmanager is a part of Caché System Management and you should read the Docs.JOB is a COS command also used in Taskmanager but not only. Any routine may use it.So your Request / Question is just not clear
go to post Robert Cemper · Nov 13, 2017 Suggested solution:#1 create a ROLE with resources DOCBOOK (Readonly) + the required Nmaspaces#2 remove required resources %Development from web application /csp/documatic #3 next create a user with the new defined role (here: "docread")I decided not to give %Development as it could allow access to terminal prompt.
go to post Robert Cemper · Nov 10, 2017 something similar: start ; open infile:"R":0 else write "input file not found",! quit open outfile:"WNS":0 else write "error creating output file",! quit set $Zt="end" for line=1:1:5 { use infile read sql use 0 if $e(sql,1,6)'="SELECT" continue set rs=##class(%ResultSet).%New() set sc=rs.Prepare(sql) set:sc sc=rs.Execute() if 'sc write "bad SQL statement",! quit set cols=rs.GetColumnCount() use outfile;; fill in headers if required while rs.Next() { for cols=1:1:cols write rs.GetData(cols),$c(9) write ! } write !,"###",! use 0 } end set $ZT="" close infile,outfile quit !! NOT TESTED !!
go to post Robert Cemper · Nov 7, 2017 correct.OVER(PARTITION BYis an unknown keyword in documentation You may need to reformulate your query to achieve a similar result
go to post Robert Cemper · Nov 5, 2017 Found it:Exceptions to READ COMMITTED 1 of some moreIf you query contains an aggregate function, the aggregate result returns the current state of the data,regardless of the specified ISOLATION LEVEL. Therefore, inserts and updates are in progress (and may subsequently be rolled back) are included in aggregate results. Deletes that are in progress (and may subsequently be rolled back) are not included in aggregate results. This is because an aggregate operation requires access to data from many rows of a table.see:http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=...
go to post Robert Cemper · Oct 27, 2017 Hi Eduard !Being a little bit lazy I simplified the query (for less typing)My example: SELECT * FROM %Dictionary.StorageDataValueDefinitionwhere id [ 'Sample.Person'And it works fine for persistent and serial classes.My hidden assumption: there is only 1 Storage Strategy.The nice point about:you get also storage locations of deleted (!!) properties that eventually might be invisible in class definition.