powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запретить передачу null параметра в PL/SQL procedure
25 сообщений из 114, страница 4 из 5
Запретить передачу null параметра в PL/SQL procedure
    #40002706
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Вы пишите примерно так: "вызывающий видит, и потому может..."
В этом примере вызывающий (а здесь вызывающим является сам компилируемый блок кода) тоже всё "видит",
и если не "может", надо бы определить - почему.

То, что написали Вы, можно было бы интерпретировать так: - атрибут для Not Null у типа всегда есть,
он может быть заполненным или нет, но обратиться и проверить его можно всегда.
Значит, к объявлению любой переменной можно дописать Not Null, и для неё может быть использована ссылка на
копию описателя базового типа, но с заполненным атрибутом.
-----------
Иным способом это можно было бы представить так - увидев объявление n Number Not Null Default 0,
компилятор расширяет раздел деклараций и, скрытым образом дописывает в него определение типа локальной области видимости.

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

Но, в отличие от прочих переменных локальной области, у параметра есть внешние обязательства,
нельзя обойтись скрытым расширением области объявлений - тип параметра должен быть известен и правильно использован,
даже в случае, когда система не резервирует атрибут Nullable/Not Nullable, а использует его по необходимости
...
Далее мне можно было бы слово в слово повторить предыдущий свой пост, но я разрешу себе этого не делать, sorry.
...
Вообще, такого рода тему, можно было обсуждать и в терминах "автоматически выводимых типов",
но я скептически на это смотрю - одно дело заменять "недостаточно точно типизированные" значения на "более точно" типизированные,
это то, что я назвал "движением от C к Ada".
Совсем другое дело, когда говорят - точный тип вам указывать не надо, компилятор умный и сам его выведет.
Это дорога от "C в ад".
Ну, в самом удачном случае, если всё-таки нужно как-то сохранять работоспособность кода - "от C к Basic-у".
Только "производительность" тогда становится левым вопросом.
вот примерно так я сейчас думаю.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40002711
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Кстати, в контексте упоминания Domain Names и прочих охов.
Вообще говоря, на 99.99% было бы достаточно, если бы объявление сорта
n table.field%type;
Наследовало бы и Not Null от поля таблицы.

По всем формальном признакам объявление типа поля в таблице обязано, и должно иметь все свойства
допустимого и глобально видимого объявления типа.

Именно к этому было и упоминание о Domain Names - новый логический конструкт позволил бы исправить старые ошибки.
А без него - не больно-то и сделаешь.
Кто возьмет на себя костюм супергероя?
Там дедушки в компании. Хитрые, умные и осторожные...
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40002717
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помечтаю:

Код: plsql
1.
function abs( n int not null ) return int not null;



Где "int not null" - новый скалярный тип, которому нельзя присвоить null, а также переменную которая может принимать значение null. Проверка компиляции.

Код: plsql
1.
2.
3.
4.
5.
n int not null := 3;
k int := 6;
...
k := n; -- так можно
n := k; -- нельзя, неявный каст в nullable запрещен во время компиляции



Все литералы будут иметь тип not null, поэтому присвоение констант не изменится. Преобразование переменных nullable в not null будет только в явном виде, через nvx (), где второй параметр not null.

Такое частичное введение сильной типизации усложнит язык во имя решения второстепенной проблемы.
PL/SQL сильной типизацией не страдал, лучше не начинать.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40002722
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

вас точно забанят.
Терпимость терпимостью, но детский сад утомляет.
Перестаньте, как тодлер, озвучивать все слова, которые вы только что услышали.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40002724
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
booby,


Не флудите в моей теме, пожалуйста.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40002726
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, я неясно определил "вызывающий", "вызываемый". Это не пользовательский код а код самого Oracle который генерируется при компиляции. Например имеем:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
create or replace
  procedure p1(p_par date)
    is
    begin
        null;
end;
/



При компиляции

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
create or replace
  procedure p2
    is
        v_param varchar2(10);
    begin
        p_1(v_param);
end;
/



проверяется что есть 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.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40002730
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

извините, я не могу это правильно прочитать.
У меня чепуха какая-то получается...

Во всяком случае, я попробовал пояснить свои соображения.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40003211
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
при компиляции дополнительно проверить

