es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

H2 parece malinterpretar una cláusula de unión válida.

Aquí hay un esquema simple de una base de datos de prueba. No hay realmente nada especial en ello. Estoy utilizando la versión 1.4.200 de H2 en modo de compatibilidad con Oracle.

create table STUFF (
    ID number(19) generated by default as identity (start with 1 increment by 1),
    NAME varchar2(128) not null,
    constraint PK<em>STUFF primary key (ID),
    constraint BK</em>STUFF unique (NAME)
);

create table STUFF<em>DETAILS (
    ID number(19) generated by default as identity (start with 1 increment by 1),
    BLAH varchar2(128) not null,
    constraint PK</em>STUFF_DETAILS primary key (ID)
);

create table STUFF<em>MORE</em>DETAILS (
    ID number(19) generated by default as identity (start with 1 increment by 1),
    BLAH<em>BLAH varchar2(128) not null,
    constraint PK</em>STUFF<em>MORE</em>DETAILS primary key (ID)
);

Aquí hay una definición de vista que funciona bien. No hay objeción por parte de H2.

create or replace view V_STUFF1
(
    ID,
    NAME,
    BLAH,
    BLAH_BLAH
)
as select
    S.ID,
    S.NAME,
    SD.BLAH,
    SMD.BLAH_BLAH
from
     STUFF S
     inner join STUFF_DETAILS SD
          inner join STUFF_MORE_DETAILS SMD
               on SD.ID = SMD.ID
          on S.ID = SD.ID
;

Aquí hay una definición de vista que H2 no acepta y muestra el siguiente mensaje de error:

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Column “SD.ID” not found

create or replace view V_STUFF2
(
    ID,
    NAME,
    BLAH,
    BLAH_BLAH
)
as select
    S.ID,
    S.NAME,
    SD.BLAH,
    SMD.BLAH_BLAH
from
     STUFF S
     inner join STUFF_DETAILS SD
          left outer join STUFF_MORE_DETAILS SMD
               on SD.ID = SMD.ID
          on S.ID = SD.ID
;

La única diferencia es el tipo del join (left outer vs inner), pero no veo ninguna razón por la cual esto debería afectar la visibilidad de la columna SD.ID.

Para mí esto parece un defecto en H2, pero antes de plantear un problema con el proyecto de H2, quiero asegurarme de que no estoy pasando por alto algo obvio o haciendo algo estúpido.

PD: Soy consciente de que puedo reescribir la definición de la vista y hacer que H2 la acepte, pero idealmente me gustaría mantener el código SQL lo más cercano posible al original. Es un proyecto de migración.

PPD: Oracle (y DB2) no tienen problemas con ambas definiciones de vistas, por lo que el problema parece ser específico de H2.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    La diferencia entre las dos definiciones de vista es que la primera utiliza una unión interna entre STUFF_DETAILS y STUFF_MORE_DETAILS, mientras que la segunda utiliza una unión externa izquierda. El mensaje de error sugiere que H2 está teniendo problemas para manejar las columnas de STUFF_DETAILS en la unión externa izquierda.

    Es posible que esto sea un error en H2, pero sin más información es difícil decirlo con certeza. También podría ser un problema de sintaxis con la unión externa izquierda con la que H2 está luchando. Una cosa que se podría probar sería reescribir la segunda definición de vista utilizando una sintaxis diferente para la unión externa izquierda, como:

    create or replace view V_STUFF2
    (
        ID,
        NAME,
        BLAH,
        BLAH_BLAH
    )
    as select
        S.ID,
        S.NAME,
        SD.BLAH,
        SMD.BLAH_BLAH
    from
         STUFF S
         inner join STUFF_DETAILS SD on S.ID = SD.ID
         left outer join STUFF_MORE_DETAILS SMD on SD.ID = SMD.ID
    ;
    

    Esta sintaxis debería ser funcionalmente equivalente a la sintaxis original de la unión externa izquierda, pero podría ser más fácil de manejar para H2.

    En general, vale la pena investigar más para ver si esto es un error en H2 o un problema de sintaxis que se puede solucionar.

Comments are closed.