powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / execute immediate
13 сообщений из 13, страница 1 из 1
execute immediate
    #39857001
Kaktus_87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, помогите плз собрать динамический блок execute immediate, в который я бы мог передавать название сиквенса из переменной.(т.е чтоб получилось что-то типо этого SELECT || seq || .nextval into m from dual;) Также записывать значения этого сиквенса в переменную.
Я знаю, что в динамическом sql можно собрать запрос с переменными, но как это делается ни как не пойму.

Также подскажите, если другой способ увеличить последовательность сиквенса число N ? - гугл не помог (

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
DECLARE
seq VARCHAR2(20) := 'BF_SEQ'; --название сиквенса
d NUMBER := 10000000; --На сколько увеличиваем сиквенс
n NUMBER; --текущее значение сиквенса
m NUMBER; --Измененное значение сиквенса

BEGIN
SELECT BF_SEQ.nextval into n from dual;
--execute immediate 'SELECT ' || seq || '.nextval' into n from dual; --хочется получить, что-то типо этого

execute immediate 'ALTER SEQUENCE BF_SEQ INCREMENT BY  '|| d ;

SELECT BF_SEQ.nextval into m  from dual;

execute immediate 'ALTER SEQUENCE BF_SEQ INCREMENT BY  1';

DBMS_OUTPUT.Put_Line( 'n= '|| n );
DBMS_OUTPUT.Put_Line( 'm= '|| m );
DBMS_OUTPUT.Put_Line( 'd= '|| d ); 
end;
...
Рейтинг: 0 / 0
execute immediate
    #39857005
CrazyCat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87,

Гуглом принципиально не пользуемся?
https://docs.oracle.com/cd/B12037_01/appdev.101/b10807/13_elems017.htm

см. examples
...
Рейтинг: 0 / 0
execute immediate
    #39857017
oragraf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87,

держи на подумать:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
  /* Процедура осуществляет перекидку сиквенса согласно значению поля таблицы.
     Если колонка не передана, то процедура пытается найти колонку через
     констрейнты. Если ключ - составной или ключ нечисловой или таблицы нет - исключение
  */
  procedure alter_sequence_nextval (p_table_name    varchar2
                                  , p_column_name   varchar2 := null
                                  , p_sequence_name varchar2 := null
                                   )
    as
    number_fmt               constant varchar2 (100) := 'fm99999999999999999999999';
    l_seq_currval                     number;
    l_seq_incrementby                 number;
    l_seq_nextval                     number;
    l_seq_cache                       number;
    l_tab_currval                     number;
    l_tab_nextval                     number;
    l_dml                             varchar2 (1000 char);
    l_column_name                     varchar2 (30 char);
    l_table_name                      varchar2 (30 char);
    l_sequence_name                   varchar2 (30 char);
  begin
    l_table_name := UPPER (DBMS_ASSERT.sql_object_name (p_table_name));
    l_sequence_name := UPPER (DBMS_ASSERT.sql_object_name (p_sequence_name));
    l_column_name := TRIM (p_column_name);

    if l_column_name is not null
    then
       l_column_name := DBMS_ASSERT.simple_sql_name (p_column_name);
    else
       begin
          select cc.column_name
            into l_column_name
            from user_constraints c
                 inner join user_cons_columns cc on cc.constraint_name = c.constraint_name and cc.owner = c.owner
                 inner join user_tab_columns tc on tc.table_name = cc.table_name and tc.column_name = cc.column_name
           where c.constraint_type in ('P', 'U') and tc.data_type in ('NUMBER', 'INTEGER') and UPPER (tc.table_name) = l_table_name;
       exception
          when NO_DATA_FOUND
          then
             raise DBMS_ASSERT.invalid_object_name;
          when TOO_MANY_ROWS
          then
             utl_ddl.error ('Таблица ' || l_table_name || ' имеет составной ключ! Укажите требуемую колонку');
             raise exc#invalid_identifier;
       end;
    end if;

    l_dml := 'select s.increment_by, s.cache_size from user_sequences s where sequence_name = upper(trim(:1))';

    execute immediate l_dml into l_seq_incrementby, l_seq_cache using l_sequence_name;

    l_dml := 'begin select max(' || l_column_name || ') into :1 from ' || l_table_name || '; :2 := ' || l_sequence_name || '.nextval; end;';

    execute immediate l_dml using out l_tab_currval, out l_seq_currval;

    if l_tab_currval > l_seq_currval -- В случае, если строго больше, тогда меняем инкремент
    then
       l_dml := 'alter sequence ' || l_sequence_name || ' increment by ' || TO_CHAR (l_tab_currval - l_seq_currval, number_fmt) || ' nocache';
       execute immediate l_dml;

       l_dml := 'begin :2 := ' || l_sequence_name || '.nextval; end;';
       execute immediate l_dml using out l_tab_nextval;

       execute immediate 'alter sequence ' || l_sequence_name || 
                         ' increment by ' || TO_CHAR (l_seq_incrementby, number_fmt) || 
                         case when l_seq_cache = 0 then ' nocache' 
                              else ' cache ' || to_char(l_seq_cache, number_fmt)
                         end;
    elsif l_tab_currval = l_seq_currval
    then -- В редких случаях, когда равны, просто еще раз дернем сиквенс, чтобы не делать alter

       l_dml := 'begin :2 := ' || l_sequence_name || '.nextval; end;';
       execute immediate l_dml using out l_tab_nextval;    

    end if;

    exception
       when DBMS_ASSERT.invalid_object_name
       then
          utl_ddl.error ('Таблицы ' || p_table_name || ' с числовым полем для сиквенса не существует');
          raise exc#invalid_identifier;
       when DBMS_ASSERT.invalid_sql_name
       then
          utl_ddl.error ('Колонка ' || p_table_name || '.' || p_column_name || ' не существует');
          raise exc#invalid_identifier;
    end;
...
Рейтинг: 0 / 0
execute immediate
    #39857022
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
execute immediate
    #39857236
Kaktus_87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
oragraf,
Спасибо большое.
В принципе мне нужна было 2 таких строчки:
Код: plsql
1.
2.
3.
4.
...
l_plsql := 'begin select ' || seq_name || '.nextval into :1 from dual; end;';
execute immediate l_plsql using out seq_currval;
...
...
Рейтинг: 0 / 0
execute immediate
    #39857302
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87
Код: plsql
1.
2.
l_plsql := 'begin select ' || seq_name || '.nextval into :1 from dual; end;';
execute immediate l_plsql using out seq_currval;

Ужас.
...
Рейтинг: 0 / 0
execute immediate
    #39857712
Kaktus_87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic,
Что не так?
...
Рейтинг: 0 / 0
execute immediate
    #39857716
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87Что не так?Ты не понял, как PL/SQL-ьно обращаться к последовательности. А затем усугубил динамический запрос бессмысленным оборачиванием в PL/SQL.
...
Рейтинг: 0 / 0
execute immediate
    #39857748
Kaktus_87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic,
Как будет правильно? Так?

Код: plsql
1.
2.
3.
4.
...
l_plsql  := 'begin :2 := ' || seq_name || '.nextval;end;';
execute immediate l_plsql using out n_seq;
...
...
Рейтинг: 0 / 0
execute immediate
    #39857759
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87Как будет правильно? Так?Какая тебе разница? Немотивированное динамическое обращение к последовательности без знания основ - это говнокод по определению. Степень говнокодистости непринципиальна.
...
Рейтинг: 0 / 0
execute immediate
    #39857767
Kaktus_87
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторКакая тебе разница?
Хочется понять как правильно, я только учусь. С oracle познакомился полгода назад только.
...
Рейтинг: 0 / 0
execute immediate
    #39857775
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87,

в древних версиях не прокатит

.....
stax
...
Рейтинг: 0 / 0
execute immediate
    #39857777
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kaktus_87авторКакая тебе разница?
Хочется понять как правильно, я только учусь. С oracle познакомился полгода назад только.
имхо, от версий зависит

для древних, я кодировал примерно так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SQL> ed
Wrote file afiedt.buf

  1  declare
  2   v varchar2(100);
  3   s number;
  4  begin
  5   v:='s';
  6   execute immediate 'select '||v||'.nextval from dual' into s;
  7   dbms_output.put_line(s);
  8* end;
SQL> /
224

PL/SQL procedure successfully completed.



....
stax
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / execute immediate
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]