powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как бы вы написали такую функцию?
25 сообщений из 29, страница 1 из 2
Как бы вы написали такую функцию?
    #40063405
romaro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне нужно генерировать случайную строку и на всякий случай проверять, нет ли уже такого значения в таблице. Реализовал при помощи потенциально бесконечного цикла, но может есть более изящный и безопасный вариант?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function public_code
--------------------------------------
return varchar2
is
	l_code_length	number	:=10;
	l_public_code	varchar2(10);
	l_count		number	:=null;
begin
	loop
		exit when l_count = 0;
		--Генерируем случайную строку
		l_public_code := DBMS_RANDOM.string (
		opt => 'a',
		len => l_code_length
		);

		--Проверяем, есть ли такое значение
		select count(*) into l_count from subject where public_code = l_public_code;
	end loop;
	
	return l_public_code;
end;
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063410
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
romaro
Мне нужно генерировать случайную строку и на всякий случай проверять, нет ли уже такого значения в таблице. Реализовал при помощи потенциально бесконечного цикла, но может есть более изящный и безопасный вариант?


Код: 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.
function public_code
--------------------------------------
return varchar2
is
	l_code_length	number	:=10;
	l_public_code	varchar2(10);
begin
	loop
		--Генерируем случайную строку
		l_public_code := DBMS_RANDOM.string (
		opt => 'a',
		len => l_code_length
		);

		--Не только "Проверяем, есть ли такое значение", но и сохраняем новое, чтобы последующие вызовы функции его уже не повторили
                insert into subject(public_code) -- что с другими полями таблицы, это Вам виднее
                  select l_public_code from dual
                    where not exists (select null from subject where public_code = l_public_code);

                exit when sql%rowcount = 1;
	end loop;
	
	return l_public_code;
end;
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063424
Фотография Vadim Lejnin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
romaro,

А чем не устраивает guid?
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063432
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
romaro
может есть более изящный
exit не в том месте. А это как бы намекает, что с алгоритмизацией не всё хорошо в голове. Т.е. эти проблемы не последние.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063442
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vadim Lejnin
А чем не устраивает guid?

Присоединяюсь к вопросу.
Кроме того, если на самом деле требуется не случайное число, а идентификатор, то как-то в RuOUG представляли в качестве генератора systimestamp
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063452
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Vadim LejninА чем не устраивает guid?

Присоединяюсь к вопросу.А я нет. Использование guid - это роспись в неспособности постичь предметную область.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063454
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic
andrey_anonymous
пропущено...

Присоединяюсь к вопросу.
А я нет. Использование guid - это роспись в неспособности постичь предметную область.


Если рассматривать это не как абстрактный вопрос "Как бы вы написали такую функцию", то применительно к любой предметной области его бы просто не было - генерировать ключ, необходимый для бизнес-логики: systimestamp, guid, если нет ничего более адекватного - это уже частности.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063458
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASNexus
systimestamp, guid, если нет ничего более адекватного - это уже частности.
Возражаю. guid естественно и отвратительно несортирабелен. А дьявол - в деталях.

Вообще предложение какой-то хрени, не понимая задачи, как минимум непрофессионально.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063463
ASNexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Elic
ASNexus
systimestamp, guid, если нет ничего более адекватного - это уже частности.
Возражаю. guid естественно и отвратительно несортирабелен. А дьявол - в деталях.

Вообще предложение какой-то хрени, не понимая задачи, как минимум непрофессионально.

Согласен - мой вариант был просто ответом на "может есть более изящный и безопасный вариант".
Просто чтобы натолкнуть автора на некоторые мысли.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063468
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если это динамические PIN-коды (и их возможное количество невелико), то лучше всего сразу сгенерировать все возможные (допустимые) значения, а для выдачи/активации использовать поле "Статус".

Если нужен рандомный пароль (количество возможных значений очень велико), то просто генерировать и проверять на отсутствие коллизий. Соль или префикс позволят снизить вероятность коллизий.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063786
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
Если это динамические PIN-коды (и их возможное количество невелико), то лучше всего сразу сгенерировать все возможные (допустимые) значения, а для выдачи/активации использовать поле "Статус".

Если нужен рандомный пароль (количество возможных значений очень велико), то просто генерировать и проверять на отсутствие коллизий. Соль или префикс позволят снизить вероятность коллизий.

я в похожих задачах (в скриптах для тестов) просто зашивал в строку timestamp и session_id. и можно не проверять на уникальность
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063813
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
legg
и можно не проверять на уникальность

