powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / а че, так можно было ?
52 сообщений из 52, показаны все 3 страниц
а че, так можно было ?
    #39482577
nxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
begin

  for i in (select 1 x from dual) 
  loop
    for ii in (select 99 y from dual) 
    loop                
      ii.y := i.x;
      
      dbms_output.put_line(ii.y);
      
    end loop;    
  end loop;
  
end;



ткните меня в доки, где описано такое поведение
я всю жизь был уверен что оно immutable
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482598
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nxx
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
begin

  for i in (select 1 x from dual) 
  loop
    for ii in (select 99 y from dual) 
    loop                
      ii.y := i.x;
      
      dbms_output.put_line(ii.y);
      
    end loop;    
  end loop;
  
end;



ткните меня в доки, где описано такое поведение
я всю жизь был уверен что оно immutableвсегда так делал
а чё?
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482601
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
for rec in (select * from table where ***)
loop
    rec.id := null;
    rec.param1 := 1;
    insert into table values rec;
end loop;
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482602
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nxx,

а что тут странного?
я наоборот (без доки) считю ii переменной тіпа %rowtype

.....
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482770
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nxx,
как перевести на русский immutable?
Если как обязано производить
Код: plsql
1.
PLS-00363: expression 'I' cannot be used as an assignment target


так это для for loop специфицировано.

У тебя другая история - Cursor FOR LOOP Statement,
для которого ничто подобное не оговаривается.

Разница, вероятно, здесь вот в чем:
в первом случае (For Loop) воздействовать на i (прямой аналог понятия итератора) означает прямую попытку слома итеративного цикла, что приводит к ошибке времени компиляции.
Второй случай (cursor for loop) сам цикл следует читать как for each в "других языках программирования".
То есть, во втором случае, переменная цикла не является итератором, который скрыт, и потому сам итератор нельзя сломать, а видимая переменная цикла есть просто значение, возвращаемое из коллекции скрытым от глаз писателя итератором.
И делай ты с этим значением что хошь.
Любая попытка объявить его immutable внутри цикла противоречила бы здравому смыслу.
Т.к.
а) это локальная копия значения из итерируемой коллекции и,
б) никакие манипуляции с ней не способны сломать сам цикл (его скрытый итератор или условия продолжения, что в данном случае, можно не различать)
В доке для cursor for loop это, по счастью не оговаривается, и любая попытка оговорить - опечалит (обессмыслит) полезность данного нам в таком виде for each
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482867
за упокой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
boobyпеременная цикла не является итератором, который скрытПрисвоение компоненте "курсора" меняется не указатель на буфер строки, а содержимое этого буфера. Посему, рассуждения на тему здравого смысла спорны.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482870
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
за упокойboobyпеременная цикла не является итератором, который скрытПрисвоение компоненте "курсора" меняется не указатель на буфер строки, а содержимое этого буфера. Посему, рассуждения на тему здравого смысла спорны.
воу-воу-воу...
как это перевести на р ю сский?
где курсора компоненте?
откуда у парня итальянская грусть?
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39482894
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyоткуда у парня итальянская грусть?
испанская.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483242
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyоткуда у парня итальянская грусть?и откуда ты знаешь, что у парня, если booby?
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483254
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--boobyоткуда у парня итальянская грусть?и откуда ты знаешь, что у парня, если booby?
Из первоисточника:
YouTube Video
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483371
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
record
Name for the loop index that the cursor FOR LOOP statement implicitly declares as a %ROWTYPE record variable of the type that cursor or select_statement returns.

Думаю, тут вопрос больше религии.
Нигде в документации не написано, что эту неявно объявленную переменную можно менять, поэтому я б не стал менять.
Мало ли переменных оракл где-то неявно объявляет, это не значит, что это хорошая практика лезть и менять их.
Другое дело, что в использовании известных недокументированных фич тоже особенно страшного ничего нет (максимум - поведение изменится в след. версии, что в ряде случаев маловероятно).

имхо.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483502
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241record
Name for the loop index that the cursor FOR LOOP statement implicitly declares as a %ROWTYPE record variable of the type that cursor or select_statement returns.

