Long Strings

Description
Often in Cache when dealing with large strings you hit the 32,000 or 64,000 character limit. This can cause your programs to stop working and often requires you to write ad-hoc solutions each time this happens.

Note: From Cache '7.1 it is possible to have strings of up to 3,600,000 characters. This is off by default but can be enabled in the System Management Portal or by using $zu(69,69).

Here I have written some routines to deal with this issue, which you can use in situations where strings could potentiality hit the  Limit.

I call it the Block Global Utility.

What it does is use a global to store all or part of the string your working with. The string is split up into 30K ‘blocks’, accessed by a block counter. You build this string up and when it’s about to hit the limit the routines causes the block counter to increment and the next chunk of the string goes into the ^global(blockCount+1).

There are 5 routines, which work together to get the job done.

BLKSTR, BLKINC, BLKADD, BLKGET and BLKC.

In the code I have given you a global called ^UTILITY is used, but you can use whatever name you want. Just make sure you change it in all 5 routines.

Using the routines

You start the process by calling D BLKSTR($Job, “Name”) This kills the global subscript ^UTILITY($Job, ”Name”) and resets the block count for this subscript. The reason for using $Job and “Name” is so that concurrent users in multiple sections of a system can use the routines at the same time. You can even subscript further to ensure the accuracy of data.

You then build your string by calling D BLKADD($Job, “Name”, STR) STR=the string you wish to add.

The routines will take care of determining weather the new string will fit in to the current block.

That’s all there is to it, so how do you get it out again?

To get a chunk of your string out of the global, you call $$BLKGET($Job, “Name”, Block) Block=an integer, from 1 to the number of blocks. You can get the number of blocks by calling $$BLKC($Job, “Name”) So essentially, after you have built up your string, you could use a for loop like so. For i=1:1: $$BLKC($Job, “Name”) {       W $$BLKGET($Job, “Name”, i) }

Full Code listing

//Block Global Utility BLKSTR(Job,Name) //Start the block utility, kill it 	K ^DCSUTILITY(Job,Name) S ^DCSUTILITY(Job,Name,"BLOCK")=1 Q BLKINC(Job,Name) //Increment the block count S ^DCSUTILITY(Job,Name,"BLOCK")=$$BLKC(Job,Name)+1 Q BLKADD(Job,Name,STR,nb=0) //Add to the Global, check to see if the new string will fit, if not make new subscript //nb = force a new block increment, only do if first block contains data if nb=1 D BLKINC(Job,Name) if $LENGTH($Get(^DCSUTILITY(Job,Name,$$BLKC(Job,Name)))_STR)>30000 D BLKINC(Job,Name) S ^DCSUTILITY(Job,Name,$$BLKC(Job,Name))=$Get(^DCSUTILITY(Job,Name,$$BLKC(Job,Name)))_STR Q BLKGET(Job,Name,Block=1) //return a block from the global Q $Get(^DCSUTILITY(Job,Name,Block)) BLKC(Job,Name) //return number of blocks Q $Get(^DCSUTILITY(Job,Name,"BLOCK"))

Useful situation
This utility came about because retrieving large amounts of data from the server using Ajax or Server calls poses problems with regards to the MAX STRING error.

When wishing to pull down data exceeding the max string limit I simply make the call to the server, which uses the above routines to pack my string into the global. I ask the server to return the first block along with the total number of blocks. I then make subsequent calls to retrieve the remaining blocks until all the data is on the CSP page, either outputted as HTML or stored in a JavaScript variable, ready for the next step of my program.