Добавление not null в таком случае должно считаться изменением сигнатуры и инвалидировать все зависимости?
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40003513
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На выходных почитал SYS.STANDARD, пока мое решение для [subj] выглядит так:

Код: plsql
1.
2.
-- функция меняет знак целого параметра, пытается защититься от передачи null
function Neg( n in simple_integer ) return simple_integer deterministic;



Это похоже на уже предложенные идеи в начале темы, используя уже существующий для этих целей тип.
Эффект: передача константы null ловится во время компиляции. передача переменной или выражения в 11.2 ловится только во время исполнения, но с внятным обозначением проблемы в строке вызывающего кода (что для меня важно, если кто-то передает в мой API неверные параметры, предпочтительно чтобы ошибка была очевидной, без необходимости лезть в мой код или в документацию)

Можно сказать, проблема на 80% решена.

Что я еще пробовал: определить новый скалярный тип (а не субтип) используя служебное слово "new".
Идея в том, что подтипы и типы взаимозаменяемы на стадии компиляции, а мне нужно запретить неявный каст integer->simple_integer.
Оракл ругается, что оператор "new" в определениях типе зарезервировал для системы, и юзерам это не дано.

Когда будет время, я собираюсь посмотреть можно ли неявный каст запретить через тип-объект, чтобы осуществить следующее:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
-- функция меняет знак целого параметра, пытается защититься от передачи null
function Neg( n in safe_int ) return safe_int deterministic;
n integer;
...
  ..Neg( n ); -- ошибка компиляции, отсутствует неявный каст integer->safe_int
  ..Neg( 5 ); -- работает, есть неявный каст или конструктор из simple_integer->safe_int (оракл в доках обещает что литералы обладают атрибутом "not null")
  ..8 +Neg( 5 ); -- работает, есть неявный каст safe_int->simple_integer



пока я вижу что Оракл автоматически создает конструкторы для кастов в тип объекта, и их невозможно скрыть объявлением private, т.к. этот элемент языка отсутствует. Но нашел пару других механизмов, которые прячут конструкторы.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40003537
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
env
SY
при компиляции дополнительно проверить

Добавление not null в таком случае должно считаться изменением сигнатуры и инвалидировать все зависимости?


Это так. У процедур f( n in natural ) и f( n in naturalN ) разные сигнатуры.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004870
Bfink
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подкину свои пять копеек -
Можно передавать NULL в параметре, а можно пропустить этот параметр.
Это эквивалентные действия? Или нужны две проверки?
И как быть если процедура головная и вызывается прямо из OCI?
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004895
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bfink,

Задача изначально была запретить возможность передачи null на уровне компиляции в функции с простыми скалярными' параметрами.

ТС (я) надеялся что наличие такого механизма позволит объявить функции "скалярными' и избавит от нудной но необходимой проверки на null в блоке валидации параметров функций.

С тех пор я увидел что простого механизма это сделать не существует, а также вполне привык ожидать null в любом выражении. Температура среды? null. Вес объекта? null. Количество памяти отведенное под объект? null.
Идентификатор типа переменной number которой присвоили null? Null, т.к. это ещё и тип. (Поймался разок при декапсуляции в DCOM).
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004901
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bfink
Подкину свои пять копеек -
Можно передавать NULL в параметре, а можно пропустить этот параметр.
Это эквивалентные действия? Или нужны две проверки?
И как быть если процедура головная и вызывается прямо из OCI?


Передать NULL означает передать значение actual параметра явно. Опустить параметр означает проверку а задан ли DEFAULT для formal параметра который и становится значением actual параметра. А ситуация

Код: plsql
1.
some_param ... DEFAULT NULL NOT NULL


отсечется еще при компиляции. A в OCI проверки думаю при OCIStmtPrepare.

SY.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004904
Bfink
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
вполне привык ожидать null в любом выражении.


Я бы еще добавил - манипуляция со строками, например, trim и опа - NULL !
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004908
Bfink
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

если нет default, то можно отличить фактический параметр NULL от пропущенного параметра внутри процедуры?
OCI подкидывает прикольные вещи, например, я не умею породить NAN в binary_float внутри PLSQL, а OCI легко делает это на входе.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004913
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bfink
SY,