Думаю, тут вопрос больше религии.
Нигде в документации не написано, что эту неявно объявленную переменную можно менять, поэтому я б не стал менять.
Мало ли переменных оракл где-то неявно объявляет, это не значит, что это хорошая практика лезть и менять их.
Другое дело, что в использовании известных недокументированных фич тоже особенно страшного ничего нет (максимум - поведение изменится в след. версии, что в ряде случаев маловероятно).Ключевое слово тут - variable. Не constant.
Да и как ещё можно сделать fetch into rec или rec := arr(i);
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483544
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic,

По мне так, здесь ключевые слова implicitly declares.
В обычном For Loop тоже variable, не константа, но менять нельзя:

FOR LOOP Index
The index of a FOR LOOP statement is implicitly declared as a variable of type INTEGER that is local to the loop. The statements in the loop can read the value of the index, but cannot change it. Statements outside the loop cannot reference the index.

С одной стороны менять cursor FOR LOOP index в документации не запрещено. С другой стороны менять неявно объявленные переменные без надлежащих причин, про которые не написано, что их можно менять, bad practice. сугубо имхо.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483631
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241,

про bad practice - не путай осторожность и bad practice.
Ну не понимаешь ты, как оно работает и зачем именно так устроено, от того даешь себе чес-слово не использовать.
Это простая осторожность - ни бэд, ни гуд.
И осторожность эта обязана быть последовательной .

Дал слово - держи.
Сказал - не трону "имплицитную переменную", значит - никогда не напишу цикл с имплицитным курсором
for r in (select dummy from dual)
loop
end loop;

Обязательно всегда сначала явно объявлю курсор, а потом только цикл его использующий.
Станет у тебя персональный практис имени тебя любимого. Будет что внукам рассказывать.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483667
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241...
С одной стороны менять cursor FOR LOOP index в документации не запрещено.

как это не - "не запрещено"?
явно и категорически запрещено путем ошибки времени копмиляции .
У тебя код даже скомпилироваться не сможет.
Читай у себя выше твою цитату из документации - The statements in the loop can read the value of the index, but cannot change it
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483723
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

Начинать обсуждение стоит после изучения документации, так смысла нет.
В документации разделы FOR LOOP Statement и Cursor FOR LOOP Statements семантически не связаны, каждый описывает свой случай, в каждом своя диаграмма с синтаксисом.

Ты все передернул.
Ссылаться можно, конечно, в документации об этом прямо написано для обоих случаев. Про менять значение для Cursor FOR LOOP Statements ничего не написано, для FOR LOOP Statement явно написано, что нельзя, но опять же семантически и логически там разные разделы, даже в цитате type INTEGER должен о чем-то говорить.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483735
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483750
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241, так это и указано в моем первом сообщении - это две разные истории, со своими правилами жизни.

А обсуждать что-либо, уже имея готовое мнение по предполагаемому вопросу - нет смысла априори.
Весь фикус строится на том, что смысл обсуждению придает спрашивающий.
Если смысл состоял в факте выражения возмущения от возможности изменять значение имплицитного рекорда в corsor for loop - то результат достигнут.
Возмущение высказано.
Объяснения не приняты.
Здесь предмета для обсуждения ни в какую лупу не просматривается.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483761
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

Лично у меня никакого возмущения нет. Изучив весь материал и аргументы, я пришел к выводу, что менять значение bad practice, это лично мое мнение и это то, что мне подсказывает здравый смысл, почему, я написал выше. Я бы предпочел, чтобы было наоборот. Пускай каждый сам смотрит аргументы и думает своей головой, не опираясь на неаргументированное мнение других.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483801
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241booby,

Лично у меня никакого возмущения нет. Изучив весь материал и аргументы, я пришел к выводу, что менять значение bad practice, это лично мое мнение и это то, что мне подсказывает здравый смысл, почему, я написал выше. Я бы предпочел, чтобы было наоборот. Пускай каждый сам смотрит аргументы и думает своей головой, не опираясь на неаргументированное мнение других.
для меня не bad practice
напр "дублирование" записей
прочитали
изменили нужное
добавили rec

в Вашем случае, нужно (имхо лишнее)
1) декларирование промежут переменной
2) перепресвоение

.....
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483804
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241,
мнение, предназначенное для личного использования, не нуждается в публичной аргументации.
Есть оно у тебя и хорошо.
Более того, для того, чтобы не опираться на мнение других не требуется даже наличие собственного.
"Раз не написано, что можно - значит нельзя" - для тебя - твое мнение ,
а для меня - лишенная конкретного контекста фраза, поэтому - бессмыслица .
Видишь - здесь даже начинать обсуждать нечего.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483860
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby"Раз не написано, что можно - значит нельзя" - для тебя - твое мнение,

