Variáveis de host são um recurso de programação bastante comum em muitas implementações de SQL.
Uma pergunta recente no DC me alertou para o fato de que, no IRIS, Caché, Ensemble, ... variáveis de host existem apenas dentro do SQL incorporado:
> Você pode fornecer variáveis de host apenas para consultas SQL incorporadas. <
Exemplos relacionados estão incluídos na documentação disponível.
Esta é uma descrição de uma solução alternativa caso você não use/não possa usar SQL incorporado.
A ideia básica é usar PPGs (Globais Privadas de Processo) para armazenar a imitação de uma variável de host.
Uma das principais razões para usar PPGs é o fato de serem excluídas automaticamente ao final do processo.
Outra ideia é evitar conflitos com arrays de variáveis locais e escopo de variáveis local versus global.Além disso, não há necessidade de uma atividade de limpeza.
Na verdade, trata-se de um conjunto de 3 métodos SQL:
- HDEC para simular SQL
DECLARE @var
e SQLSET @var
r - HGETV e HGETI para retornar o valor da variável como VARCHAR ou INT.
- Como um recurso adicional, NULL é retornado se a variável não foi definida ou declarada anteriormente.
- Se necessário, retornar qualquer outro tipo de dado é bastante fácil.
- HDEL é fornecido caso surja a improvável necessidade de excluir uma variável de host.
Class User.HostVar
{
ClassMethod GetV(name) As %String [ SqlName = HGETV, SqlProc ]
{
quit $get(^||host($g(name,"%")))
}
ClassMethod GetI(name) As %Integer [ SqlName = HGETI, SqlProc ]
{
quit $get(^||host($g(name,"%")))
}
ClassMethod Declare(name, val) As %Integer [ SqlName = HDEC, SqlProc ]
{
set ^||host($g(name,"%"))=$g(val)
quit $$$OK
}
ClassMethod Del(name) As %Integer [ SqlName = HDEL, SqlProc ]
{
kill ^||host($g(name,"%"))
quit $$$OK
}
}
ObjectScriptObjectScript
Meu exemplo contém 2 variantes para implementação.
A primeira é em ObjectScript puro; essa variante também está disponível em IPM.
A segunda é baseada em SQL e pode ser implementada também sobre ODBC/JDBC.
CREATE or REPLACE
PROCEDURE HDEC(IN name VARCHAR(50), IN val VARCHAR(50)) RETURNS INT
LANGUAGE OBJECTSCRIPT
{ set ^||host($g(name,"%"))=$g(val)
quit $$$OK
}
SQLSQL
CREATE or REPLACE PROCEDURE
HGETV(IN name VARCHAR(50)) RETURNS VARCHAR(50)
LANGUAGE OBJECTSCRIPT
{
quit $get(^||host($g(name,"%")))
}
SQLSQL
CREATE or REPLACE PROCEDURE
HGETI(IN name VARCHAR(50)) RETURNS INT
LANGUAGE OBJECTSCRIPT
{
quit $get(^||host($g(name,"%")))
}
SQLSQL
CREATE or REPLACE
PROCEDURE HDEL(IN name VARCHAR(50)) RETURNS INT
LANGUAGE OBJECTSCRIPT
{ kill ^||host($g(name,"%"))
quit $$$OK
}
ObjectScriptObjectScript
Ambas as variantes são projetadas para serem utilizáveis sem um prefixo de pacote.
Portanto, o pacote User (o padrão) é usado, mapeando para o esquema padrão SQLUser em SQL.
Durante os testes, detectei que forçar uma sequência de Definição e Consumo dessas variáveis de host pode ser um exercício complicado se você quiser executá-lo dentro de uma única instrução SQL.
Eu consegui fornecer uma sequência previsível apenas usando uma construção CASE.
SELECT
CASE
WHEN HDEC('rcc',66) > 0 -- set host var
THEN HGETI('rcc')-5||' ** '||HGETV('rcc')
END
ObjectScriptObjectScript
Dentro de um stored procedure você não enfrenta esse problema.
Meu exemplo e também o pacote fornecido no Open Exchange foram construídos e testados no IRIS. Embora a construção seja bastante básica, ela também roda sem nenhuma alteração no Caché, Ensemble, ... e seus derivados e, claro, em todos os derivados HEALTH* do IRIS.
Minha única dúvida é sobre um banco de dados fragmentado em combinação com Globais Privadas de Processo. Eu simplesmente não tinha uma configuração disponível para testar esse cenário.
Não presumo que esta proposta seja a solução definitiva. Situações específicas podem exigir uma abordagem mais sofisticada ou, de outra forma, construções mais simples.
Como mencionado anteriormente, vejo a grande vantagem de ter uma solução que possa ser usada sobre acesso ODBC ou JDBC e não requeira codificação com VSCode ou Studio.Video
Implementação do Portal de Ideias
Esperando seus votos no concurso.
Muito Obrigado @Heloisa Paiva