параметры exeсute immediate

Romanick
Дата: 08.06.2006 12:12:31
Есть вызов

Execute immediate строка_sql using мои_параметры

Можно ли сделать, чтобы количество параметров было разным?

Т.е. При одном вызове было
Execute immediate строка_sql using p1, p2;
при другом
Execute immediate строка_sql using p1, p2, p3;

Заранее спасибо.
VasyakinM
Дата: 08.06.2006 12:19:35
Интересно, а как по твоему в этом случае будет выглядеть строка_sql.

Если sql каждый раз разный, то я не совсем понял в чем вопрос, если одинаковый, то ты хочешь неициализировать какую-то часть параметров в запросе, а это ему ой как не понравится.
dmidek
Дата: 08.06.2006 12:21:04
Хорошее решение
здесь
Romanick
Дата: 08.06.2006 12:22:09
VasyakinM
Интересно, а как по твоему в этом случае будет выглядеть строка_sql.

Если sql каждый раз разный, то я не совсем понял в чем вопрос, если одинаковый, то ты хочешь неициализировать какую-то часть параметров в запросе, а это ему ой как не понравится.


Да, sql каждый раз совершенно разный и для разных таблиц с разным количеством параметров.
softwarer
Дата: 08.06.2006 12:22:32
Надо извращаться. Сходу можно предложить так:

procedure execute ( sql_stmt varchar2, p1 varchar2, p2 varchar2, p3 varchar2 ) is
  stmt varchar2(32000) ;
  params varchar2(100) ;

  function quote ( value varchar2 ) is
  begin
    return replace ( value, '''', '''''' ) ;
  end ;

  procedure add_param ( param_name varchar2, param_value varchar2 ) is
  begin
    if param_value is not null then
      params := params || ', ' || param_name ;
      stmt := stmt || ' ' || param_name || ' varchar2(' || length ( param_value ) ||
        ') := ''' || quote ( param_value ) || ''' ;' ;
    end if ;
  end ;

begin
  stmt := 'declare dummy char(1);' ;
  add_param ( 'p1', p1 ) ; 
  add_param ( 'p2', p2 ) ;
  add_param ( 'p3', p3 ) ;
  stmt := stmt || ' begin execute immediate ''' || quote ( sql_stmt ) || '''' ;
  if params is not null then stmt := stmt || ' using ' || params ; end if ;
  execute immediate stmt ;
end ;
Romanick
Дата: 08.06.2006 13:19:47
softwarer
Надо извращаться. Сходу можно предложить так:



Так ведь не prepare-ится внутренний запрос, насколько я могу судить. В кеше будет много мусора.

В идеале сделать бы так:

PKG_QUERY.SetEntity('имя_таблицы');
PKG_QUERY.SetNumberParam('id', :id);
PKG_QUERY.SetDateParam('dat', :dat);
PKG_QUERY.Prepare; -- собираем запрос типа insert into table (id, dat) values (:id, :dat) и prepare-им его.

PKG_QUERY.Execute; -- первый вызов

PKG_QUERY.SetNumberParam('id',:id);
PKG_QUERY.SetDateParam('dat', :dat);
PKG_QUERY.Execute; -- следующий вызов и т.д.
softwarer
Дата: 08.06.2006 14:24:36
Romanick
В идеале сделать бы так:

Если в идеале, значит отказаться от execute immediate и работать через dbms_sql.
KoTTT
Дата: 09.06.2006 12:00:15
Ну или использовать DBMS_SESSION.set_context
Romanick
Дата: 09.06.2006 12:05:51
Уже сделал через DBMS_SQL