Robert Cemper · Jun 3, 2019 go to post

Assuming you get the call string as the variable parameter then

for par="SERVER","PORT","NAMESPACE" set @par=$P($P(parameter,par_"=",2),":") zw @par
SERVER="127.0.0.1"
PORT=1972
NAMESPACE="SAMPLES"
Robert Cemper · Jun 3, 2019 go to post

Sorry you didn't  publish the definition of  color  .

so assuming it is a $LB( ) structure   $LISTTOSTRING(color,',') may cover your needs.  It's an SQLFUNCTION too!

just LIST(color)   is wrong as it produces a comma-separated list of MULTIPLE records.  

Robert Cemper · Jun 2, 2019 go to post

you can delete the class in Studio or from SMPortal.
so you delete the class DEFINITION and the related table DEFINITION. but no  data.

BUT.

DROP TABLE in SQL also deletes the data  AND the definition because this is part of SQL Standard. (Se also MySQL)

I'd suggest you take some time to really read the documentation or consume some online training.
 

Robert Cemper · Jun 1, 2019 go to post

" In MySQL, a "view" is just a saved SQL query - dropping a view does not drop data. 
I never imagined dropping the class  (which I thought was just a view) would empty the global. 
The global was still there, but all the data was gone. "

Caché is different from MySQL but has also VIEWS and dropping a View doesn't touch any Data

But identical as in MySQL DROP TABLE deletes the data.

from http://www.mysqltutorial.org/mysql-drop-table
The DROP TABLE statement removes a table and its data permanently from the database. 

and this was your question:
So how else do I drop the table?

and later:
 I did one by DDL 

Robert Cemper · Jun 1, 2019 go to post

if you use DROP without option %NODELDATA  your data are gone. 
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=RSQL_droptable

Short Caché Basics:

  • all data are stored in globals, nowhere else
  • classes describe the structure how data are stored and can be accessed as Objects or Tables. 
  • classes never change, generate or delete data, but provide methods to do so.

so having 3 'tables' on the same global is just having 3 views of the same house.

Recommend readings: Long Caché Basics and Introduction to Caché SQL

Robert Cemper · Jun 1, 2019 go to post

IF you have seen the "Light weight Excel"  and its  Open Exchange  Repository
then all you have to do is

- open your file 

- use your file

execute OnPage method (from example or your personal  variation of it)

- close your file

BINGO!

to make it easier the referred method here:

ClassMethod OnPage() As %Status
 {
 set sqlStatement="SELECT TOP 23 ID,Name,%ODBCOUT(DOB) DOB,SSN FROM Sample.Person"
    ,query = ##class(%ResultSet).%New()
    ,sc = query.Prepare(sqlStatement)
  set:sc sc=query.Execute()
  quit:'sc sc
  set cols=query.GetColumnCount()
  write "<table border=1>",!,"<tr>"
  for col=1:1:cols {
   write "<th align=left><b>"_query.GetColumnHeader(col)_"</b></th>"
   }
  while query.Next() {
   write "</tr>",!,"<tr>"
    for col=1:1:cols {
      write "<td>"_query.GetData(col)_"</td>"
     }
   }
  write "</tr>",!,"</table>"
  quit $$$OK
 }
 
Robert Cemper · May 31, 2019 go to post

OK. I experienced that scenario quite often. sad

Suggestion to verify that indices will help you.
- Take a typical class definition, make a copy without storage definition (or remove it)
- compile it with Chaché Default storage and  run  INSERT INTO new.table SELECT * from old.table a flat table scan
- verify the new table against your needs. 
- if it fits then the problem has moved to "update frequency" which might be easier to solve.
It's, of course, limited to the critical tables and not the whole DB

Robert Cemper · May 31, 2019 go to post

In your case, you have to KILL the underlying globals manually.
As seen in Storage definition

eg. <Global>^SVK</Global>  and all others too that you didn't publish

What I've seen so far DDL enabling might not fit your expectations because of that ancient mapping.
(looks like late 80ties or before) 

