sql >> Database teknologi >  >> RDS >> Oracle

Groovy SQL Oracle Array Funktion/Procedure Out Parameter Registrering

Jeg har lige stået over for det samme problem og har nu en løsning. Grundlæggende er der to problemer. Den første er, at Oracle kræver, at du fortæller navnet på array-typen, når outputparameteren er registreret. Det andet er, hvordan man kan overtale Groovy til at lade dig gøre det. Heldigvis ser det ud til, at Groovy-designerne tænkte på dette og giver dig mulighed for at underklasser groovy.sql.Sql for at tilslutte sig parameterindstillingen.

Jeg vil bruge eksempeltypen og den lagrede procedure i dette svar på et lignende spørgsmål på JDBC-niveau:

SQL> CREATE TYPE t_type AS OBJECT (val VARCHAR(4));
2  /
Type created

SQL> CREATE TYPE t_table AS TABLE OF t_type;
2  /
Type created

SQL> CREATE OR REPLACE PROCEDURE p_sql_type (p_out OUT t_table) IS
2  BEGIN
3     p_out := t_table(t_type('a'), t_type('b'));
4  END;
5  /
Procedure created

Nu mangler vi et par nye Groovy-klasser:

import groovy.sql.*
import java.sql.CallableStatement
import java.sql.PreparedStatement
import java.sql.SQLException
import oracle.jdbc.driver.*

class OracleArrayOutParameter implements OutParameter {
    String typeName

    int getType() {
        OracleTypes.ARRAY
    }
}

class OracleArrayAwareSql extends Sql {

    OracleArrayAwareSql(Sql parent) {
        super(parent)
    }

    void setObject(PreparedStatement statement, int i, Object value) throws SQLException {
        if (value instanceof OracleArrayOutParameter) {
            try {
                OracleArrayOutParameter out = (OracleArrayOutParameter) value;
                ((CallableStatement) statement).registerOutParameter(i, out.getType(), out.typeName);
            } catch (ClassCastException e) {
                throw new SQLException("Cannot register out parameter.");
            }
        }
        else {
            super.setObject(statement, i, value)
        }
    }
}

Brugen af ​​disse er ret ligetil. Du vil sandsynligvis have Oracle-dokumentationen om arrays til at forstå de resulterende datastrukturer.

// First create a "normal" groovysqlSql instance, using whatever method you like

def parent = Sql.newInstance("jdbc:oracle:thin:@host:port:sid", "user", "password", "oracle.jdbc.OracleDriver")

// Then create an OracleArrayAwareSql instance giving that parent instance as a parameter

def sql = new OracleArrayAwareSql(parent)

// Now define an OracleArrayOutParameter naming the array type

def tTableParam = new OracleArrayOutParameter(typeName: 'T_TABLE')

// And make a stored procedure call as usual

sql.call("{call p_sql_type(${tTableParam})}") { out ->

    // The returned parameter is of type oracle.sql.ARRAY

    out.array.each { struct ->
        println struct.attributes
    }
}



  1. PostgreSQL:forbedring af pg_dump, pg_restore ydeevne

  2. Brug APP_NAME() til at få applikationsnavnet på den aktuelle session i SQL Server

  3. Understøttede formatmodeller til datofunktionerne ROUND() og TRUNC() i Oracle

  4. Foretagelse af ændringer til flere poster baseret på ændring af enkelt post med SQL