powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Эмуляция условного выражение
18 сообщений из 18, страница 1 из 1
Эмуляция условного выражение
    #34854230
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно сэмулировать условное выражение
Код: plaintext
condition ? if_condition_true_value : if_condition_false_value
есть ли у кого-нибудь опыт в этом деле? Может быть, как-нибудь хитро использовать пользовательские операторы?
Пример.
Надо чтобы в переменную _var записалось значение 'yes'
Код: plaintext
EXECUTE 'SELECT 4 > 3 ? ''yes'' : ''no''' INTO _var;
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854271
Фотография Zashibis
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Через CASE вроде можно
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854289
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RTFM:
автор
Код: plaintext
9.13. Conditional Expressions

в частности -
автор
Код: plaintext
1.
2.
3.
CASE WHEN condition THEN result
     [WHEN ...]
     [ELSE result]
END
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854300
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Слово эмуляция немного неточно употребил, каюсь
Мне нужно, чтобы выполнилось след. выражение
Код: plaintext
EXECUTE 'SELECT 4 > 3 ? ''yes'' : ''no''' INTO _var;
можно ли с помощью стандартных возможностей этого добиться?

Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854384
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dan BlackСлово эмуляция немного неточно употребил, каюсь
Мне нужно, чтобы выполнилось след. выражение
Код: plaintext
EXECUTE 'SELECT 4 > 3 ? ''yes'' : ''no''' INTO _var;
можно ли с помощью стандартных возможностей этого добиться?

Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
вас затрудняет вписать конструкцию CASE внутрь формируемого стринга?


печальны дела твои, оспидя
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854395
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, учитывая, что конструкция мне даётся извне в вышеприведенном виде.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854408
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не поленюсь, проделаю чисто механическое:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
EXECUTE 'SELECT 4 > 3 ? ''yes'' : ''no''' INTO _var;
+
CASE WHEN condition THEN result
     [WHEN ...]
     [ELSE result]END
=

EXECUTE 'SELECT 
CASE WHEN  4 > 3
 THEN  \'yes\'
 ELSE \'no\'
 END' INTO _var;

и что у вас вызвало затруднения???
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854437
Фотография Ёш
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dan Blackда, учитывая, что конструкция мне даётся извне в вышеприведенном виде.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 


Код: plaintext
execute replace(replace(replace('SELECT 4 > 3 ? ''yes'' : ''no''', 'SELECT ', 'CASE WHEN '), ' ? ', ' THEN '), ' : ', ' ELSE ') || ' END' into _var;
:)
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854450
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dan Blackда, учитывая, что конструкция мне даётся извне в вышеприведенном виде.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
т.е. на вход вы получаете заведомо сформированное выражение вида
'select xxxxxxxxxx ? yyyyyyyy : zzzzz'
и хотите его "выполнить"?
так распарсьте внутре некой ф-ии - найдите , что у вас xxxxxxxx, а что уууууууууууу, и zzzzzzz. в простых случаях можно конечно цепляться к фрагментам "'select ", " ? " и " : " (и попросту механически всовывать тудыть " CASE WHEN ", " THEN " и " ELSE " реплейсом, а в конец автоматом END) но в сложных (если условия могут быть вложены) - надо, имхо, аккуратную рекурсивную парсилку писать (с учетом всего возможного входного синтаксиса "выражений").
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854452
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть много логических выражений
Код: plaintext
Условие ? результат1 : результат2
надо вычислить их значение. При этом условия могут быть сложными: содержать скобки, другие условия внутри себя. То есть отпарсить всё это нелегко. Все операции сравнения постгресс поддерживает, кроме ?: . Поэтому возник вопрос, можно ли эту конструкцию привести к виду, понимаемому постгресом.
Были бы там конструкции с двумя параметрами, не парился, создал бы нужные операторы и всё заработало бы, а тут нужен оператор, который понимает три параметры, или какая-нибудь другая фишка, о которой я не знаю.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854468
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321надо, имхо, аккуратную рекурсивную парсилку писать (с учетом всего возможного входного синтаксиса "выражений").
нет ни желания, ни времени писать парсилку из-за одного "неподдерживаемого" условного выражения.
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854469
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ёш
имхо - SELECT потеряли
Код: plaintext
1.
2.
3.
4.
5.
execute replace(
replace(
replace('SELECT 4 > 3 ? ''yes'' : ''no''', 'SELECT ', 'SELECT CASE WHEN ')
, ' ? ', ' THEN ')
, ' : ', ' ELSE ')
 || ' END;' into _var;



но опять таки - если нет вложенных конструкций
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854481
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вложенные конструкции есть есть и им нет числа ;)
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854538
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dan Black 4321надо, имхо, аккуратную рекурсивную парсилку писать (с учетом всего возможного входного синтаксиса "выражений").
нет ни желания, ни времени писать парсилку из-за одного "неподдерживаемого" условного выражения.нет - не пишите.
никто ж не заставляет.