Обсуждать смысла нет, потому что вы не читатель.
Само собой, когда я говорил про cursor FOR LOOP index, я говорил про Cursor FOR LOOP Statement.

user1241 Мало ли переменных оракл где-то неявно объявляет, это не значит, что это хорошая практика лезть и менять их.

user1241 В обычном For Loop тоже variable, не константа, но менять нельзя:

user1241 С другой стороны менять неявно объявленные переменные без надлежащих причин, про которые не написано, что их можно менять, bad practice

Я привык работать с документацией и стараюсь выбирать правильные инструменты для решения задач. Одна лишняя строчка это не проблема (тут, кстати, пример не помешает)
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483931
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot user1241]booby"Раз не написано, что можно - значит нельзя" - для тебя - твое мнение,

Обсуждать смысла нет, потому что вы не читатель.
Само собой, когда я говорил про cursor FOR LOOP index, я говорил про Cursor FOR LOOP Statement.

user1241 Мало ли переменных оракл где-то неявно объявляет, это не значит, что это хорошая практика лезть и менять их.
В этой фразе нет содержания и вы не постарались придать ей смысл в конкретном контексте cursor for loop.
С моей точки зрения - это даже на "мнение" не тянет - обыкновенный последний выдох ПЖ.

user1241 В обычном For Loop тоже variable, не константа, но менять нельзя:
и что?

user1241 С другой стороны менять неявно объявленные переменные без надлежащих причин, про которые не написано, что их можно менять, bad practice
вы как-нибудь определитесь - что должно быть написано, для того чтобы вы смогли проявить ваше умение читать. Что именно вас беспокоит - что компилятор неявно определяет переменные без видимых вами причин, что писатель документации лично вам не выдал разрешения на модификацию неявно объявленного экземпляра рекорда, или что в этом разделе вам не показали кусок кода, где модификация оправдана по некому основанию?

Второе, вообще говоря, гарантируется фразой Statements inside the loop can reference record and its fields ( Assignment statement - он вполне себе стейтмент, среди прочих),
а третье точно за рамками описывающей синтаксис документации.

user1241 Я привык работать с документацией и стараюсь выбирать правильные инструменты для решения задач. Одна лишняя строчка это не проблема (тут, кстати, пример не помешает)
Похоже, что тот, кто вам это сказал - жестоко посмеялся над вами.
Вы даже боитесь неправильно - вы не знаете ни как читать, ни как бояться, от того пишите чепуху.
Бояться надо совсем другого - уходить в область нарушения выданных вам гарантий

cursor for loop гарантирует вам что, курсор будет как открыт, так и закрыт имлицитно,
даже если вы его преждевременно прерываете по exit.
В отсутствии преждевременно завершения цикла курсор бдет выфетчен целиком.
И его имлицитно декларированный рекорд гарантированно доступен для стейтментов внутри тела цикла. А уж модифицировать его значение в этом цикле или вовсе не использовать - это уж как ваша фантазия сыграет. Вам гарантируется, что этот рекорд есть .
Гарантии эти даны были с самого начала и гарантированное поведение будет сохраняться до самого конца существования конструкции cursor for loop.
Иначе сам язык программирования сменит название .
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483941
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241...
Ты все передернул.
Ссылаться можно, конечно, в документации об этом прямо написано для обоих случаев. Про менять значение для Cursor FOR LOOP Statements ничего не написано, для FOR LOOP Statement явно написано, что нельзя, но опять же семантически и логически там разные разделы, даже в цитате type INTEGER должен о чем-то говорить.

касательно INTEGER - всего лишь о многолетней ошибке в документации.
Просто попробуй выполнить:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
begin
  for i in 1..4294967294
  loop
    sys.dbms_output.put_line(i);
  end loop;    
end;
/
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483952
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Единственное содержательное
boobyВторое, вообще говоря, гарантируется фразой Statements inside the loop can reference record and its fields ( Assignment statement - он вполне себе стейтмент, среди прочих),
а третье точно за рамками описывающей синтаксис документации.
Вы подгоняете под, то что хотите увидеть. Ссылаться можно. Это же написано в FOR LOOP Statement:

