sql >> Database >  >> RDS >> Oracle

Groovy SQL Oracle Array Functie/Procedure Uit Parameters Registratie

Ik heb net hetzelfde probleem gehad en heb nu een oplossing. In principe zijn er twee problemen. De eerste is dat Oracle vereist dat u het de naam van het arraytype vertelt wanneer de uitvoerparameter wordt geregistreerd. De tweede is hoe je Groovy kunt overtuigen om je dat te laten doen. Gelukkig lijkt het erop dat de Groovy-ontwerpers hieraan hebben gedacht en je toestaan ​​om groovy.sql.Sql te subklassen om in de parameterinstelling te haken.

Ik gebruik het voorbeeldtype en de opgeslagen procedure in dit antwoord op een vergelijkbare vraag op 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 hebben we een paar nieuwe Groovy-lessen nodig:

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)
        }
    }
}

Het gebruik hiervan is vrij eenvoudig. U wilt waarschijnlijk dat de Oracle-documentatie over arrays de resulterende gegevensstructuren begrijpt.

// 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. Hoe Kubernetes te installeren met Kubeadm

  2. Hoe kan ik UUID's gebruiken in SQLAlchemy?

  3. Hoe ORA-29285 op te lossen:fout bij het schrijven van bestanden

  4. Hernoem een ​​externe sleutel in SQL Server met behulp van T-SQL