а если приведете конкретный синтаксис вложений ваших условностей и т.п. - можно покумекать, как выйти малой кровью.


С другой - все тройные операторы сводимы к двойным (если хорошо покумекать): у вас в реале :
(буленов результат) ?(оператор1) выражение1 : (оператор2) выражение2
т.е:
(операнд1 оператор1 операнд2) оператор2 операнд3
если оператор1 при фалсе в операнд1 вернет специяльную (выколотую из всех возможных значений для операнд2) величинку, а оператор3 увидев такую величинку во входящем значении вернет операнд3 без разговоров - вы сведете задачу к операторам от 2-х величин. правда - некомутативным операторам, а как все там у вас обставлено в синтаксисе скобочками - надо еще подумать.
в качестве ведичинки предлагаю "НеХренаЖСебеВеличинка"
но трудность в том, что боюсь и ? и : - могут оказаться уже занятыми операторами
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854566
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, и выкалывать не надо. надо (для "?") в случае фалсе возвращать значение заведомо другого типа (специально его можно даже ввести в перечень типов), а для ":" писать два оператора - для разных входных пар типов.
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34854726
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321кстати, и выкалывать не надо. надо (для "?") в случае фалсе возвращать значение заведомо другого типа (специально его можно даже ввести в перечень типов), а для ":" писать два оператора - для разных входных пар типов.
Хороший вариант, даже рабочий. Спасибо
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34856179
4321
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dan BlackХороший вариант, даже рабочий. Спасибогм. исчо вчера подумал, что вариант нерабочий. кажется в постгре из одной ф-ии (типизированных переменных) трудно вернуть разнотипные результаты. разве что определив тип возврата record.

с другой была такая идея: 2 (и более) операнда могут рассматриваться и как один комплексный операнд (вектор, или сложный). т.ч. можно либо составить компаунды вида (булен, число), либо (число,число) - в зависимости от порядка действия операторов. (можно ли и как им рулить в постгре - крайне неясно).

для примера проверим в каком порядке выполняются сравнения:
Код: plaintext
1.
2.
3.
--SELECT 1=2=(1=1);
SELECT ( 1 = 2 )= 1 = 1 ;
--SELECT ((1=2)=1)=1
--SELECT  1 = 2 = 1 = 1 ;
видим, что постгре выполняет сравнения от хвоста к началу (если нет скобок).

посему я попробовал сделать так:

Код: plaintext
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.
CREATE TYPE v_numeric AS
   (x numeric,
    y numeric);

CREATE OR REPLACE FUNCTION vector_num(numeric, numeric)
  RETURNS v_numeric AS
$BODY$
SELECT ($ 1  , $ 2 )::v_numeric
;
 $BODY$
  LANGUAGE 'sql' IMMUTABLE;

CREATE OPERATOR ` (
  PROCEDURE = vector_num,
  LEFTARG = numeric,
  RIGHTARG = numeric);

CREATE OR REPLACE FUNCTION w_num(bool, v_numeric)
  RETURNS numeric AS
$BODY$
SELECT CASE WHEN $ 1 
	THEN $ 2 .x
ELSE 
$ 2 .y
END
;
 $BODY$
  LANGUAGE 'sql' IMMUTABLE;

CREATE OPERATOR ? (
  PROCEDURE = w_num,
  LEFTARG = bool,
  RIGHTARG = v_numeric);
-так еще и однородные члены сгруппированы более "интуитивно",
но, к сожалению, ошибся в рассчетах:
Код: plaintext
1.
--SELECT true ? 1`2; - ошибка в порядке выполнения
SELECT true ? ( 1 ` 2 );-- работает только так
(` вместо : пришлось выбрать из-за ограничения постгре на имена операторов)

далее, даже переписав через компаундный вид (bool, numeric) сразу предвидим проблемы с заданием (навязыванием) порядка выполнения в сложных выражениях вида
a=b ? c+d : e*f
, т.е. таких, где скобками не выделяются операнды целиком. можно утверждать, что замена "?" на ")?(" и : на "):(" - была бы безусловно верна, если только правильно поставить и начальную скобку (перед а в данном случае) и конечную (после f), но вот тут-то и, кажется, засада (для сложно-сочиненных выражений). какую-то парсилку придется писать даже и тут. (проблема, кстати, была бы и для некомпаундных типов промежуточных возвратов - она таки в синтаксическом разборе порядка действия)


если таки что придумаете - черканите хотя б идейку - интересно.
...
Рейтинг: 0 / 0
Эмуляция условного выражение
    #34857780
Dan Black
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
4321[если таки что придумаете - черканите хотя б идейку - интересно.
Так как работа разовая, то посчитали, что экономически более целесообразно посадить 10 операторов, которые за день набьют данные в базу, чем иметь секс с разбором подобных выражений или ломать голову, как эту задачу лучше решить
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Эмуляция условного выражение
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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