Как вызвать функцию Oracle или хранимую процедуру, используя структуру Spring Persistence?

Я использую структуру сохранения Spring для своего проекта. Я хочу вызвать функцию оракула или хранимую процедуру из этой структуры.

Может ли кто-нибудь предложить, как я могу этого достичь.

Пожалуйста, дайте решение как для * функции оракула, так и для * хранимой процедуры.

Спасибо.


person Community    schedule 14.05.2009    source источник
comment
Spring имеет структуру сохранения? Вы имеете в виду Spring JdbcTemplate? Или Гибернация?   -  person Adam Paynter    schedule 14.05.2009
comment
Я использовал DPTK для создания инфраструктуры постоянства и фабрики запросов Spring. Теперь хотите вызвать функцию оракула или хранимую процедуру, используя существующие функции, можете ли вы помочь мне отсортировать это.   -  person    schedule 14.05.2009
comment
DPTK является продуктом IBM: alphaworks.ibm.com/tech/dptk   -  person cliff.meyers    schedule 15.05.2009
comment
Я не понимаю отношения к junit. Не могли бы вы предоставить эту информацию?   -  person guerda    schedule 15.05.2009


Ответы (4)


Предполагая, что вы имеете в виду JdbcTemplate:

jdbcTemplate.execute(
    new CallableStatementCreator() {
        public CallableStatement createCallableStatement(Connection con) throws SQLException{
            CallableStatement cs = con.prepareCall("{call MY_STORED_PROCEDURE(?, ?, ?)}");
            cs.setInt(1, ...); // first argument
            cs.setInt(2, ...); // second argument
            cs.setInt(3, ...); // third argument
            return cs;
        }
    },
    new CallableStatementCallback() {
        public Object doInCallableStatement(CallableStatement cs) throws SQLException{
            cs.execute();
            return null; // Whatever is returned here is returned from the jdbcTemplate.execute method
        }
    }
);

Вызов функции практически идентичен:

jdbcTemplate.execute(
    new CallableStatementCreator() {
        public CallableStatement createCallableStatement(Connection con) {
            CallableStatement cs = con.prepareCall("{? = call MY_FUNCTION(?, ?, ?)}");
            cs.registerOutParameter(1, Types.INTEGER); // or whatever type your function returns.
            // Set your arguments
            cs.setInt(2, ...); // first argument
            cs.setInt(3, ...); // second argument
            cs.setInt(4, ...); // third argument
            return cs;
        }
    },
    new CallableStatementCallback {
        public Object doInCallableStatement(CallableStatement cs) {
            cs.execute();
            int result = cs.getInt(1);
            return result; // Whatever is returned here is returned from the jdbcTemplate.execute method
        }
    }
);
person Adam Paynter    schedule 14.05.2009
comment
здесь мы вызываем SP, как мы можем вызвать функцию Oracle... Я не имею в виду JdbcTemplate, я ссылаюсь на структуру сохранения с использованием DPTK.. - person ; 14.05.2009
comment
Второй пример — вызов функции. К сожалению, я не знаком с ДПТК. У него есть веб-сайт? - person Adam Paynter; 14.05.2009
comment
хорошо, я попытаюсь реализовать это с помощью своего кода... надеюсь, что это сработает.. Спасибо, Адам, сообщу вам о результате.. - person ; 14.05.2009
comment
Вы не должны использовать это. Я просто не знал, что такое структура сохраняемости Spring. Это было только мое лучшее предположение. - person Adam Paynter; 14.05.2009
comment
DPTK (Design Patter Tool Kit) — это подключаемый модуль RAD, к сожалению, у меня сейчас нет веб-сайта для него, как только я его получу, я отправлю его вам. - person ; 14.05.2009

Более простой способ вызова функции Oracle в Spring — это подкласс StoredProcedure, как показано ниже.

public class MyStoredProcedure extends StoredProcedure{
    private static final String SQL = "package.function";

