Artigo
· 7 hr atrás 3min de leitura

Variáveis de host SQL ausentes ?

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 SQL SET @var
  • 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
}
}

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
  } 
CREATE or REPLACE PROCEDURE
HGETV(IN name VARCHAR(50)) RETURNS VARCHAR(50)
  LANGUAGE OBJECTSCRIPT 
  {
 	quit $get(^||host($g(name,"%")))
  }
CREATE or REPLACE PROCEDURE
HGETI(IN name VARCHAR(50)) RETURNS INT
  LANGUAGE OBJECTSCRIPT 
  {
 	quit $get(^||host($g(name,"%")))
  }  
CREATE or REPLACE  
PROCEDURE HDEL(IN name VARCHAR(50)) RETURNS INT
  LANGUAGE OBJECTSCRIPT 
  { 	kill ^||host($g(name,"%"))
	quit $$$OK
  } 

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  

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

GitHub

Implementação do Portal de Ideias

 
Esperando seus votos no concurso.

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