Statements inside the loop can reference index
но при этом:
, but cannot change its value.
Причем разделы не связаны. Были бы связаны, было бы логично распространить ограничение but cannot change its value, и на Cursor FOR LOOP Statement (при этом, бывают ситуации, что oracle разрешает, документация запрещает, не знаю как вы, но в таких ситуациях, если не доказано, что это documentation bug, я следую документации)

При этом никто пока, что даже примеров, когда эта техника может реально сократить код, не представил. Я так понимаю, тут битва идёт за собственный код.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483961
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241,

какая битва?
Твое представление правильное до тех пор, пока ты веришь в него.
Что до последнего - тема не звучала - когда лично вы, читатели форума, так делаете.
Вопрос - можно ли так делать вообще.
Так вот - персонально для вас - user1241 - нельзя .
По вашему праву иметь собственное мнение.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483962
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
boobyuser1241...
Ты все передернул.
Ссылаться можно, конечно, в документации об этом прямо написано для обоих случаев. Про менять значение для Cursor FOR LOOP Statements ничего не написано, для FOR LOOP Statement явно написано, что нельзя, но опять же семантически и логически там разные разделы, даже в цитате type INTEGER должен о чем-то говорить.

касательно INTEGER - всего лишь о многолетней ошибке в документации.
Просто попробуй выполнить:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
begin
  for i in 1..4294967294
  loop
    sys.dbms_output.put_line(i);
  end loop;    
end;
/


Видел, это мимо темы, сильно в сторону обсуждение пойдёт.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483968
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241
Видел, это мимо темы, сильно в сторону обсуждение пойдёт.
во, видишь как хорошо поговорили: я не читатель и все передернул, а ты, привыкший к документации, приплетаешь Integer, который о чем-то должен говорить, но, как оказалось, говорит мимо темы.
А говоришь битва.
Всего лишь речь идет о том, что то, что ты считаешь честью запретить лично для себя, у тебя нет сил запретить мне.
Вот такой он - цветочек аленький.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483971
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
boobyРазница, вероятно, здесь вот в чем:
в первом случае (For Loop) воздействовать на i (прямой аналог понятия итератора) означает прямую попытку слома итеративного цикла, что приводит к ошибке времени компиляции.
Второй случай (cursor for loop) сам цикл следует читать как for each в "других языках программирования".
То есть, во втором случае, переменная цикла не является итератором, который скрыт, и потому сам итератор нельзя сломать, а видимая переменная цикла есть просто значение, возвращаемое из коллекции скрытым от глаз писателя итератором.
И делай ты с этим значением что хошь.
Любая попытка объявить его immutable внутри цикла противоречила бы здравому смыслу.
Т.к.
а) это локальная копия значения из итерируемой коллекции и,
б) никакие манипуляции с ней не способны сломать сам цикл (его скрытый итератор или условия продолжения, что в данном случае, можно не различать)
В доке для cursor for loop это, по счастью не оговаривается, и любая попытка оговорить - опечалит (обессмыслит) полезность данного нам в таком виде for each
С учетом, что примеров нет, с первой частью согласен, с последним предложением нет. В первом случае есть смысл менять индекс, чтобы повлиять на ход цикла, во втором случае смысла менять loop index нет, по указанным в цитате же причинам (да и мало кто додумается), поэтому в документации про это ничего не написано, т.к. смысла нет. Если есть два объяснения, логично взять самое простое. Над сильно экзотическими ситуациями, можно наверное подумать, но если они почти не встречаются, не в счет.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483976
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241,
если пост был для меня - то я пас.
Этот поток слов уже даже на поток сознания перестал быть похожим.
Разговаривать с ботами у меня в моменте интереса нет.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483977
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241С учетом, что примеров нет
Попробуйте объяснить разницу между
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare
  cursor c in select * from ...;
  i c%rowtype;
begin
 open c;
 loop
   fetch c into i;
   exit when c%notfound;
   i.f := ...;
 end loop;
 close c;
end;


и
Код: plsql
1.
2.
3.
4.
5.
6.
7.
declare
  cursor c in select * from ...;
begin
  for i in c loop
   i.f := ...;
 end loop;
end;



Что до практических примеров - то в некоторых случаях обогащение в ETL вполне можно рассматривать как таковой.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483982
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andrey_anonymous,

