sql >> Databáze >  >> RDS >> Oracle

Groovy SQL Oracle Array Funkce/procedura Registrace parametrů

Právě jsem čelil stejnému problému a nyní mám řešení. V zásadě existují dva problémy. První je, že Oracle vyžaduje, abyste mu řekli název typu pole, když je registrován výstupní parametr. Druhým je, jak přesvědčit Groovyho, aby vám to dovolil. Naštěstí se zdá, že na to návrháři Groovy mysleli a umožnili vám podtřídu groovy.sql.Sql, abyste se zapojili do nastavení parametrů.

V této odpovědi na podobnou otázku na úrovni JDBC použiji typ příkladu a uloženou proceduru:

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

Nyní potřebujeme několik nových tříd Groovy:

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

Jejich použití je docela jednoduché. Pravděpodobně budete chtít, aby dokumentace Oracle o polích porozuměla výsledným datovým strukturám.

// 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. ORA-01036:neplatný název/číslo proměnné při spuštění dotazu přes C#

  2. Jak funguje WEEK() v MariaDB

  3. 4 způsoby, jak vypsat všechny tabulky v databázi MySQL

  4. Jak analyzovat aktivitu jedné databáze na serveru SQL