Nova postagem

Pesquisar

Artigo
· Fev. 23 1min de leitura

Como rodar SQL no terminal

Rubrica de Perguntas Frequentes da InterSystems

Para executar SQL no Terminal, use $system.SQL.Shell().

Por favor, consulte o exemplo abaixo.

SAMPLES>do $System.SQL.Shell()
SQL Command Line Shell
---------------------------------------------------- The command prefix is currently set to: <>.
Enter q to quit, ? for help.
SAMPLES>>select * from Sample.Vendor
1. select * from Sample.Vendor Vendor Balance Contact DaysClear DiscDays DiscRate LastInvDate LastPayDate MinPayment Name NetDays PayFlag TaxReportingAddress_City Address_State Address_Street Address_Zip
: *If you press Enter without entering anything on the first line, it will switch to multi-line input mode.
USER>d $SYSTEM.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------
Enter q to quit, ? for help.
USER>> << entering multiline statement mode, 'GO' to execute >>
1>>set transaction isolation level read committed
2>>go

Para detalhes, por favor, consulte o documento abaixo.

Como usar SQLShell [IRIS]
Como usar SQLShell

Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· Fev. 23 4min de leitura

Creando respuestas FHIR con una producción de interoperabilidad en IRIS

Cuando creamos un repositorio FHIR en IRIS, tenemos un endpoint para acceder a la información, crear nuevos recursos, etc. Pero hay algunos recursos en FHIR que probablemente no tengamos en nuestro repositorio, por ejemplo, un recurso Binary (este recurso devuelve un documento, como un PDF, por ejemplo).

He creado un ejemplo en el que cuando se solicita un recurso Binary, el endpoint de FHIR devuelve una respuesta, como si existiera en el repositorio.

En primer lugar, necesitamos un Namespace y un endpoint FHIR. Después, necesitamos configurar una producción de interoperabilidad que se conectará al endpoint de FHIR. Esta producción debe tener estos elementos:

  • Business Operations:
    • HS.Util.Trace.Operations (de hecho, esto es opcional, pero puede ser muy útil)
    • HS.FHIRServer.Interop.Operation, con la propiedad TraceOperations establecida a *FULL*
  • Business Service:
    • HS.FHIRServer.Interop.Service, con la propiedad TraceOperations establecida a *FULL* y la propiedad Target Config Name con el valor del nombre de la operación HS.FHIRServer.Interop.Operation

Así es como se ve la producción:

Después de crear esta producción, necesitamos conectarla con el endpoint de FHIR. Por lo tanto, editamos el endpoint de FHIR y configuramos el parámetro Service Config Name con el nombre del Business Service:

Ahora, si comenzamos a enviar solicitudes al repositorio FHIR, veremos todas las trazas en el Visor de mensajes:

Ahora podemos tener un Business Process para controlar qué hacer con rutas específicas.

En este ejemplo tenemos un Business Process que recibe cada solicitud (ahora el Business Service está conectado a este Business Process, en lugar de la Business Operation) y 2 nuevas Business Operation que realizan otras acciones que se explicarán más adelante:

Veamos el Business Process llamado FHIRRouter:

Si echamos un vistazo, veremos que, si la propiedad RequestPath contiene "Binary/", entonces haremos algo con esta solicitud: generar nuestra respuesta Binary personalizada. De lo contrario, enviaremos la solicitud al repositorio FHIR directamente.

Veamos la secuencia llamada "Generate Binary":

En primer lugar, creamos una nueva instancia de HS.FHIRServer.Interop.Response. Y obtenemos el ID del documento de la propiedad RequestPath. ¿Cómo? Cada vez que alguien quiere un recurso Binary, debe solicitarlo con el ID del documento en la ruta URL, algo así: ..../fhir/r4/Binary/XXXXX. Por lo tanto, extraemos el ID del documento de la ruta con esta expresión:

$Replace(request.Request.RequestPath,"Binary/","")

(No es muy elegante, pero funciona).

Si tenemos un ID de documento, entonces realizamos una llamada a una Business Operation llamada Find para encontrar el nombre de archivo asociado a ese ID de documento:

