发布新帖

查找

摘要
· 四月 29

A chance to win the InterSystems READY 2025 pass and hotel!

Dear Developer Community member,

There's still time to take part in our developer challenge to win hotel accommodation and free passes to the InterSystems READY 2025!

🎯 Code Your Way to InterSystems READY 2025

Duration: April 21 - May 04, 2025

Task:

  1. Upload an IRIS-based side project to Open Exchange. Be creative - it can be useful, quirky, fun, or just something you've always wanted to try.
  2. Record a short inspirational video (up to 5 minutes):
    • Tell us how InterSystems technologies or the Developer Community impacted your project or career.
    • Explain why YOU should get a ticket to the InterSystems READY 2025.
  3. Submit your video and a link to your app via this form.

>> Full details here

Let's celebrate creativity together. Get ready for the future!

问题
· 四月 29

How to access a stream property in a SQL trigger

I have an IRIS persistent class with a %Stream property whose value is a JSON object. I'd like to use a SQL trigger to pull some value out of the JSON and persist it in another property, for easy querying and indexing. See below for a minimal example:

Class PAB.DebugStream Extends %Persistent
{

Property Contents As %Stream.GlobalCharacter;
Property msg As %String;
ClassMethod InsertRow()
{
    set stream = ##class(%Stream.GlobalCharacter).%New()
    $$$ThrowOnError(stream.Write({"msg":"hello world!"}))
    &sql(insert into PAB.DebugStream (Contents) values (:stream))
    $$$ThrowSQLIfError(SQLCODE, %msg)
}

Trigger ExtractKeys [ Event = INSERT/UPDATE, Foreach = row/object, Time = AFTER ]
{
    new contentsJSON, id, msg
    if {Contents*C} {
        set contentsJSON = {}.%FromJSON({Contents})
        set id = {ID}
        set msg = contentsJSON.msg
        &sql(update PAB.DebugStream set msg = :msg where Id = :id)
        $$$ThrowSQLIfError(SQLCODE, %msg)
    }
}
}

However, the SQL insert fails in the trigger with a JSON parsing message like this:

<THROW>InsertRow+9^PAB.DebugStream.1 *%Exception.SQL -415 -415 InsertRow+9^PAB.DebugStream.1 Error occurring during INSERT in table 'PAB.DebugStream':  $ZE=<THROW>%FromJSON+22^%Library.DynamicAbstractObject.1 *%Exception.General Parsing error 3 Line 1 Offset 1

If I log the value of {Contents} in the trigger, it's not the stream object as I expect but an integer value.

How can I get the new value of a %Stream property in a SQL trigger?

I'm also open to suggestions about better ways to persist/index specific paths in a JSON property.

2 Comments
讨论 (2)1
登录或注册以继续
公告
· 四月 29

Préparez-vous, soyez prêt, obtenez la certification !

Vous prévoyez de participer à l'InterSystems READY 2025 (du 22 au 25 juin), le sommet mondial de cette année ?

Get Certified at InterSystems READY 2025, June 23-25, Orlando, FL

🏁 Si oui, tentez votre examen de certification gratuitement !

Prouvez vos compétences en technologie InterSystems et obtenez notre certification de haut niveau dans l'un des huit domaines proposés.

Examens inclus :

  • Spécialiste d'interface InterSystems HL7®
  • Spécialiste InterSystems IRIS SQL
  • Spécialiste technique HealthShare Unified Care Record

👩‍💻Si vous êtes titulaire de la certification Spécialiste InterSystems SQL, vous pouvez également passer le nouvel examen InterSystems IRIS SQL Professional (en version bêta) !

Consultez la liste complète des examens disponibles. Préparez-vous dès maintenant et réservez votre place !

👉 Obtenez votre certification à READY 2025 !

讨论 (0)1
登录或注册以继续
文章
· 四月 29 阅读大约需 4 分钟

Tiempos de respuesta al usar SQL dinámico y SQL embebido

Cuando trabajáis con InterSystems IRIS, los desarrolladores y arquitectos de bases de datos a menudo se enfrentan a una decisión crítica: si usar SQL Dinámico o SQL Embebido para consultar y actualizar datos. Ambos métodos tienen sus propias fortalezas y casos de uso, pero comprender sus implicaciones en el rendimiento es esencial para tomar la decisión correcta. El tiempo de respuesta, una métrica clave en la evaluación del rendimiento de las aplicaciones, puede variar significativamente dependiendo del enfoque de SQL que utilicéis. El SQL Dinámico ofrece flexibilidad, ya que las consultas pueden construirse y ejecutarse en tiempo de ejecución, lo que lo hace ideal para escenarios con necesidades de consulta impredecibles o altamente variables. Por el contrario, el SQL Embebido enfatiza la estabilidad y eficiencia al integrar el código SQL directamente en la lógica de la aplicación, ofreciendo tiempos de respuesta optimizados para patrones de consulta predefinidos.