если нет default, то можно отличить фактический параметр NULL от пропущенного параметра внутри процедуры?
OCI подкидывает прикольные вещи, например, я не умею породить NAN в binary_float внутри PLSQL, а OCI легко делает это на входе.


А что тут отличать? Если Oracle осуществляет проверки перед вызовом то тупо смотрим есть ли у formal параметрa default. Если Oracle осуществляет проверки вызываемом коде то скорее всего передается флаг опущен данный actual параметр или нет.

SY.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004922
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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');
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004959
Bfink
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Породить float/NAN возможно


А в NUMBER, который тип колонки в таблице?

infinity можно.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004967
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Bfink
А в NUMBER, который тип колонки в таблице?

infinity можно.

Видел NaN в Oracle'вой табличке (нужно было базу в PostgreSQL перегнать). Очень мучался. JDBC падало.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004968
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

Так вот же виновник !

з.ы. Example порадовал, видимо есть и запись с обратным условием
Код: plsql
1.
SELECT last_name FROM employees WHERE salary IS NOT INFINITE;
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004972
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
env
з.ы. Example порадовал, видимо есть и запись с обратным условием
сначала налоги с такой зарплаты заплати NULL или NaN и то получше будут - хоть в тюрьму не посадят
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004994
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bfink
НеофитSQL
Породить float/NAN возможно


А в NUMBER, который тип колонки в таблице?

infinity можно.


внутренний формат NUMBER позволяет хранить особые значения, но посмотрев на код Оракла я сомневаюсь что NaN поддерживается для этого типа, по крайней мере в PL/SQL.

Почему я так считаю:
- в STANDARD не определена константа для NUMBER_NAN как она определена для нескольких других типов.
- имплементация стандартной функции NANVL(NUMBER,NUMBER) не учитывает такой возможности, просто возвращает первый параметр.
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40004999
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я, кстати, не знал, что NUMBER позволяет хранить infinity. Только что поигрался с этим, обнаружил следующее:

В PL/SQL присутствует полная поддержка для десятичной бесконечности, кроме определения NUMBER_INFINITY.
Есть положительная и отрицательная бесконечности, определена функция "is infinite" для типа NUMBER, арифметика работает как ожидается, вычислительные функции тоже. Косинус от нее равен одному. Это говорит об отсутствии NaN/NUMBER, т.к. косинус от двоичной бесконечности это NaN.

В PL/SQL ее можно кастить в BINARY_FLOAT и обратно, все отрабатывается корректно. Преобразование в строку работает, хотя вместо 'Inf' оно печатает совсем другое.

В SQL с этой величиной печально, даже чтобы ее создать пришлось извернуться. SQL строго ловит арифметические переполнения и не разрешает касты от 1/0f. Когда получилось ее создать, все операции вылетают по ошибке, даже "is infinite" (иронично!).
SQL явно не любит эту величину, а вот с бинарными бесконечностями работает нормально.

А как вы столкнулись с десятичной бесконечностью в таблице? Пришла через импорт?
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40005007
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Неофит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:

  • Positive numbers in the range 1 x 10-130 to 9.99...9 x 10125 with up to 38 significant digits
  • Negative numbers from -1 x 10-130 to 9.99...99 x 10125 with up to 38 significant digits
  • Zero
  • Positive and negative infinity (generated only by importing from an Oracle Database, Version 5)
11.2 официальная поддержка исчезла, но в Format models по-прежнему осторожно сказано про ~ и -~:
автор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 (-~).
...
Рейтинг: 0 / 0
Запретить передачу null параметра в PL/SQL procedure
    #40005009
Bfink
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Бесконечность получить просто, в колонку NUMBER нужно инсертить 1/0b или -1/0b для отрицательной бесконечности.
А вот NaN так вставить не удалось. Зато OCI это делает легко - вставляешь строку в числовой параметр и в таблице очень плохое значение. Оно почему то больше нуля и его можно выделить на равенство. Особенно прикольно делать по этой колонке группировку.
...
Рейтинг: 0 / 0
25 сообщений из 114, страница 4 из 5
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Запретить передачу null параметра в PL/SQL procedure
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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