Robert Cemper · Aug 2, 2018 go to post

for cleaning up:

/// to get rid of old versions
/// select OBJ.DSTIME_DelVersion('Table',Version)
/// 
ClassMethod DelVersion(Table As %String = " "Version As %Integer = 0) As %Integer [ SqlProc ]
{
 Quit:'$l(Table) '$$$OK
 Kill ^OBJ.DSTIME(Table,+Version)
 Quit $$$OK
}

 
Robert Cemper · Aug 2, 2018 go to post

All I know about python is  "Monty Python" smiley

OK.

The table you want to control needs to get a parameter   Parameter DSTIME = "AUTO";  and a recompile

Then you can use this class to trace  changes, new, delete

/// Handle DSTIME using SQL
/// 
select * from OBJ.DSTIME where version = lastversion
/// to show all
Class OBJ.DSTIME Extends %Persistent [ Final, SqlRowIdPrivate {
Index idx On (Table, Version, RowID) [ IdKey ];
Property Version As %Integer [ ReadOnly, SqlColumnNumber = 2 ];
Property Table As %String [ ReadOnly, SqlColumnNumber = 3 ];
Property RowID As %String [ ReadOnly, SqlColumnNumber = 4 ];
Property Signal As %Integer(DISPLAYLIST = ",Modified,New,Deleted", VALUELIST = ",0,1,2")
   [
Calculated, , SqlComputedSqlColumnNumber = 5,
     SqlComputeCode = { set {*}=^OBJ.DSTIME({Table},{Version},{RowID})}];
Property LastVersion As %Integer [ Calculated, SqlComputed, SqlColumnNumber = 6,
   
SqlComputeCode = { set {*}=+$G(^OBJ.DSTIME) } ];

/// to get actual last version and switch to new version
/// select top 1 LastVersion,OBJ.DSTIME_NewVersion(LastVersion) from OBJ.DSTIME
/// 
ClassMethod NewVersion(anycolumn As %String) As %Integer [ SqlProc ]
 Quit $I(^OBJ.DSTIME) }
Storage Default {
<DataLocation>^OBJ.DSTIME</DataLocation>
<IdLocation>^OBJ.DSTIMED</IdLocation>
<IndexLocation>^OBJ.DSTIMEI</IndexLocation>
<StreamLocation>^OBJ.DSTIMES</StreamLocation>
<Type>%Library.CacheStorage</Type>
}

 

 so get your actual changes

select * from OBJ.DSTIME where version = lastversion

and switch to next version by 

select top 1 LastVersion,OBJ.DSTIME_NewVersion(LastVersion) from OBJ.DSTIME

.

But you have to have full access to Caché as you have to make the DB "talking"  to be able to "listen"

Robert Cemper · Aug 2, 2018 go to post

If you have just SQL access you may wrap a class around  ^OBJ.DSTIME to  select changes

Robert Cemper · Aug 2, 2018 go to post

You have to test on server  = "www.intersystem.com"  not just domain.
443 is ok

 
USER>s req=##class(%Net.HttpRequest).%New()
USER>s req.SSLConfiguration="SSL"
USER>set sc=req.Get("https://www.intersystems.com")
USER>zw sc
sc=1
USER>set data=req.HttpResponse.Data
USER>do data.OutpuToDevice()
>>>>    lot of content  <<<<
Robert Cemper · Aug 1, 2018 go to post

There are some mistakes.

#1 the links should be "HTTPS://www.intersystems.com" and you didn't set a ssl/tls config.

if you use 

Set sc=httprequest.Get("http://www.intersystems.com",2)
Do $system.OBJ.DisplayError(sc)

you get ERROR #6159: ===> SSL missing

#2 HttpResponse is an ObjectReferce not a Property

set res=httprequest.HttpResponse
ZW res
 
res=<OBJECT REFERENCE>[3@%
Net.HttpResponse]
+----------------- general information ---------------
|      oref value: 3
|      class name: %Net.HttpResponse
| reference count: 3
+----------------- attribute values ------------------
|    ContentBoundary = ""
|        ContentInfo = ""
|      ContentLength = 178
|        ContentType = "text/html"
|               Data = "4@%Stream.GlobalCharacter"   ;;; here is your reply
|Headers("CONNECTION") = "keep-alive"
|Headers("CONTENT-LENGTH") = 178
|Headers("CONTENT-TYPE") = "text/html"
|    Headers("DATE") = "Wed, 01 Aug 2018 15:25:05 GMT"
|Headers("LOCATION") = "https://www.intersystems.com/"
|  Headers("SERVER") = "nginx"
|  Headers("X-TYPE") = "default"
|        HttpVersion = "HTTP/1.1"
|       ReasonPhrase = "Moved Permanently"
|         StatusCode = 301
|         StatusLine = "HTTP/1.1 301 Moved Permanently"
+-----------------------------------------------------

The content is in a Stream!! 
So Write is totally inappropriate to show it. Instead:

do res.OutputToDevice()   ;;;or similar
HTTP/1.1 301 Moved Permanently
CONNECTION: keep-alive
CONTENT-LENGTH: 178
CONTENT-TYPE: text/
html
DATE: Wed, 01 Aug 2018 15:25:05 GMT
LOCATION: https://www.intersystems.com/
SERVER:
nginx
X-TYPE: default
 
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
Robert Cemper · Jul 30, 2018 go to post

You may also want to check your message against the definition in WSDL. (e.g with XMLspy or similar)
there are enough SOAP services around that don't fit to the WSDL they publish.

Robert Cemper · Jul 30, 2018 go to post

Hi Thomas,

If you generate your webservice from a WSDL  you should check your classes
for correct hierarchical structure AND for properties flagged as required in WSDL.
Typical situation: 
an address is optional but inside the address, the street is required.  
This can cause the whole address to be interpreted as required.
You may either remove the required in properties or before generating the classes you edit the WSDL ( often easier).
 

Robert Cemper · Jul 15, 2018 go to post

Your Sales Rep or Sales Engineer should also be a trustworthy resource.
(probably not on Sunday morning / afternoon)

Robert Cemper · Jul 14, 2018 go to post

As by your concrete question

Caché

InterSystems Caché® is a high-performance database that powers transaction processing applications around the world. It is used for everything from mapping a billion stars in the Milky Way, to processing a billion equity trades in a day, to managing smart energy grids.

Ensemble

InterSystems Ensemble® is a seamless platform for rapid connectivity and the development of new connectable applications. Ensemble users typically complete projects twice as fast compared to previous generations of integration products.

InterSystems IRIS

InterSystems IRIS Data Platform™ sets a new level of performance for rapidly developing and deploying important applications. All of the needed tools and capabilities are provided in a reliable, unified platform spanning data management, interoperability, transaction processing, and analytics.

more

Robert Cemper · Jul 13, 2018 go to post

I'm not aware of a "customized" collation.
But this might be an appropriate workaround:

- for your property, you define an additional calculated property that results out of your  customized collation
- for this new calculated property,  you define COLLATION = EXACT to avoid default surprises (SQLUPPER !!!)

If you index it, you should get what you expected without impact to the rest of your table

Robert Cemper · Jul 12, 2018 go to post

On Win you could just swith on terminal logging.

For Linux, you could connect to your server using PuTTY or similar and enable logging.

Or make your personal copy %GSIZE => %zGSIZE and disable the artificial page breaks.
(an interesting programming exercise)

Robert Cemper · Jul 11, 2018 go to post

$EXTRACT(string,*-4,*)
should do it .  * marks the last char in the string

*-4 ist he first of the last five chars

Robert Cemper · Jul 9, 2018 go to post

if there is a problem with the single quote it should be in the query above as well. 
Your LAB person may look different to it. No by SQL.

Robert Cemper · Jul 8, 2018 go to post

Very interesting result.

You fall in timeout even with CallbackComment IS NULL   !!!!!

so single quotes can't be part of the game. 
So this should also work

SELECT 
LENGTH(CallbackComment)
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 
AND CallbackComment IS NOT NULL

and this too

SELECT 
LENGTH(CallbackComment), CallbackComment
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 
AND CallbackComment IS NOT NULL

This will indicate that some empty (NULL)  element is causing the troubles.

It might make sense to initialize all NULL CallbackComments with something.

Robert Cemper · Jul 8, 2018 go to post

You can do an additional check directly in the table that holds CallbacKComment

From the Query Plan I  assume it is 

  • SQ. CB_Contact

 something like 

SELECT ID,
LENGTH(CallbackComment), CallbackComment 
FROM SQ.CB_Contact
WHERE CallbackComment IS NOT NULL

this should lead you to the critical point and someone with enough 
privileges could take a look at the stored data if it is really a single quote or something else

Robert Cemper · Jul 8, 2018 go to post

As it stops also with the REPLACE let'S do 2 other checks:

SELECT 
CallbackComment
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 
AND CallbackComment IS NULL

this verifies that the day plays no role

SELECT 
LENGTH(CallbackComment)
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 
AND NOT CallbackComment [ ''''

Now we exclude all single quotes
If this one fails means that we see a single quote but it might be some other character

I also changed to LENGTH as  it should not interfere with single quotes

[ is the contains operator

Robert Cemper · Jul 8, 2018 go to post

If you limit the result set and increase the number, does it show any rows or other impact?

SELECT TOP 50
REPLACE(CallbackComment  ,'''','?')
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 
Robert Cemper · Jul 8, 2018 go to post

So you also have no chance to add indices, check for implicit joins and other useful stuff.
And of course no terminal access.

Robert Cemper · Jul 8, 2018 go to post

OK. You found 801 entries  with ~200 k global  access.
and the query works as expected

So 

SELECT COUNT(*) 
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-10'

for Tuesday Apr.10 it should return 801  

What is the count for Monday  2018-04-09 ?  I 'd expect more

SELECT
 COUNT(*)
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 
Robert Cemper · Jul 8, 2018 go to post

As you see the query plan is significantly shorter.
Your original refers to 3 other tables.
To find out why and how to improve would require all table/class  & view definitions

  • SQ.CBPhoneResult_View
  • SQ.CBPH_Phone
  • SQ. CBPH_Result      your 2nd query ends here  
  • SQ. CB_Test      access to  CallbackComment starts here
  • SQ. CB_Order
  • SQ. CB_Contact

Without the related class definition it is hard to say how these tables link to each other

But you really should run it from the terminal prompt to see your result at least once:

Do you have developer access to your Caché  at all? 
Can you see the class definitions in Studio ? 

Robert Cemper · Jul 8, 2018 go to post

You may also reformulate your SELECT to read directly from the tables used
starting with the one holding  PhoneDateODBC and forget all the other burden.

Robert Cemper · Jul 8, 2018 go to post

OK,now your timeout is clear.
with a Relative Cost of  ~2 millions, your query requires some support to speed up.
You just see the first 6 empty results.

First reason: you run over ALL records in  ...PhoneMaster
with an inner loop in  ...Testmaster on IndexCall,OrdeCode, TestCode,...Result_Index

So your timeout is not surprising.

I'd suggest creating an Index on PhoneDateODBC to speed up your query. >>  lower  Relative Cost
with 2 million I'm quite sure that you even timeout over ODBC.

So I'm back to my earlier suggestion:
Let your query run from terminal prompt,
have a coffee or two and maybe it is completed then.

This is not your fault.
Blame the designer of that ugly VIEW

Robert Cemper · Jul 8, 2018 go to post

OK.
You use a Caché version before 2015.1 that doesn't know $TRANSLATE

It's then 

SELECT
 REPLACE(CallbackComment  ,'''','?')
FROM SQ.CBPhoneResult_View
WHERE PhoneDateODBC = '2018-04-09' 

I expect you will run into a timeout again.
So please click to "Show Query Plan" and let us see what's going on.

Additionally, on left border click to Views;
select  SQ.CBPhoneResult_View and get an Image similar to this

important part:  VIEW TEXT

Robert Cemper · Jul 8, 2018 go to post

OK. now the picture gets clear.

 the key problem looks as if a single ' is interpreted as a String delimiter.
so instead of naked CallbackComment 
You may try

$TRANSLATE(CallbackComment  ,'''','?')

(it's really 4single quotes, no typo)
So you replace the single quote by a non-conflicting character BEFORE the string is passed to ODBC   
This would prove that the single quote is the cause of trouble.

Robert Cemper · Jul 8, 2018 go to post

what product/component are you interested in?

  • IRIS
  • ENSEMBLE
  • HEALTHSHARE
  • CACHÉ
  • TRAK
  • iKNOW
  • DEEPSEE
  • ..
  • ...

and others is as wide as the whole software industry

please be more specific

Robert Cemper · Jul 7, 2018 go to post

in addition, it would be worth to see what your SQ.CBPhoneResult_View does.

By the ending VIEW I assume it is a View and not a Table:
So the complexity of the executed query is hidden and could be the real performance problem.