En este artículo, exploraré los tiempos de respuesta al usar estos dos tipos de SQL y cómo dependen de las diferentes estructuras de clases y del uso de parámetros. Para ello, voy a utilizar las siguientes clases del diagrama:

Para probar los tiempos, creé la siguiente cantidad de objetos para cada clase:

  • Patient - 50M
  • Visit - 150M
  • Doctor - 500K
  • Address - 50M

De esta manera, esperaba que vierais tiempos razonables para la ejecución de las consultas y que pudierais observar las diferencias entre ejecutar SQL Embebido y SQL Dinámico. El único índice que añadí fue el índice automático de uno a muchos para la relación Doctor-Visit.

Así que vamos a ver las consultas que voy a ejecutar y, después, la duración de su ejecución:

  1. select count(*) from Hospital.Address
  2. select count(*) from Hospital.Address where State = :param
  3. select count(*) from Hospital.Patient left join Hospital.Address on p.address = a.id
  4. select count(*) from Hospital.Patient left join Hospital.Address on p.address = a.id where a.State = :param
  5. select count(a.Address->State) from Hospital.Patient a
  6. select count(*) from Hospital.Patient where p.Address->State = :param
  7. select count(p.Visit->VisitDate) from Hospital.Patient p
  8. select count(*) from Hospital.Patient where p.Visit->VisitDate > :param
  9. select count(v.Patient->Name) from Hospital.Visit v
  10. select count(*) from Hospital.Visit where v.Patient->Name %startswith :param
  11. select count(v.Patient->Address->State) from Hospital.Visit v
  12. select count(*) from Hospital.Visit where v.Patient->Address->State = :param
  13. select count(v.Doctor->Name) from Hospital.Visit v
  14. select count(*) from Hospital.Visit where v.Doctor->Name %startswith :param
  15. select count(*) into :p from Hospital.Visit where v.Doctor->Name %startswith :param and v.Patient->Name %startswith :param
  16. select count(*) into :p from Hospital.Visit where v.Doctor->Name %startswith :param and v.Patient->Name %startswith :param and v.Patient->Address->State = :param1

Obviamente, lo anterior es la sintaxis para SQL Embebido (porque hay parámetros nombrados). Para SQL Dinámico, las consultas son casi iguales, pero en lugar de parámetros nombrados, tenéis parámetros no nombrados 😉. Por ejemplo, para la última consulta, tengo la siguiente consulta:

select count(*) from Hospital.Visit v where v.Doctor->Name %startswith ? and v.Patient->Name %startswith ? and v.Patient->Address->State = ?

Ahora, vamos a echar un vistazo a los resultados:

No of query Embedded SQL (sec) Dynamic SQL (sec)
1 49 12
2 3 3
3 32 26
4 47 46
5 48 46
6 47 46
7 1767 1806
8 1768 1841
9 31 26
10 83 81
11 41 45
12 73 71
13 23 26
14 1 1
15 2 2
16 3 3

Podéis ver un gran valor atípico, que es la primera consulta. El SQL Embebido tardó mucho más tiempo en ejecutarse que el SQL Dinámico. Ejecutando las mismas consultas varias veces obtuve más o menos el mismo resultado. Así que es lo que es.

En general, podéis ver que la relación padre-hijos es mucho más lenta desde el lado de la propiedad de los hijos, aunque todos los datos de Patient y Visit estén almacenados en el global de Patient. El índice salvó la situación para la relación de uno a muchos, y el tiempo de ejecución fue considerablemente más corto. En conjunto, el tiempo de respuesta es mayormente similar y difiere en menos del 10%; a veces, incluso es el mismo. Por supuesto, utilicé consultas simples que no tardaron demasiado en prepararse, así que esta etapa casi podría ser ignorada.

讨论 (0)1
登录或注册以继续
公告
· 四月 29

Get READY, get set, get certified!

Are you planning to attend InterSystems READY 2025 (June 22–25), this year's global summit?

Get Certified at InterSystems READY 2025, June 23-25, Orlando, FL

🏁 If so, take advantage of a free certification exam attempt! 

Prove your skills in InterSystems technology and earn our highest-level credential in one of eight areas.

Exams include:

  • InterSystems HL7® Interface Specialist
  • InterSystems IRIS SQL Specialist
  • HealthShare Unified Care Record Technical Specialist

👩‍💻If you hold the InterSystems SQL Specialist certification, you can also try the new InterSystems IRIS SQL Professional exam (in beta)! 

See the full list of available exams. Start preparing now, and reserve your spot early!

👉 Get certified at READY 2025!

讨论 (0)1
登录或注册以继续