Pessoal,
quem usa oracle e ja precisou usar alguma procedure com um parametro desse ( muito usado no Forms ) por favor me de uma
ajuda…
eu ja revirei o google, ja tentei todos os exemplos que tem lá, procurei no metalink, abri chamado na oracle mas a solução que me deram nao atende… na solução o cara cria uma classe java pra mapear e talz mas eu nao posso criar 1 classe pra cada função do sistema que temos aqui ( sao mais de 4000 ) e muitas delas usam esse tipo de parametro.
eu fiz uma classe aqui pra criar os TYPES dinamicamente, com metadados… esta funcionando perfeitamente:
public class JavaOracleMapper {
Connection conn;
PreparedStatement stmt;
ResultSet rs;
ResultSetMetaData rsmeta;
StringBuffer sql;
String table;
String objectName;
String collectionName;
public JavaOracleMapper( Connection conn, String table ) {
this.conn = conn;
this.table = table;
this.objectName = "TP_".concat( table );
this.collectionName = "TP_".concat( table ).concat( "_ROW" );
}
/*
* CRIA UM OBJECT TYPE = 'TP_TABELA' E UM
* OBJECT COLLECTION = 'TP_TABELA_ROW'
*/
public void updateTypes() throws Exception {
try {
/*
* UM OBJECT TYPE NAO PODE SER ATUALIZADO ENQUANTO TIVER
* UMA COLLECTION TYPE COMO DEPENDÊNCIA.
*/
sql = new StringBuffer();
sql.append( "SELECT 1 FROM USER_OBJECTS WHERE OBJECT_NAME = ? ");
stmt = conn.prepareStatement( sql.toString() );
stmt.setString( 1, this.collectionName );
rs = stmt.executeQuery();
if ( rs.next() ) {
sql = new StringBuffer();
sql.append( "DROP TYPE ").append( this.collectionName );
stmt = conn.prepareStatement(sql.toString());
stmt.execute();
}
/*
* OBTEM OS METADADOS, E CRIA O OBJECT TYPE E O COLLECTION
* TYPE PARA A TABELA
*/
sql = new StringBuffer();
// OBTEM UM RESULTSET VAZIO ( 1 != 2 ), APENAS PARA METADADOS
sql.append("SELECT * FROM ").append( table ).append(" WHERE 1 = 2");
stmt = conn.prepareStatement( sql.toString() );
rs = stmt.executeQuery();
rsmeta = rs.getMetaData();
sql = new StringBuffer();
sql.append(" CREATE OR REPLACE TYPE ").append( objectName ).append(" AS OBJECT ( ");
int colunas = rsmeta.getColumnCount();
for ( int i = 1; i <= colunas; i++ ) {
String nome = rsmeta.getColumnName(i);
String tipo = rsmeta.getColumnTypeName(i);
sql.append( nome ).append(" ").append( tipo );
if ( tipo.startsWith("VARCHAR") ) {
sql.append("(").append(rsmeta.getColumnDisplaySize(i)).append(")");
}
if ( tipo.startsWith("NUMBER") ) {
sql.append("(").append(rsmeta.getPrecision(i)).append(")");
}
if ( i != colunas ) {
sql.append(", ");
}
}
sql.append(" )");
stmt = conn.prepareStatement( sql.toString() );
stmt.execute();
sql = new StringBuffer();
sql.append(" CREATE OR REPLACE TYPE ").append( collectionName ).append(" IS TABLE OF ").append( objectName );
stmt = conn.prepareStatement( sql.toString() );
stmt.execute();
} catch (Exception e) {
e.printStackTrace();
throw new Exception("Falha ao tentar criar os Object Types no Banco. " + e.getMessage() );
}
}
public static void main( String args[] ) {
try {
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@//xxxx:xxx/xxxx", "yyyy", "zzzz" );
JavaOracleMapper mapper = new JavaOracleMapper( conn, "TABLE_XPTO");
mapper.updateTypes();
Object[][] elements = {{10000L, "TESTANDO", "USUARIO", "TESTE", "S",
"S", "S", 1, "S", "S", 1, 1, 1, 1, 1, 1}} ;
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(
"TP_TABLE_XPTO_ROW", conn);
ARRAY array = new ARRAY(descriptor, conn, elements);
OracleCallableStatement stmt = (OracleCallableStatement)
conn.prepareCall(" { call pa_xpto.inclui_usuarios( ?, ? ) } ");
stmt.setLong(1, 1);
stmt.setARRAY(2, array);
stmt.execute();
} catch ( Exception e ) {
e.printStackTrace();
}
}
o problema esta na hora de executar, onde eu ja peguei todos os tipos possiveis de erro:
“PLS-00306: número incorreto de tipos de argumentos na chamada para ‘INCLUI_XXXXX’”
“erro interno” - esse foi comédia… só tem isso na descricao do erro
Se alguem tiver experiencia com isso da uma força ae…