De hecho, esta Business Operation Find siempre devuelve el mismo nombre de archivo:

Es un ejemplo de lo que podemos hacer.

Si tenemos un nombre de archivo, entonces, llamamos a otra Business Operation llamada File para obtener el contenido de este archivo, codificado en base64:

Y finalmente, podemos devolver 2 tipos de respuestas:

  • Si no tenemos el contenido del archivo (porque no tenemos un ID de documento o no encontramos su nombre de archivo o contenido asociado), devolvemos una respuesta 404, con este contenido personalizado:
 set json = {
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "not-found",
            "diagnostics": "<HSFHIRErr>ResourceNotFound",
            "details": {
                "text": "No resource with type 'Binary'"
            }
        }
    ]
 }
 set json.issue.%Get(0).details.text = json.issue.%Get(0).details.text_" and id '"_context.docId_"'"
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"
  • Si tenemos contenido de archivo, entonces devolvemos una respuesta 200 con este contenido personalizado
 set json = {
  "resourceType": "Binary",
  "id": "",
  "contentType": "application/pdf",
  "securityContext": {
    "reference": "DocumentReference/"
  },
  "data": ""
 }
 set json.id = context.docId
 set json.securityContext.reference = json.securityContext.reference_json.id
 set json.data = context.content.Read(context.content.Size)
 
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"

La clave aquí es crear un HS.SDA3.QuickStream, que contenga el objeto JSON. Y añadir este QuickStream a la respuesta.

Y ahora, si probamos nuestro endpoint, si solicitamos un documento Binary, veremos la respuesta:

Y si solicitamos un documento Binary que no existe (puedes probarlo sin pasar ningún ID de documento), veremos la respuesta 404:

En resumen, conectando nuestro endpoint FHIR con interoperabilidad podemos hacer lo que queramos, con todas las capacidades de InterSystems IRIS.

Discussão (0)0
Entre ou crie uma conta para continuar
Artigo
· Fev. 23 4min de leitura

Creating FHIR responses with IRIS Interoperability production

When we create a FHIR repository in IRIS, we have an endpoint to access information, create new resources, etc. But there are some resources in FHIR that probably we wont have in our repository, for example, Binary resource (this resource returns a document, like PDF for example).

I have created an example that when a Binary resource is requested, FHIR endpoint returns a response, like it exists in the repository. 

First of all, we need a Namespace and a FHIR endpoint. After this, we need to configure an Interoperability production that will be connected to the FHIR endpoint. This production must have this items:

  • Business Operations:
    • HS.Util.Trace.Operations (in fact this is optional, but can be very useful)
    • HS.FHIRServer.Interop.Operation, with TraceOperations property set to *FULL*
  • Business Service:
    • HS.FHIRServer.Interop.Service, with TraceOperations property set to *FULL* and Target Config Name set to HS.FHIRServer.Interop.Operation name

This is how production looks like:

After creating this production, we need to connect it with the FHIR endpoint. So edit FHIR endpoint and set the parameter Service Config Name with the name of the Business Service:

Now, if we start to send requests to FHIR repository, we will see all the traces in Message Viewer:

Now we can have a Business Process to control what to do with specific paths.

