Fundo
Procurando passar um conjunto de pares de nome/valor para um procedimento armazenado de maneira independente do banco de dados, usando JDBC. Uma estrutura de banco de dados é definida da seguinte forma:
CREATE TYPE array_parameters AS (
v_name VARCHAR2(255),
v_value CLOB
);
Essa estrutura, que pode ter definições equivalentes na maioria dos bancos de dados relacionais modernos, está sendo proposta como uma forma de passar um número arbitrário de pares nome/valor para um procedimento armazenado. A chamada do procedimento armazenado é semelhante a:
SELECT rxm( '...map...', array_parameters );
Onde o ...map...
pode incluir qualquer número de referências variáveis, assumindo a seguinte forma :
account.id = $id &&
person.last_name = $surname && ...
O array_parameters
, em teoria, poderia ser preenchido como:
array_parameters[0].v_name = "$id";
array_parameters[0].v_value = "123456789";
array_parameters[1].v_name = "$surname";
array_parameters[1].v_value = "O'Malley, The \"Great\"";
Problema
JDBC4 define um método chamado createArrayOf , que é o New South China Mall of APIs:
- Não suportado pela Oracle
- Não suportado pelo MySQL
- Não suportado pelo Microsoft SQL Server
- Não suportado pelo Apache Derby
- Sem suporte da Sybase
Sem a capacidade de criar a matriz de par de nome/valor, não vejo nenhuma maneira óbvia de passar os valores sem recorrer a implementações específicas do banco de dados (como usar o ARRAY da Oracle ou contorções obtusas para oferecer suporte ao MySQL).
Pergunta
Como você definiria e, em seguida, chamaria um procedimento armazenado que pode receber um número arbitrário de pares nome/valor de maneira independente do banco de dados?
Ideia #1
Uma ideia seria definir duas matrizes de strings, em vez de uma estrutura de matriz de objeto, e chamar o procedimento armazenado da seguinte maneira:
SELECT rxm( '...map...', array_names, array_values );
As duas matrizes seriam vinculadas a índices, mas isso provavelmente createArrayOf()
também dependeria de .
Ideia #2
Pode ser possível passar os pares como strings separadas por vírgulas. No entanto, os próprios valores podem conter vírgulas, o que dificulta a codificação de parâmetros usando strings separadas por vírgula. (Falando de modo geral, qualquer separador pode aparecer como um caractere em algum lugar nos valores, o que também inclui separadores de escape, como \,
.)
Essa parece ser a solução mais independente de banco de dados, mas implementar uma rotina de decodificação CSV em vários bancos de dados em PL/SQL não é trivial nem eficiente.
Ideia #3
Use o Hibernate como uma camada de abstração e implemente uma rotina JPQL que passa na matriz de pares nome/valor. Por exemplo, chamar query.setParameterList , que pode funcionar apenas para IN
cláusulas, em vez de parâmetros de procedimentos armazenados.