Не совсем верно.
Проблемы с уникальностью в таком подходе словить можно на хорошем оборудовании.
Более того, на практике ловят.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063828
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И они гарантированно всплывут при использовании нескольких серверов.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063830
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
legg
и можно не проверять на уникальность

Не совсем верно.
Проблемы с уникальностью в таком подходе словить можно на хорошем оборудовании.
Более того, на практике ловят.

в одну миллионную секунды в одной сессии успевают два вызова влезть? круто. но это если совсем никакой логики нет и просто подряд генерим строки. ну тогда добавить пакетную переменную и инкрементировать ее.

сиквенсы и гуиды, как я понимаю, мы не используем.
в любом случае в такой задаче я попытался б избавиться от проверки уникальности - обеспечил бы на этапе генерации.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063836
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
И они гарантированно всплывут при использовании нескольких серверов.

это когда несколько инстансов на одной базе? легко исправляется добавлением в строку идентификатора сервера.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063838
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, когда разные сервера (физические или виртуальные) с не идеально синхронизированными часами.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063840
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
legg
в одну миллионную секунды в одной сессии успевают два вызова влезть?

Откуда взялась одна миллионная секунды?
Не нужно путать разрядность типа данных и разрешающую способность системного таймера.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063841
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
Не нужно путать разрядность типа данных и разрешающую способность системного таймера.

...глас разума однако.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40063863
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
legg
в одну миллионную секунды в одной сессии успевают два вызова влезть?
а откуда брать timestamp будешь? Если systimestamp то он как и sysdate вообще внутри одного запроса не меняется - две строчки уже не вставишь:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
with function pause(n number) return timestamp as begin dbms_session.sleep(n); return systimestamp; end;
select systimestamp, pause(3) "systimestamp_from_plsql" from dual
union all
select systimestamp, pause(3) "systimestamp_from_plsql" from dual
union all
select systimestamp, pause(3) "systimestamp_from_plsql" from dual;

SYSTIMESTAMP                                                                systimestamp_from_plsql
--------------------------------------------------------------------------- ---------------------------------------
2021-04-19 11:12:03.799658 +00:00                                           2021-04-19 11:12:06.798881000
2021-04-19 11:12:03.799658 +00:00                                           2021-04-19 11:12:09.849911000
2021-04-19 11:12:03.799658 +00:00                                           2021-04-19 11:12:12.849886000
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40064093
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov
а откуда брать timestamp будешь? Если systimestamp то он как и sysdate вообще внутри одного запроса не меняется - две строчки уже не вставишь:

||rownum :)
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40064094
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous
Alibek B.
Не нужно путать разрядность типа данных и разрешающую способность системного таймера.

...глас разума однако.

хм.. я ни в коем случае не спорю - полный профан в этой области, но разве разрешающая способность сист ямных таймеров в наше время не в наносекундах измеряется?
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40064095
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.
Нет, когда разные сервера (физические или виртуальные) с не идеально синхронизированными часами.


я systimestamp имел в виду. он же единственный и неповторимый?
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40064097
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
legg
разве разрешающая способность сист ямных таймеров в наше время не в наносекундах измеряется?

Нет, конечно.

legg
я systimestamp имел в виду. он же единственный и неповторимый?

Ничего не понял.
Кто единственный и неповторимый?
Если на одном сервере часы отстают на секунду от второго сервера, то и systimestamp на нем через секунду повторит значение со второго сервера.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40064100
legg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.

Ничего не понял.
Кто единственный и неповторимый?
Если на одном сервере часы отстают на секунду от второго сервера, то и systimestamp на нем через секунду повторит значение со второго сервера.

Это я ничего не понял, потому что не имел дела с подобным).
По поводу разных серверов - у них ведь есть какой-то уникальный идентификатор? если нет - сделать и запихнуть в контекст или пакетную переменную и конкатенировать к строке.
По поводу времени - то , если интенсивность генерации новых строк в самом деле создает риски генерации в один и тот же таймсемп двух строк - таким же образом можно запоминать предыдущее время с текущим и если оно совпадает - добавлять постфикс-счетчик. В любом случае уверен что можно выкрутиться и обеспечить уникальность не дергая каждый раз таблицу. Конечно, если данные в таблицу попадают только через нашу генерилку, нет другого источника данных.
...
Рейтинг: 0 / 0
Как бы вы написали такую функцию?
    #40064105
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
legg
таким же образом можно запоминать предыдущее время с текущим и если оно совпадает - добавлять постфикс-счетчик

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


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