в контексте этой темы, разница: в первом случае Basic LOOP Statement, во втором случае FOR LOOP Statement.
в первом случае явно объявленная переменная i, во втором случае неявно объявленный loop index i
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483984
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
user1241andrey_anonymous,

в контексте этой темы, разница: в первом случае Basic LOOP Statement, во втором случае FOR LOOP Statement.cursor FOR LOOP Statement
в первом случае явно объявленная переменная i, во втором случае неявно объявленный loop index i
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483986
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241,

в примерах andrey_anonymous во втором случае i - не индекс цикла .
i - элемент коллекции, состав которой определяется курсором, возвращаемый программисту на данном логическом шаге цикла.

Это не про индекс цикла ни в каком приближении.
Идекс цикла во втором случае, даже если есть физически по реализации, - логически недоступен.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483987
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241в первом случае явно объявленная переменная i, во втором случае неявно объявленный loop index i
В первом случае - явно объявленная i c%rowtype, во втором случае - неявно объявленная i c%rowtype.
Ни одном из примеров нет индекса , как способа повлиять на выполнение for loop.
А объяснить я прошу лишь одно - почему в случае 1 присвоение допустимо, а в случае 2 - нет.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39483994
nxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
логика как бы понятна, но
могли бы также логично сделать и по-другому

константное (immutable) значение можно инициализировать динамическим runtime-значением
обернули бы fetch как-то так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare 
                                        
  l_tmp varchar2(20);
    
  cursor c1 is select 'xx' from dual;
begin

  open c1;                
  fetch c1 into l_tmp;

  declare
    ctest CONSTANT varchar2(20) := l_tmp;
  begin
    dbms_output.put_line(ctest);
  end;                                  
  
  close c1;
  
end;
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484007
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,

в документации это так назвали, не знаю почему, пускай будет, record variable, т.е. неявно объявленная переменная типа %ROWTYPE.

record
Name for the loop index that the cursor FOR LOOP statement implicitly declares as a %ROWTYPE record variable of the type that cursor or select_statement returns.

2andrey_anonymous я нигде не писал, что недопустимо. Аргументации, чтобы назвать использование этой фичи правильным документированным способом решать задачи явно не хватает. Но это пускай каждый сам за себя решает.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484021
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nxx,

обрати внимание, что тебе пришлось буферизировать свою константу через изменяемую переменную. Т.е - проделать дополнительную работу с невысказанной целью.

Одна из традиций логических предпочтений опирается на соотнесение выбранных правил логики с некоторой реальностью.
Здесь "могла бы столь же логично" должно опираться на какую-то мыслимую историю, соотносимую с практическим миром возможностей.
В случае For loop проектировщики языка предотвращают ошибку программиста, ломающую заданное в условиях цикла его число шагов. То есть - это охрана работы алгоритма цикла.

Изменение значения переменной в cursor for loop не может сломать сам цикл.
С точки зрения синтаксиса - цикл целиком безопасен.
Требуя неизменности переменной цикла cursor for loop от разработчиков языка дай им
ясный категорический императив, приводящий к более безопасной инфраструктуре выполнения программы.
Не с точки зрения - могут ли быть ошибки в программировании бизнес логики (от таких ошибок нет защиты), а с точки зрения безопасности работы самой программы - она уйдет в область не инициализированных адресов и завершит работу авостом,
или впадет в бесконечный цикл или еще какая-то катастрофа ее ожидает в конструкции cursor for loop именно от факта изменения переменной цикла.

Главный поинт в том, что текущее значение переменной цикла в cursor for loop не соотносится ни с возможностью продолжения, ни с возможностью прекращения цикла.
Цикл нельзя сломать, воздействуя на неё.
Как повысится безопасность языка, если такое воздействие взять и запретить?
Должен быть либо смысл запрета, либо запрет ограничивает возможности языка.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484024
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241,
если там так на самом деле написано - то это простой дефект документации.
Это не индекс.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484032
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241Аргументации, чтобы назвать использование этой фичи правильным документированным способом
Пока что не хватает аргументации, чтобы назвать использование этой "фичи" неправильным.

1. Практика:
- Логически два приведенных мной примера эквивалентны.
- Контрпример отсутствует.
По сути курсорный for loop можно рассматривать как синтаксический сахар, обертку вокруг варианта 1.