In this example we have a Business Process that receives every request (now the Business Service it's connected to this Business Process, instead of the Business Operation) and 2 new Business Operation that makes another actions that will be explained later:

Let's take a look to the Business Process called FHIRRouter:

If we take a look, we will see that, if RequestPath contains "Binary/", then we will do something with this request: generate our custom Binary response. Otherwise, we will send the request to FHIR Repository directly.

Let't take a look at the sequence called "Generate Binary":

First of all, we create a new instance of HS.FHIRServer.Interop.Response. And we get the document ID from the Request Path. How? Every time someone want's a Binary resource, it must be requested with the ID of the document in the URL path, something like this: ..../fhir/r4/Binary/XXXXX. So we extract the document ID from the Request Path with this expression:

$Replace(request.Request.RequestPath,"Binary/","")

(It's not very elegant, but it works).

If we have a document ID, then we make a call to a Business Operation called Find to find the filename associated to that document ID:

In fact, this Business Operation Find always returns the same filename:

It's an example of what we can do.

If we have a filename, then, we call another Business Operation called File to get this file content, encoded in base64:

And finally, we can return 2 kind of responses:

  • If we don't have file content (because we don't have a document ID or we don't find it's associated filename or content), we return a 404 response, with this custom response:
 set json = {
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "not-found",
            "diagnostics": "<HSFHIRErr>ResourceNotFound",
            "details": {
                "text": "No resource with type 'Binary'"
            }
        }
    ]
 }
 set json.issue.%Get(0).details.text = json.issue.%Get(0).details.text_" and id '"_context.docId_"'"
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"
  • If we have file content, then we return a 200 response with this custom response:
 set json = {
  "resourceType": "Binary",
  "id": "",
  "contentType": "application/pdf",
  "securityContext": {
    "reference": "DocumentReference/"
  },
  "data": ""
 }
 set json.id = context.docId
 set json.securityContext.reference = json.securityContext.reference_json.id
 set json.data = context.content.Read(context.content.Size)
 
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"

The key here is to create a HS.SDA3.QuickStream, that contains the JSON object. And add this QuickStream to the response.

And now, if we test our endpoint, if we request of a Binary document, we will see the response:

And if we request a Binary document that doesn't exist (you can test it passing no document ID), we will see 404 response:

In summary, connecting our FHIR endpoint with interoperability we can do whatever we want, with all the capabilities of InterSystems IRIS.

5 Comments
Discussão (5)2
Entre ou crie uma conta para continuar
Pergunta
· Fev. 21

SQL Table - Data Cleanup

Hi Community,

I've created a method in my File Service to do a cleanup for every file load. Currently, I've set it to delete data when LastUpdated date is greater than maxdate. However, I want to do a cleanup for every new file load. Any suggestions or advice on how to do this? Thanks!

 

Method Cleanup()
{

   Set tMaxDate = ""
   &SQL(SELECT Max(LastUpdated) into :tMaxDate
   FROM MC_Table_Data.Patient) 
 

   &SQL(DELETE MC_Table_Data.Patient WHERE LastUpdated<:tMaxDate)
}

Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· Fev. 21 4min de leitura

Controlando o IRISTEMP: Pare de Deixar Que Ele Ocupe Todo o Seu Armazenamento!

Introdução: Quando o IRISTEMP Armazena Dados Demais

Então, você verificou seu servidor e viu que o IRISTEMP está crescendo demais. Não precisa entrar em pânico. Vamos investigar o problema antes que seu armazenamento acabe.

Passo 1: Confirmar o Problema de Crescimento do IRISTEMP

Antes de assumir que o IRISTEMP é o problema, vamos verificar seu tamanho real.

Verificar o Espaço Livre

Execute o seguinte comando no terminal IRIS:

%SYS>do ^%FREECNT

Quando solicitado, digite:

Database directory to show free space for (*=All)? /<your_iris_directory>/mgr/iristemp/

Se a saída mostrar muito pouco espaço livre, o IRISTEMP está enchendo seu armazenamento como um armário superlotado. Mas se o espaço livre estiver bom, mas o arquivo de banco de dados IRISTEMP (IRIS.DAT) ainda for enorme (que é provavelmente por isso que você está aqui), significa que os dados temporários já foram limpos. Nesse caso, sua missão é ficar de olho nas coisas, seguir os passos abaixo para pegá-lo em flagrante na próxima vez e recuperar esse espaço precioso.

Passo 2: Identificar o que está usando o IRISTEMP

Execute ^%GSIZE para encontrar Globais Grandes

%SYS>do ^%GSIZE

Siga as instruções:

Directory name: /<your_iris_dir>/mgr/iristemp/

All Globals? No => yes

33 items selected from
33 available globals

1) Get exact packing details
2) Get block counts only
3) Use fast stochastic estimate

Please select an option:  3 => 3