Robert Cemper · May 31, 2019 go to post

You shouldn't be so much concerned on looping the RecordSet
INSERT ...... SELECT ....  
looks smaller and smarter  but does basically the same

Robert Cemper · May 31, 2019 go to post

Well the code you posted shows a rather ancient type of table mapping away from standards.

And the errors you got underlines this as standard methods like %BuildIndices and %PurgeiIndices are not implemented.

I see 3 possible options:
- you find in the code (not necessarily in the class definition) some method to (re) generate the indices. 
Without experience with Caché and Object Script a rather impossible task.

- you create a copy of the class definition and move all data there by INSERT INTO new.table SELECT * from old.table
but it is unclear from what you showed to us if INSERT into your table is supported at all 

- least risky. you out-comment all broken indices except [IDKEY] and just use a flat table scan.
this is a fast workaround at the price of a poor performance on bigger tables.

honestly. - not a funny situation
 

Robert Cemper · May 31, 2019 go to post

You gave the answer already!

By compilation, you DEFINE indexes at their rules.

But you need to generate their content separately by ClassMethod 

 in each class.

Or from management portal. 

Then they are ready to use.

Robert Cemper · May 31, 2019 go to post

There is another way directly with SQL 

First, you CREATE a temporary table according to your needs (or have it ready)

CREATE GLOBAL TEMPORARY TABLE MyTemp.Table temp1, temp2, . . . . .

Next, you fill it by INSERT directly from SELECT

INSERT INTO  MyTemp.Table  (temp1,Temp2, . . .) 
      SELECT COL1,COL2, ...   FROM Source.Table WHERE ...... 

The select is the same as before.

Robert Cemper · May 30, 2019 go to post

give your anchor tag an ID and modify it using some JS script.

or use %ZEN.Auxiliary.locatorLink or any other element that allows a  HREF.

or trigger it with JS from any onclick event or similar. 

It's not much ZEN but pure JS

Robert Cemper · May 30, 2019 go to post

Hola Francisco !

Málaga is a splendid place. 
I was there several times privately (with all related sightseeing) and on business.
Always a great experience! 
I wish my Spanish (reading) was not so rusted to assist in tranlsation of articles.

especially this one Uso de expresiones regulares en ObjectScript

Bienvenido, Robert

Robert Cemper · May 27, 2019 go to post

Independent of the way how your servers are linked It might be the easiest to have  SOAP service to call each other passing the lab episode number '1119102928' as a parameter.

If a lock exists it will be removed. if not nothing happens.

Studio has an easy to use SOAP wizard to create the Server and Client part.
 

Robert Cemper · May 24, 2019 go to post

Francisco,

instead of FOR EACH which obviously uses a nonexisting   Next method
you could create a loop using <WHILE> and do a "manual" loop.

For the condition   source.retorno.datos.polizas.poliza.%Size() gives you the  index limit

and source.retorno.datos.polizas.poliza.%Get(idx).sucursal   .... and similar provides the content. 

You have to increment idx manually and it runs from 0 (zero!) to %Size()-1

It's not as elegant as <foreach> but you have control over your JSON input.

Robert Cemper · May 24, 2019 go to post

You can get the pid without iteration.

set nsp=$znspace
set pid=^$|nsp|lock("^DBLock(""Patient"",1119102928)","OWNER")
do $system.Process.Terminate(pid)

|nsp| is only required for access to a lock in a different namespace.

Robert Cemper · May 22, 2019 go to post

as you describe if you refer to a file outside Caché and Caché has no control over it
it's a clear case of data inconsistency

you have 4 options:
1a) create a fake file at that reference an delete it then

1b) add an "on before delete" trigger to check and fix in advance either in the record or  in file system 

2a) manipulate the file reference using the object behind your entry

2b) do the delete at object level, trap the error and ignore it. since the file is gone anyway 

Robert Cemper · May 17, 2019 go to post

when you generate Classes from XSD you require a reference. That' s where xsd is stored.  It may make sense to ich copy it first to your default repository and generate your classes after.