    public MyStoredProcedure(DataSource ds){
        super(ds,SQL);
        declareParameter(new SqlOutParameter("param_out",Types.NUMERIC));
        declareParameter(new SqlParameter("param_in",Types.NUMERIC));
        setFunction(true);//you must set this as it distinguishes it from a sproc
        compile();
    }

    public String execute(Long rdsId){
        Map in = new HashMap();
        in.put("param_in",rdsId);
        Map out = execute(in);
        if(!out.isEmpty())
            return out.get("param_out").toString();
        else
            return null;
    }
}

И назовите это так

@Autowired DataSource ds;
MyStoredProcedure sp = new MyStoredProcedure(ds);
String i = sp.execute(1l);

Используемая здесь функция Oracle просто принимает числовой параметр и возвращает числовой параметр.

person Community    schedule 29.09.2009
comment
насколько я понимаю, код SQL должен выглядеть так: {:param_out = call schema.package.MY_FUNCTION(:param_in)} - person mmoossen; 15.05.2012
comment
мой последний комментарий неверен. константа SQL должна содержать только имя процедуры/функции, например schema.package.MY_FUNCTION, и имена параметров в Java HAVE, чтобы они соответствовали именам параметров, определенным в процедуре/функции. - person mmoossen; 15.05.2012

На мой взгляд, это один из самых простых подходов:

public class ServRepository {

    private JdbcTemplate jdbcTemplate;
    private SimpleJdbcCall functionGetServerErrors;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        jdbcTemplate.setResultsMapCaseInsensitive(true);
        this.functionGetServerErrors = new SimpleJdbcCall(jdbcTemplate).withFunctionName("THIS_IS_YOUR_DB_FUNCTION_NAME").withSchemaName("OPTIONAL_SCHEMA_NAME");
    }

        public String callYourFunction(int parameterOne, int parameterTwo) {
            SqlParameterSource in = new MapSqlParameterSource().addValue("DB_FUNCTION_INCOMING_PARAMETER_ONE", parameterOne).addValue("DB_FUNCTION_INCOMING_PARAMETER_TWO", parameterTwo);
            return functionGetServerErrors.executeFunction(String.class, in);
        }
}
person Deniss M.    schedule 07.08.2017
comment
Почему не new SimpleJdbcCall(dataSource)? - person Alex78191; 09.10.2019
comment
@ Alex78191 Alex78191 вам нужно будет написать там SQL. Я пытаюсь оставаться агностиком. - person Deniss M.; 10.10.2019
comment
Нет, все остальное то же самое. - person Alex78191; 10.10.2019
comment
@ Alex78191 Alex78191 не могли бы вы предоставить пример ответа с SimpleJdbcCall? Я не помню, почему я выбрал это решение. - person Deniss M.; 11.10.2019
comment
@ Alex78191 Alex78191 у него есть SQL. Я выбрал это решение, потому что это была чистая Java и довольно простая. - person Deniss M.; 14.10.2019

Вызов функции с использованием NamedParameterJdbcTemplate:

final String query = "select MY_FUNCTION(:arg1, :arg2, :arg3) from dual";
Map<String, Object> argMap = new HashMap<>();
argMap.put("arg1", "value1");
argMap.put("arg2", 2);
argMap.put("arg3", "value3");
final String result = new NamedParameterJdbcTemplate(dataSource)
        .queryForObject(query, argMap, String.class);

Процедура вызова с использованием JdbcTemplate:

final String query = "call MY_PROCEDURE(?, ?, ?)";
final Object[] args = {"arg1", "arg2", "arg3"};
new JdbcTemplate(dataSource).execute(query, args, String.class);

Вызов функции с использованием SimpleJdbcCall:

final String result = new SimpleJdbcCall(dataSource)
        .withCatalogName("MY_PACKAGE")
        .withFunctionName("MY_FUNCTION")
        .executeFunction(String.class, "arg1", "arg2");

Процедура вызова с использованием SimpleJdbcCall:

new SimpleJdbcCall(dataSource)
        .withCatalogName("MY_PACKAGE")
        .withProcedureName("MY_PROCEDURE")
        .execute("arg1", arg2);
person Alex78191    schedule 09.10.2019