2. По документации - уже не раз отмечено в этом топике, что использовать курсорный индекс можно, НО не в качестве lvalue . Что же касается курсорного цикла - то ссылаться на record variable можно без упомянутого ограничения .
Таким образом, присвоение значений атрибутам record variable - легально.

3. Поднимем ставки по документации:
http://www.oracle.com/us/corporate/pricing/olsa-ru-v111003-070656.pdf ORACLE DOES NOT GUARANTEE THAT THE
PROGRAMS WILL PERFORM ERROR-FREE OR
UNINTERRUPTED OR THAT ORACLE WILL
CORRECT ALL PROGRAM ERRORS.
...THERE ARE
NO OTHER EXPRESS OR IMPLIED WARRANTIES
OR CONDITIONS, INCLUDING WARRANTIES OR
CONDITIONS OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE.

Судя по этому ДОКУМЕНТУ, ПО Oracle вообще нельзя применять в какой-либо PARTICULAR PURPOSE, а все истории про высокую доступность, надежность и прочее - суть маркетинговый буллшит.
Сливаем компоненты?
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484033
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241При этом никто пока, что даже примеров, когда эта техника может реально сократить код, не представил.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SQL> ed
Wrote file afiedt.buf

  1  begin
  2   --аля создать по шабону
  3   for r in (select * from t where id=1) loop
  4    r.id:=-r.id;
  5    insert into t values r;
  6   end loop;
  7* end;
SQL> /

PL/SQL procedure successfully completed.



....
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484038
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stax..user1241При этом никто пока, что даже примеров, когда эта техника может реально сократить код, не представил.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SQL> ed
Wrote file afiedt.buf

  1  begin
  2   --аля создать по шабону
  3   for r in (select * from t where id=1) loop
  4    r.id:=-r.id;
  5    insert into t values r;
  6   end loop;
  7* end;
SQL> /

PL/SQL procedure successfully completed.




....
stax 20613006
не оно?
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484051
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx 20613006
не оно?

оно, я просто долго набирал/постил

но по любому "переменная" за рамками loop не доступна

.....
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484054
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
nxxлогика как бы понятна, но
могли бы также логично сделать и по-другому

константное (immutable) значение можно инициализировать динамическим runtime-значением
обернули бы fetch как-то так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
declare 
                                        
  l_tmp varchar2(20);
    
  cursor c1 is select 'xx' from dual;
begin

  open c1;                
  fetch c1 into l_tmp;

  declare
    ctest CONSTANT varchar2(20) := l_tmp;
  begin
    dbms_output.put_line(ctest);
  end;                                  
  
  close c1;
  
end;



імхо
оракля примерно (не константой) так и обявляет
переменных две
уровня блока и уровня цикла
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SQL> <<b>>
  2  declare
  3   i integer :=0;
  4  begin
  5   for i in 1..10 loop
  6    b.i:=100;
  7    null;
  8   end loop;
  9   dbms_output.put_line(i);
 10  end;
 11  /
100

PL/SQL procedure successfully completed.



.....
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484542
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По поводу актуальности.

andreymx
Код: sql
1.
2.
3.
4.
5.
6.
for rec in (select * from table where ***)
loop
    rec.id := null;
    rec.param1 := 1;
    insert into table values rec;
end loop;


stax..
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SQL> ed
Wrote file afiedt.buf

  1  begin
  2   --аля создать по шабону
  3   for r in (select * from t where id=1) loop
  4    r.id:=-r.id;
  5    insert into t values r;
  6   end loop;
  7* end;
SQL> /

PL/SQL procedure successfully completed.



....
stax
Где-то может и сойдёт, покрутить где-нибудь в мозговых задачках, но, тёмную сторону скрыли, в production я бы пилить такое не стал.
Трудно назвать хорошим код, который ломается при добавлении столбца в таблицу или вьюшку неизвестно где в N мест.

см. что Кайт пишет по этому поводу:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:676611400346196844 A reader
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table xx(i date,k as (to_char(i,'yyyy')) check (k in ('2010','2011')));

declare xx_rec xx%rowtype;begin xx_rec.i:=sysdate;insert into xx values xx_rec;end;
  2  /
declare xx_rec xx%rowtype;begin xx_rec.i:=sysdate;insert into xx values xx_rec;end;
*
ERROR at line 1:
ORA-54013: INSERT operation disallowed on virtual columns
ORA-06512: at line 1


