Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Эмуляция условного выражение / 18 сообщений из 18, страница 1 из 1
08.10.2007, 14:56
    #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
08.10.2007, 15:06
    #34854271
Zashibis
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
Через CASE вроде можно
...
Рейтинг: 0 / 0
08.10.2007, 15:09
    #34854289
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
RTFM:
автор
Код: plaintext
9.13. Conditional Expressions

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

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

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


печальны дела твои, оспидя
...
Рейтинг: 0 / 0
08.10.2007, 15:37
    #34854395
Dan Black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
да, учитывая, что конструкция мне даётся извне в вышеприведенном виде.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
08.10.2007, 15:40
    #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
08.10.2007, 15:47
    #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
08.10.2007, 15:50
    #34854450
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
Dan Blackда, учитывая, что конструкция мне даётся извне в вышеприведенном виде.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
т.е. на вход вы получаете заведомо сформированное выражение вида
'select xxxxxxxxxx ? yyyyyyyy : zzzzz'
и хотите его "выполнить"?
так распарсьте внутре некой ф-ии - найдите , что у вас xxxxxxxx, а что уууууууууууу, и zzzzzzz. в простых случаях можно конечно цепляться к фрагментам "'select ", " ? " и " : " (и попросту механически всовывать тудыть " CASE WHEN ", " THEN " и " ELSE " реплейсом, а в конец автоматом END) но в сложных (если условия могут быть вложены) - надо, имхо, аккуратную рекурсивную парсилку писать (с учетом всего возможного входного синтаксиса "выражений").
...
Рейтинг: 0 / 0
08.10.2007, 15:51
    #34854452
Dan Black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
Есть много логических выражений
Код: plaintext
Условие ? результат1 : результат2
надо вычислить их значение. При этом условия могут быть сложными: содержать скобки, другие условия внутри себя. То есть отпарсить всё это нелегко. Все операции сравнения постгресс поддерживает, кроме ?: . Поэтому возник вопрос, можно ли эту конструкцию привести к виду, понимаемому постгресом.
Были бы там конструкции с двумя параметрами, не парился, создал бы нужные операторы и всё заработало бы, а тут нужен оператор, который понимает три параметры, или какая-нибудь другая фишка, о которой я не знаю.
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
08.10.2007, 15:54
    #34854468
Dan Black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
4321надо, имхо, аккуратную рекурсивную парсилку писать (с учетом всего возможного входного синтаксиса "выражений").
нет ни желания, ни времени писать парсилку из-за одного "неподдерживаемого" условного выражения.
...
Рейтинг: 0 / 0
08.10.2007, 15:54
    #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
08.10.2007, 15:58
    #34854481
Dan Black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
вложенные конструкции есть есть и им нет числа ;)
Код: plaintext
1.
----------------------------
 Verba volent, scripta manent 
...
Рейтинг: 0 / 0
08.10.2007, 16:15
    #34854538
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
Dan Black 4321надо, имхо, аккуратную рекурсивную парсилку писать (с учетом всего возможного входного синтаксиса "выражений").
нет ни желания, ни времени писать парсилку из-за одного "неподдерживаемого" условного выражения.нет - не пишите.
никто ж не заставляет.

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


С другой - все тройные операторы сводимы к двойным (если хорошо покумекать): у вас в реале :
(буленов результат) ?(оператор1) выражение1 : (оператор2) выражение2
т.е:
(операнд1 оператор1 операнд2) оператор2 операнд3
если оператор1 при фалсе в операнд1 вернет специяльную (выколотую из всех возможных значений для операнд2) величинку, а оператор3 увидев такую величинку во входящем значении вернет операнд3 без разговоров - вы сведете задачу к операторам от 2-х величин. правда - некомутативным операторам, а как все там у вас обставлено в синтаксисе скобочками - надо еще подумать.
в качестве ведичинки предлагаю "НеХренаЖСебеВеличинка"
но трудность в том, что боюсь и ? и : - могут оказаться уже занятыми операторами
...
Рейтинг: 0 / 0
08.10.2007, 16:21
    #34854566
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
кстати, и выкалывать не надо. надо (для "?") в случае фалсе возвращать значение заведомо другого типа (специально его можно даже ввести в перечень типов), а для ":" писать два оператора - для разных входных пар типов.
...
Рейтинг: 0 / 0
08.10.2007, 17:02
    #34854726
Dan Black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
4321кстати, и выкалывать не надо. надо (для "?") в случае фалсе возвращать значение заведомо другого типа (специально его можно даже ввести в перечень типов), а для ":" писать два оператора - для разных входных пар типов.
Хороший вариант, даже рабочий. Спасибо
...
Рейтинг: 0 / 0
09.10.2007, 11:39
    #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
09.10.2007, 17:10
    #34857780
Dan Black
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Эмуляция условного выражение
4321[если таки что придумаете - черканите хотя б идейку - интересно.
Так как работа разовая, то посчитали, что экономически более целесообразно посадить 10 операторов, которые за день набьют данные в базу, чем иметь секс с разбором подобных выражений или ломать голову, как эту задачу лучше решить
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Эмуляция условного выражение / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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