Robert Cemper · May 14, 2019 go to post

In fact, I see not 1 but 2 tables that share the same global.

so it might be easier to have 2 separated definitions one with and the other without the  4th subscript (some $h)

for access with SQL you than can use a UNION to assemble them. like:

SELECT * FROM (
     SELECT Account, PGC, Entity, ' ' as DateTime, ..fields... FROM TAB1 WHERE <some condition >
     UNION ALL
     SELECT Account, PGC, Entity, DateTime, ..same as above... FROM TAB2 WHERE <same condition >
) order by 1,2,3,4

or  you decide to add the missing subscript in your global to have a common structure

Robert Cemper · May 10, 2019 go to post

Thank you Dan!

So after years, I realized what the proper use of  [ Identity ] is.
It's well documented .  Anyhow it passed my attention.

yes  Thanks for the clarification.

Robert Cemper · May 8, 2019 go to post

If this is Caché standard ID it is projected to SQL as xDBC Type INTEGER
Caché SQL Reference - Data Types says:

INTEGER %Library.Integer (MAXVAL=2147483647, MINVAL=-2147483648)

so 5983658923646 is definitely out of range

xDBC Type :

   represents a 64 bit integer value.

I'm not aware of any parameter to change the data type of the generated ID.
But this hack may do the trick. Just add this calculated Property to your class without affecting the storage.

Property myID As %BigInt [ Calculated, SqlComputeCode = { set {*}=%ID}, SqlComputed ];
 

Robert Cemper · May 6, 2019 go to post

As long as you don't go for Sharding this might work quite well.

For Sharding the whole storage environment will make a significant difference also in class definitions.
 

Robert Cemper · May 6, 2019 go to post

I tried it now in Caché 2016.2.2 manually overwriting Storage <Type>%Storage.Persistent</Type>.

During compilation it gets automatically set back to  <Type>%Library.CacheStorage</Type>
Also in class defintion.

Does this automatic change go back to repository ??? 

Robert Cemper · May 6, 2019 go to post

At first sight in Documatic, it  looks like 

 was just renamed to  

%Storage.Persistent

As a workaround, I would simply try in Caché to make a copy of  %Library.CacheStorage to a new %Storage.Persistent
(a pure rename)  Then compile a class with one and the other and compare the generated .int code.

It's a dirty hack. frown
But I have no hope ISC will ever provide some backward port from IRIS to Caché.

Sorry I have no IRIS at hands and can't try it myself.

Robert Cemper · May 5, 2019 go to post

score

-1  #1 - disagree, see no valid reasoning

-2  #2 - strongly disagree

-1 #3 - disagree because of #2

+1 #4- agree

+1 #5 - agree

+1 #6 - agree . pls.send enhancement req. to engineering

+0 #7 - not clear about the message ? an oref is neither primitive nor dynamic

+0 #8 - miss imagination of inconsistent return types

+0 #9 - don't understand that message
 

Robert Cemper · May 2, 2019 go to post

It's really a matter of taste.

If you don't like the long list of params (especially with lousy documented methods) you can

#1) use 1 single param and pass a local array byRef .  and decode it yourself eg:

par("IPadrr")="127.0.0.1")
par("Port")=1972
par(Namespace")="SAMPLES"

.....
do  ##class(my.par).method(.par)

or

#2) use the traditional style you may know from Caché I/O Device Guide  having also just 1 parameter

do  ##class(my.pieces).method("/SERVER=127.0.0.1:/PORT=1972:/NAMESPACE=SAMPLES")

I personally prefer #2) as it gives you an embedded doc on your intentions.

Robert Cemper · Apr 29, 2019 go to post

#1) all documentation on XML is here

It covers everything to output Objects to XML.

#2) to fill  this in-between object you may use the SQL Table represented by an object class.
 as simple INSERT  INTO  my.xmltable select .........

You just have to take care that the object class also extends %XML.Adapter .
That makes it ready for XML Export.  All details described in docs