I guess this means that existing code that uses %ROWTYPE will break if a virtual column is added to a table. Any way around this? Thanks

Tom KyteIt is what it is. Not any different than if you were not granted insert on that column.

Even worse would be if your code use the record type to blindly insert all columns without thought - AND someone adds a new column with a default value. Guess what would happen - you would defeat the default.

Recommend always - always - to use the column list when inserting - always.

insert into t ( c1, c2, c3, .. ) values ....

never

insert into t values ( ...);


I don't like the insert into T values <record> "ability" at all - a very shaky proposition.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484548
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241По поводу актуальности.


Где-то может и сойдёт, покрутить где-нибудь в мозговых задачках, но, тёмную сторону скрыли, в production я бы пилить такое не стал.
Трудно назвать хорошим код, который ломается при добавлении столбца в таблицу или вьюшку неизвестно где в N мест.

см. что Кайт пишет по этому поводу:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:676611400346196844 пропущено...

пропущено...


Вы про *
1) лень было поля перечислять для примера
2) покажите, как добавление поля сломает приведенный код?

......
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484560
dbpatch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241Elic,

По мне так, здесь ключевые слова implicitly declares.
В обычном For Loop тоже variable, не константа , но менять нельзя:

FOR LOOP Index
The index of a FOR LOOP statement is implicitly declared as a variable of type INTEGER that is local to the loop. The statements in the loop can read the value of the index, but cannot change it. Statements outside the loop cannot reference the index.

С одной стороны менять cursor FOR LOOP index в документации не запрещено. С другой стороны менять неявно объявленные переменные без надлежащих причин, про которые не написано, что их можно менять, bad practice. сугубо имхо.

вы прямо с дуба рухнули, чесслово.

как в качестве индексной переменной может использоваться константа ?
i - то меняется, а не сохраняет неизменное значение на протяжении всего жизненного цикла

в остальном - в документации все четко сказано, читать можно, менять нельзя. переменяет эту переменную нечто, но не statements inside loop, никакого противоречия
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484593
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stax..Вы про *
1) лень было поля перечислять для примера
2) покажите, как добавление поля сломает приведенный код?

......
stax
Если * нет, null логично прописать в запросе (и с явным курсором в том числе, над очень экзотическими ситуациями можно подумать, но врят ли кто-то реально использует до такой степени эту фичу)

11g+
Код: 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.
SQL> drop table xx;

Table dropped.

SQL>
SQL> create table xx(id number,i date);

Table created.

SQL>
SQL> insert into xx(i) values(sysdate);

1 row created.

SQL>
SQL> commit;

Commit complete.

SQL>
SQL> begin
  2     --аля создать по шабону
  3     for r in (select * from xx) loop
  4
  5       r.id:=-r.id;
  6       insert into xx values r;
  7     end loop;
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL>
SQL> alter table XX add k as (TO_CHAR("I",'yyyy'));

Table altered.

SQL>
SQL> begin
  2     --аля создать по шабону
  3     for r in (select * from xx) loop
  4
  5       r.id:=-r.id;
  6       insert into xx values r;
  7     end loop;
  8  end;
  9  /
begin
*
ERROR at line 1:
ORA-54013: INSERT operation disallowed on virtual columns

...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484598
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241Если * нет, null логично прописать в запросе
ШО?!

В запросе логично прописывать те поля, с которыми работаешь.
И %rowtype объявлять не от таблицы, а от курсора.
Соответственно, в insert перечисление полей - тоже must have.
И все нормально с "фичей"
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484604
user1241
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
+По поводу актуальности:

andrey_anonymoususer1241С учетом, что примеров нет
Попробуйте объяснить разницу между
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
declare
  cursor c in select * from ...;
  i c%rowtype;
begin
 open c;
 loop
   fetch c into i;
   exit when c%notfound;
   i.f := ...;
 end loop;
 close c;
end;


и
Код: plsql
1.
2.
3.
4.
5.
6.
7.
declare
  cursor c in select * from ...;
begin
  for i in c loop
   i.f := ...;
 end loop;
end;



Что до практических примеров - то в некоторых случаях обогащение в ETL вполне можно рассматривать как таковой.
Желательно более полный пример, пусть с ETL, с тем как это используется.
И желательно, где нет выше описанной проблемы, и код, который не было бы лучше переписать через bulk collect / forall.

