|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
SY, Вы пишите примерно так: "вызывающий видит, и потому может..." В этом примере вызывающий (а здесь вызывающим является сам компилируемый блок кода) тоже всё "видит", и если не "может", надо бы определить - почему. То, что написали Вы, можно было бы интерпретировать так: - атрибут для Not Null у типа всегда есть, он может быть заполненным или нет, но обратиться и проверить его можно всегда. Значит, к объявлению любой переменной можно дописать Not Null, и для неё может быть использована ссылка на копию описателя базового типа, но с заполненным атрибутом. ----------- Иным способом это можно было бы представить так - увидев объявление n Number Not Null Default 0, компилятор расширяет раздел деклараций и, скрытым образом дописывает в него определение типа локальной области видимости. И я подразумевал точно это. Параметр с точки зрения использующего кода внутри процедуры в этом отношении неотличим от локальной переменной, он и есть - локальная переменная в области видимости процедуры. (И в этом смысле было бы хорошо, если бы доступный для описания его ограничений типа синтаксис, был доступен и для любых других переменных локальной области видимости, тогда предложенный вариант кода тоже окажется компилируемым) Но, в отличие от прочих переменных локальной области, у параметра есть внешние обязательства, нельзя обойтись скрытым расширением области объявлений - тип параметра должен быть известен и правильно использован, даже в случае, когда система не резервирует атрибут Nullable/Not Nullable, а использует его по необходимости ... Далее мне можно было бы слово в слово повторить предыдущий свой пост, но я разрешу себе этого не делать, sorry. ... Вообще, такого рода тему, можно было обсуждать и в терминах "автоматически выводимых типов", но я скептически на это смотрю - одно дело заменять "недостаточно точно типизированные" значения на "более точно" типизированные, это то, что я назвал "движением от C к Ada". Совсем другое дело, когда говорят - точный тип вам указывать не надо, компилятор умный и сам его выведет. Это дорога от "C в ад". Ну, в самом удачном случае, если всё-таки нужно как-то сохранять работоспособность кода - "от C к Basic-у". Только "производительность" тогда становится левым вопросом. вот примерно так я сейчас думаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 22:28 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
SY, Кстати, в контексте упоминания Domain Names и прочих охов. Вообще говоря, на 99.99% было бы достаточно, если бы объявление сорта n table.field%type; Наследовало бы и Not Null от поля таблицы. По всем формальном признакам объявление типа поля в таблице обязано, и должно иметь все свойства допустимого и глобально видимого объявления типа. Именно к этому было и упоминание о Domain Names - новый логический конструкт позволил бы исправить старые ошибки. А без него - не больно-то и сделаешь. Кто возьмет на себя костюм супергероя? Там дедушки в компании. Хитрые, умные и осторожные... ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 22:47 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Помечтаю: Код: plsql 1.
Где "int not null" - новый скалярный тип, которому нельзя присвоить null, а также переменную которая может принимать значение null. Проверка компиляции. Код: plsql 1. 2. 3. 4. 5.
Все литералы будут иметь тип not null, поэтому присвоение констант не изменится. Преобразование переменных nullable в not null будет только в явном виде, через nvx (), где второй параметр not null. Такое частичное введение сильной типизации усложнит язык во имя решения второстепенной проблемы. PL/SQL сильной типизацией не страдал, лучше не начинать. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:04 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
НеофитSQL, вас точно забанят. Терпимость терпимостью, но детский сад утомляет. Перестаньте, как тодлер, озвучивать все слова, которые вы только что услышали. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:11 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
booby, Не флудите в моей теме, пожалуйста. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:16 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
А, я неясно определил "вызывающий", "вызываемый". Это не пользовательский код а код самого Oracle который генерируется при компиляции. Например имеем: Код: plsql 1. 2. 3. 4. 5. 6. 7.
При компиляции Код: plsql 1. 2. 3. 4. 5. 6. 7. 8.
проверяется что есть p1 и ее параметры и посколько formal параметр date а actual параметр varchar2 генерируется код для преобразования v_param из varchar2 в date которое выполнится при вызове и только тогда выяснится преобразуется v_param в date или нет. Так что все что Oracle должен сделать это разрешить указание NULL/NOT NULL в formal параметре, добавить поле NULLABLE в SYS.ARGUMENT$, при компиляции дополнительно проверить NULLABLE в "что есть p1 и ее параметры" и если NOT NULL сгенерировать код проверки actual параметр на NULL при вызове. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:18 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
SY, извините, я не могу это правильно прочитать. У меня чепуха какая-то получается... Во всяком случае, я попробовал пояснить свои соображения. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2020, 23:36 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
SY при компиляции дополнительно проверить Добавление not null в таком случае должно считаться изменением сигнатуры и инвалидировать все зависимости? ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2020, 09:23 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
На выходных почитал SYS.STANDARD, пока мое решение для [subj] выглядит так: Код: plsql 1. 2.
Это похоже на уже предложенные идеи в начале темы, используя уже существующий для этих целей тип. Эффект: передача константы null ловится во время компиляции. передача переменной или выражения в 11.2 ловится только во время исполнения, но с внятным обозначением проблемы в строке вызывающего кода (что для меня важно, если кто-то передает в мой API неверные параметры, предпочтительно чтобы ошибка была очевидной, без необходимости лезть в мой код или в документацию) Можно сказать, проблема на 80% решена. Что я еще пробовал: определить новый скалярный тип (а не субтип) используя служебное слово "new". Идея в том, что подтипы и типы взаимозаменяемы на стадии компиляции, а мне нужно запретить неявный каст integer->simple_integer. Оракл ругается, что оператор "new" в определениях типе зарезервировал для системы, и юзерам это не дано. Когда будет время, я собираюсь посмотреть можно ли неявный каст запретить через тип-объект, чтобы осуществить следующее: Код: plsql 1. 2. 3. 4. 5. 6. 7.
пока я вижу что Оракл автоматически создает конструкторы для кастов в тип объекта, и их невозможно скрыть объявлением private, т.к. этот элемент языка отсутствует. Но нашел пару других механизмов, которые прячут конструкторы. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2020, 16:14 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
env SY при компиляции дополнительно проверить Добавление not null в таком случае должно считаться изменением сигнатуры и инвалидировать все зависимости? Это так. У процедур f( n in natural ) и f( n in naturalN ) разные сигнатуры. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.09.2020, 16:40 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Подкину свои пять копеек - Можно передавать NULL в параметре, а можно пропустить этот параметр. Это эквивалентные действия? Или нужны две проверки? И как быть если процедура головная и вызывается прямо из OCI? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 13:41 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Bfink, Задача изначально была запретить возможность передачи null на уровне компиляции в функции с простыми скалярными' параметрами. ТС (я) надеялся что наличие такого механизма позволит объявить функции "скалярными' и избавит от нудной но необходимой проверки на null в блоке валидации параметров функций. С тех пор я увидел что простого механизма это сделать не существует, а также вполне привык ожидать null в любом выражении. Температура среды? null. Вес объекта? null. Количество памяти отведенное под объект? null. Идентификатор типа переменной number которой присвоили null? Null, т.к. это ещё и тип. (Поймался разок при декапсуляции в DCOM). ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 14:29 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Bfink Подкину свои пять копеек - Можно передавать NULL в параметре, а можно пропустить этот параметр. Это эквивалентные действия? Или нужны две проверки? И как быть если процедура головная и вызывается прямо из OCI? Передать NULL означает передать значение actual параметра явно. Опустить параметр означает проверку а задан ли DEFAULT для formal параметра который и становится значением actual параметра. А ситуация Код: plsql 1.
отсечется еще при компиляции. A в OCI проверки думаю при OCIStmtPrepare. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 14:43 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
НеофитSQL вполне привык ожидать null в любом выражении. Я бы еще добавил - манипуляция со строками, например, trim и опа - NULL ! ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 14:57 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
SY, если нет default, то можно отличить фактический параметр NULL от пропущенного параметра внутри процедуры? OCI подкидывает прикольные вещи, например, я не умею породить NAN в binary_float внутри PLSQL, а OCI легко делает это на входе. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 15:01 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Bfink SY, если нет default, то можно отличить фактический параметр NULL от пропущенного параметра внутри процедуры? OCI подкидывает прикольные вещи, например, я не умею породить NAN в binary_float внутри PLSQL, а OCI легко делает это на входе. А что тут отличать? Если Oracle осуществляет проверки перед вызовом то тупо смотрим есть ли у formal параметрa default. Если Oracle осуществляет проверки вызываемом коде то скорее всего передается флаг опущен данный actual параметр или нет. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 15:09 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Bfink SY, если нет default, то можно отличить фактический параметр NULL от пропущенного параметра внутри процедуры? OCI подкидывает прикольные вещи, например, я не умею породить NAN в binary_float внутри PLSQL, а OCI легко делает это на входе. Насколько я понимаю PL/SQL, с точки зрения вызываемой процедуры пропущеных параметров не бывает, т.к. компилятор или выдаст ошибку в вызывающем коде, или (если указано значение default) подставит значение по умолчанию, как если бы оно было явным. Как результат, в вызываемой процедуре невозможно сказать, была она вызвана с пропущенным параметром, или с параметром, значение которого совпадает с default. Объявление процедуры proc( i in simple_integer ) защищает от явной передачи null в виде константы, но не защищает от передачи переменной или выражения, которые окажутся null. Породить float/NAN возможно, , или вы хотели это сделать как результат арифметической операции? f1 binary_float := BINARY_FLOAT_NAN; f2 binary_float := utl_raw.cast_to_binary_float('ffc00000'); ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 15:35 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
НеофитSQL Породить float/NAN возможно А в NUMBER, который тип колонки в таблице? infinity можно. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 17:26 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Bfink А в NUMBER, который тип колонки в таблице? infinity можно. Видел NaN в Oracle'вой табличке (нужно было базу в PostgreSQL перегнать). Очень мучался. JDBC падало. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 17:46 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Leonid Kudryavtsev, Так вот же виновник ! з.ы. Example порадовал, видимо есть и запись с обратным условием Код: plsql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 17:50 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
env з.ы. Example порадовал, видимо есть и запись с обратным условием ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 18:09 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Bfink НеофитSQL Породить float/NAN возможно А в NUMBER, который тип колонки в таблице? infinity можно. внутренний формат NUMBER позволяет хранить особые значения, но посмотрев на код Оракла я сомневаюсь что NaN поддерживается для этого типа, по крайней мере в PL/SQL. Почему я так считаю: - в STANDARD не определена константа для NUMBER_NAN как она определена для нескольких других типов. - имплементация стандартной функции NANVL(NUMBER,NUMBER) не учитывает такой возможности, просто возвращает первый параметр. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 19:31 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
Я, кстати, не знал, что NUMBER позволяет хранить infinity. Только что поигрался с этим, обнаружил следующее: В PL/SQL присутствует полная поддержка для десятичной бесконечности, кроме определения NUMBER_INFINITY. Есть положительная и отрицательная бесконечности, определена функция "is infinite" для типа NUMBER, арифметика работает как ожидается, вычислительные функции тоже. Косинус от нее равен одному. Это говорит об отсутствии NaN/NUMBER, т.к. косинус от двоичной бесконечности это NaN. В PL/SQL ее можно кастить в BINARY_FLOAT и обратно, все отрабатывается корректно. Преобразование в строку работает, хотя вместо 'Inf' оно печатает совсем другое. В SQL с этой величиной печально, даже чтобы ее создать пришлось извернуться. SQL строго ловит арифметические переполнения и не разрешает касты от 1/0f. Когда получилось ее создать, все операции вылетают по ошибке, даже "is infinite" (иронично!). SQL явно не любит эту величину, а вот с бинарными бесконечностями работает нормально. А как вы столкнулись с десятичной бесконечностью в таблице? Пришла через импорт? ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 19:44 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
НеофитSQL Я, кстати, не знал, что NUMBER позволяет хранить infinity. Только что поигрался с этим, обнаружил следующее: В PL/SQL присутствует полная поддержка для десятичной бесконечности, кроме определения NUMBER_INFINITY. Есть положительная и отрицательная бесконечности, определена функция "is infinite" для типа NUMBER, арифметика работает как ожидается, вычислительные функции тоже. Косинус от нее равен одному. В PL/SQL ее можно кастить в BINARY_FLOAT и обратно, все отрабатывается корректно. Преобразование в строку работает, хотя вместо 'Inf' оно печатает совсем другое. В SQL с этой величиной печально, даже чтобы ее создать пришлось извернуться. SQL строго ловит арифметические переполнения и не разрешает касты от 1/0f. Когда получилось ее создать, все операции вылетают по ошибке, даже "is infinite" (иронично!). SQL явно не любит эту величину, а вот с бинарными бесконечностями работает нормально. А как вы столкнулись с десятичной бесконечностью в таблице? Пришла через импорт? Аж до 11.1 официально поддерживались inf для обратной совместимости с Oracle 5: 11.1 https://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#CNCPT313 10.2 https://docs.oracle.com/cd/B19306_01/server.102/b14220/datatype.htm#sthref3810 9i https://docs.oracle.com/cd/B10501_01/server.920/a96524/c13datyp.htm#16210 8i https://docs.oracle.com/cd/A87860_01/doc/server.817/a76965/c10datyp.htm#743 7 https://docs.oracle.com/cd/A57673_01/DOC/server/doc/SCN73/ch6.htm авторThe following numbers can be stored in a NUMBER column:
авторIf a positive NUMBER value is extremely large and cannot be represented in the specified format, then the infinity sign (~) replaces the value. Likewise, if a negative NUMBER value is extremely small and cannot be represented by the specified format, then the negative infinity sign replaces the value (-~). ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 20:23 |
|
Запретить передачу null параметра в PL/SQL procedure
|
|||
---|---|---|---|
#18+
НеофитSQL, Бесконечность получить просто, в колонку NUMBER нужно инсертить 1/0b или -1/0b для отрицательной бесконечности. А вот NaN так вставить не удалось. Зато OCI это делает легко - вставляешь строку в числовой параметр и в таблице очень плохое значение. Оно почему то больше нуля и его можно выделить на равенство. Особенно прикольно делать по этой колонке группировку. ... |
|||
:
Нравится:
Не нравится:
|
|||
02.10.2020, 20:26 |
|
|
start [/forum/topic.php?fid=52&msg=40003513&tid=1880836]: |
0ms |
get settings: |
6ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
139ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
others: | 309ms |
total: | 549ms |
0 / 0 |