sql >> Databasteknik >  >> RDS >> Oracle

Groovy SQL Oracle Array Funktion/Procedur Out Parametrar Registrering

Jag har precis stött på samma problem och har nu en lösning. I grund och botten finns det två problem. Den första är att Oracle kräver att du berättar namnet på arraytypen när utdataparametern registreras. Det andra är hur man övertalar Groovy att låta dig göra det. Lyckligtvis verkar det som att Groovy-designerna tänkt på detta och låter dig underklassa groovy.sql.Sql för att ansluta till parameterinställningen.

Jag kommer att använda exempeltypen och den lagrade proceduren i det här svaret på en liknande fråga på JDBC-nivå:

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 behöver vi ett par nya 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)
        }
    }
}

Användningen av dessa är ganska okomplicerad. Du vill förmodligen att Oracle-dokumentationen om arrayer förstår de resulterande datastrukturerna.

// 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. Tips för läs-/skrivlås beroende på transaktionsisoleringsnivå i MSSQL

  2. I Redshift/Postgres, hur räknar man rader som uppfyller ett villkor?

  3. Upptäck om värdet är nummer i MySQL

  4. Utöka EM Grid Control till nya noder