andrey_anonymous3. Поднимем ставки по документации:
По поводу отсутствии гарантии исправления ошибок, с этим так или иначе можно везде столкнуться, кто-то видит одно, кто-то видит иначе, оракл имеет право на свое мнение, по крайней мере об этом честно пишет. Мне кажется тут больше, чтобы отсеять совсем неадекватов. При серьезных претензиях, сомневаюсь, что этот пункт будет играть определяющую роль в суде.

имхо.

Предлагаю от темы документации перейти к теме использования в production системах.
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484616
stax..
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241stax..Вы про *
1) лень было поля перечислять для примера
2) покажите, как добавление поля сломает приведенный код?

......
stax
Если * нет, null логично прописать в запросе (и с явным курсором в том числе, над очень экзотическими ситуациями можно подумать, но врят ли кто-то реально использует до такой степени эту фичу)

11g+
Код: 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.
SQL> drop table xx;

Table dropped.

SQL>
SQL> create table xx(id number,i date);

Table created.

SQL>
SQL> insert into xx(i) values(sysdate);

1 row created.

SQL>
SQL> commit;

Commit complete.

SQL>
SQL> begin
  2     --аля создать по шабону
  3     for r in (select * from xx) loop
  4
  5       r.id:=-r.id;
  6       insert into xx values r;
  7     end loop;
  8  end;
  9  /

PL/SQL procedure successfully completed.

SQL>
SQL> alter table XX add k as (TO_CHAR("I",'yyyy'));

Table altered.

SQL>
SQL> begin
  2     --аля создать по шабону
  3     for r in (select * from xx) loop
  4
  5       r.id:=-r.id;
  6       insert into xx values r;
  7     end loop;
  8  end;
  9  /
begin
*
ERROR at line 1:
ORA-54013: INSERT operation disallowed on virtual columns



Вы про виртуальные колонки, я с ними ниразу не стыкался

* во многих случаях плохо

я от звездочки отвык из-за репорта
у меня выходило примерно так
если репорт создать на основе селекта со * то все работало,
но если напр добавить столбец (не виртуальный), то требовалась перекопиляция

потом я вообще отказался от формата rep

* использую в основном из-за лени
да и for loop вместо ореn/fetch, тож удобное лентяйство

......
stax
...
Рейтинг: 0 / 0
а че, так можно было ?
    #39484625
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
user1241Что до практических примеров - то в некоторых случаях обогащение в ETL вполне можно рассматривать как таковой.
Желательно более полный пример, пусть с ETL, с тем как это используется.
[/quot]
1. Генерация суррогатного ключа по правилам чуть более сложным, чем sequence
2. Обогащение кодом словарной статьи (в ассоциативном массиве держим словари) - снижает количество join в запросе, что при параллельном исполнении на большом объеме может давать профит за счет уменьшения использования temp под буферизацию
3. [телеком] Обогащение записи о соединении кодом города (максимально полное соответствие при переменной длине префикса) - неплохо решается на ассоциативном массиве зоновой разбивки.
Elic что-то подобное говорил про номера банковских карт (BIN?).

user1241И желательно, где нет выше описанной проблемы, и код, который не было бы лучше переписать через bulk collect / forall.

Описанной проблемы нет, если следовать правилу явного перечисления полей - как в курсоре, так и в insert.
Переписывание под bulk collect не всегда оправдано ввиду автоматического "переписывания под bulk collect" курсорных циклов на дефолтном уровне оптимизации pl/sql в современных версиях rdbms.

user1241andrey_anonymous3. Поднимем ставки по документации:
Мне кажется тут больше, чтобы отсеять совсем неадекватов. При серьезных претензиях, сомневаюсь, что этот пункт будет играть определяющую роль в суде.
Ну-ну.
Таким образом, если я правильно понял, некая филькина грамота под названием "документация" (которая сама по себе содержит баги и меняется вендором по собственному произволу) имеет для Вас решающее значение (даже не документация, а Ваша интерпретация этой документации), а документ, являющийся частью договора , т.е. юридически значимого документа, от того же вендора, где он говорит о том, что не гарантирует применимости своего продукта для решения любой конкретной задачи - это типа страшилки.
Очень последовательно :)
...
Рейтинг: 0 / 0
52 сообщений из 52, показаны все 3 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / а че, так можно было ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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