Exemplo de saída:

        Global              Blocks          Bytes Used Packing
      ----------- ---------------- ------------------- -------
      IRIS.Temp.Ensemble
                                1                  60      1 %
      IRIS.Temp.MARIO
                               50             360,960     88 %
      IRIS.Temp.RecompileInfo
                                1                  84      1 %

Se você vir algo desconhecido, especialmente relacionado a ISC ou SQL, pode ser que consultas SQL estejam usando muito espaço. Verifique com os desenvolvedores do aplicativo para ver o que essas consultas estão fazendo e se elas podem ser otimizadas. Às vezes, adicionar um índice ou remover uma cláusula ORDER BY desnecessária pode fazer uma grande diferença.

Passo 3: Verificar Globais Privadas de Processo (PPGs)

Globais Privadas de Processo (PPGs) podem não ser liberadas corretamente por alguns processos. Execute:

%SYS>DO ^GETPPGINFO

Exemplo de saída:

%SYS> DO ^GETPPGINFO("*")
Process ID: 303 --> Total PPG Block count 10840
  ^||%t uses 10838 blocks (maxblock #1926355)
  ^||TempQuery uses 2 blocks (maxblock #115489)
  Highest block #: 1926355
Process ID: 33456 --> Total PPG Block count 45343
  ^||MARIOtest uses 45343 blocks (maxblock #1927313)
  Highest block #: 1927313

Se um processo estiver usando muito espaço de PPG, ele pode estar travado ou não funcionando como esperado. Você deve investigar com os desenvolvedores do aplicativo para verificar se os PPGs são conhecidos e se há algo quebrado no código. Da mesma forma, se o PPG não for conhecido e parecer código interno da InterSystems (por exemplo, ^||%t), é melhor você abrir um caso de suporte WRC pedindo ajuda.

Torne-se um especialista em GETPPGINFO lendo a documentação oficial.

Passo 4: Corrigir o Problema

Opção 1: Parar o Processo

Uma vez que você identificou o processo consumindo o IRISTEMP, se você sabe o que ele está fazendo e considera seguro, você pode usar o Portal de Gerenciamento do Sistema ou o terminal para pará-lo. Do terminal, você pode encontrar o trabalho e terminá-lo:

%SYS>do ^JOBEXAM

Encontre o número do trabalho e execute:

%SYS>DO ^RESJOB
 
Force a process to quit InterSystems IRIS
 
Process ID (? for status report): 7732

Process ID (? for status report):
 
%SYS>

⚠️ Pare um processo apenas se você o conhecer e tiver certeza de que é seguro fazê-lo!

Opção 2: Reiniciar o IRISTEMP e Definir Limites

Para limpar o IRISTEMP, pare o Iris, remova seu arquivo IRIS.DAT e reinicie:

iris stop <instance_name>
rm /<iris_directory>/mgr/iristemp/IRIS.DAT
iris start <instance_name>

Para impedir que ele cresça demais, defina um limite na sua configuração do IRIS:

[Startup]
MaxIRISTempSizeAtStart=5000

Consulte a documentação oficial sobre MaxIRISTempSizeAtStart para obter mais detalhes. Além disso, há outros artigos com mais detalhes na comunidade: Como Reduzir o IRISTEMP

Opção 3: Versão antiga? Atualize!

Se você estiver executando uma versão antiga do Iris, atualize! Por exemplo, lembro-me de termos corrigido um bug na versão 2021.1.1+ onde o IrisTemp podia crescer descontroladamente. Atualizar e estar nas versões de manutenção mais recentes é a melhor maneira de evitar bugs conhecidos.

Conclusão: Mantenha o IRISTEMP Sob Controle

Seguindo estes passos, você pode:
✅ Encontrar o que está usando o IRISTEMP com ^%GSIZE e ^GETPPGINFO
✅ arar processos conhecidos que ocupam muito espaço PPG
✅ ecuperar o espaço definindo limites ou recriando o banco de dados IrisTemp.

Atualizar! Isto é sempre recomendado!

Ao fazer isto, você pode manter o IRISTEMP sob controle e evitar problemas de armazenamento. 🚀

Discussão (0)1
Entre ou crie uma conta para continuar