Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Mih_dim Member Откуда: Сообщений: 145 |
Здравствуйте! Есть таблица, хранящая формулу расчета в виде текста. Эта формула зависит от неких параметров, которых может быть произвольное количество. Например вычисление формулы (сам текст формулы это текст между select и from): select CASE WHEN [Par1]=1 THEN CASE WHEN ( [Par2] > 0 ) OR ([Par3] >0) THEN [Par4] else [Par1] END + CASE WHEN [Par4]=1 THEN [Par2] else [Par1]+10 END else 30 END from (select 1 Par1, 2 Par2, 3 Par3, 4 Par4, 5 Par5) T Сам запрос сильно упрощен для понимания. Вопрос: Нужно узнать по какой ветке формулы пошло вычисление и ее выделить жирным, как показано ниже. Т.е в SQL мне нужно определить что выделять. CASE WHEN [Par1]=1 THEN CASE WHEN ( [Par2] > 0 ) OR ([Par3] >0) THEN [Par4] else [Par1] END + CASE WHEN [Par4]=1 THEN [Par2] else [Par1]+10 END else 30 END Примечание: в формуле могут использоваться только выражение case when then else end и логические и арифметические операции+ скобки. Все параметры всегда в квадратных скобках. Набор параметров для одной формулы всегда одинаков, но значения разные. И формул разных таких у меня более 1000 штук. Подскажите как правильно "распарсить" формулу и найти "листья" дерева формулы? |
21 мар 13, 11:15 [14076117] Ответить | Цитировать Сообщить модератору |
Maxx Member [скрыт] Откуда: Сообщений: 24290 |
У вас есть таблица в полях которой записан текст запроса ? Правильно ? У вас есть некая ХП которая принимает в себя параметры и рожает динамический скл относительно парметров ? Вы хотите понять куда оно попадет ? И в конце концов ГДЕ НАДО ВЫДЕЛИТЬ текст ? |
21 мар 13, 11:28 [14076216] Ответить | Цитировать Сообщить модератору |
Mind Member Откуда: Лучший город на Земле Сообщений: 2322 |
CASE (Transact-SQL) How do I write a Parser in C#? Parsing |
||
22 мар 13, 00:37 [14079747] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Извините что не отвечал - уезжал и инета не было. У меня есть таблица где в определенном поле записаны тексты запросов. в каждой строке свой. У вас есть некая ХП которая принимает в себя параметры и рожает динамический скл относительно парметров ? Да Вы хотите понять куда оно попадет ? Да Надо знать в какую ветку запроса зайдет при тех или иных значениях входных параметров в этот набор кейсов. А выделение ветки по которой прошло вычисление - это уже вторая задача и при решении первой уже не очень сложная. Главное понять какие именно выражения в запросе дали такой результат. |
||
25 мар 13, 12:05 [14091382] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Информацию об этом я и так знаю, тока мне нужно "распарсить" чисто в T-SQL. Я пытался написать, но что то очень уж сложно у меня выходит и все время находятся выражения которые не верно парсяться. Может кто то уже "парсил" что нить подобное и есть более изящные решения??? Очень надо. |
||||
25 мар 13, 12:10 [14091409] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Информацию об этом я и так знаю, тока мне нужно "распарсить" чисто в T-SQL. Я пытался написать, но что то очень уж сложно у меня выходит и все время находятся выражения которые не верно парсяться. Может кто то уже "парсил" что нить подобное и есть более изящные решения??? Очень надо. |
||||
25 мар 13, 12:13 [14091421] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Парсер работает с текстом. Парсер не может знать значений полей. Потому что значения эти будут известны только в момент выполнения. |
||
25 мар 13, 12:18 [14091458] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Парсер T-SQL, написанный на T-SQL? Знатное извращение ![]() Более изящное решение — парсить T-SQL не на T-SQL. |
||
25 мар 13, 12:36 [14091592] Ответить | Цитировать Сообщить модератору |
Mind Member Откуда: Лучший город на Земле Сообщений: 2322 |
![]() Mih_dim, Для каждой задачи свой инструмент. Если уж очень надо - напишите CLR. |
||||
26 мар 13, 03:59 [14094944] Ответить | Цитировать Сообщить модератору |
на самом деле не очень понял зад
Guest |
Mih_dim, как вариант можно все что после THEN и ELSE заменять на время поиска пути на последовательно наращиваемую битовую маску и типо в какую-нибуь переменную (-ные) складывать. в конце получится общая или на каждый кейс своя битовая маска. не получится если более ранний кейс меняет значения которые должны влиять на более поздний. |
26 мар 13, 07:55 [14095036] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Хм... а каким образом case может поменять какое-либо значение? Значения ведь меняются оператором присваивания? |
||
26 мар 13, 11:35 [14095838] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Я знаю только T-sql. И на другом написать не могу. Просто тупо перебором символов в цикле с проверкой последовательности их - этот вариант мне не нравиться и хотел спросить есть ли более изящный вариант (не в "лоб"). |
||||
27 мар 13, 10:08 [14100161] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9633 |
Mih_dim, Купите готовый. Предложений достаточно. |
27 мар 13, 10:47 [14100392] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Жирным выделить написал - это для понимания задачи. Если не знаете как решить на T-SQL, так не пишите. Я это так вижу: мне нужна хранимка в которую я буду передавать строку (формулу), а она мне будет возвращать таблицу. Пример: Строка: case when 1=2 then 2 else case when 1=1 then 3 else 4 end + 45 end Возвращается таблица:
Где flag=1 показывает, по каким "листьям" прошел расчет. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
27 мар 13, 10:49 [14100408] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Алгоритмов парсинга полно. Вы хоть один нашли ? Или вы ищите готовый код на T-SQL ? |
||
27 мар 13, 10:53 [14100433] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Готовый на T-sql в виде хранимки? Вряд ли, а мне нужен именно такой. |
||
27 мар 13, 11:03 [14100511] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Их много а какой применить к моей задачи не знаю. Я ищю хотя бы подобный код чтобы его доработать или метод с помощью которого я бы написал сам. 1. Если есть уже подобное решение, то я бы посмотрел бы на него 2. Если нет, то подскажите какой лучше использовать алгоритм 3. Если не понятно какой лучше, то подскажите хотя бы какой проще для понимания. |
||||
27 мар 13, 11:07 [14100525] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
1) Создаёте формальное описание грамматики подмножества языка T-SQL, которое используется в ваших выражениях. Это будет контекстно-свободная грамматика, более конкретно надо смотреть в процессе создания; 2) Пишете лексический анализатор, разбивающий исходный текст на литералы, используемые в грамматике; 3) Пишете синтаксический анализатор, строящий по набору литералов дерево разбора в соответствии с описанием грамматики; 4) Пишете семантический анализатор, который собственно уже сможет определить ветви дерева разбора, по которому пройдёт вычисление с указанными параметрами. |
||
27 мар 13, 11:07 [14100526] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Вы предлагаете выбрать за вас ?
То, что вы написали, есть обыкновенное разбиение строки на подстроки с разделителем пробел |
||||
27 мар 13, 11:10 [14100544] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Наверное, метод рекурсивного спуска. Хотя перспектива его реализации на T-SQL не очень ясна (из-за ограничения MSSQL — не более 32 вложенных вызовов хранимых процедур). Вот нашлась некая статья на Хабре с исходниками на Java (сперва я даже был в полной уверенности, что это C#): Парсер формул с помощью метода рекурсивного спуска. |
||
27 мар 13, 11:33 [14100694] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Да заполнение таблицы это не сложно, а вот проставление флага? Вот задача. |
||||||
27 мар 13, 13:52 [14101689] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Спасибо я посмотрю этот метод. |
||||
27 мар 13, 13:53 [14101696] Ответить | Цитировать Сообщить модератору |
Glory Member Откуда: Сообщений: 104760 |
Разумеется. Для этого как указали в сообщении 14100526 нужно определять лексику, семантику, синтаксис. Грубо говоря, правила отличия подстроки "case" от подстроки "1=1" |
||
27 мар 13, 13:56 [14101711] Ответить | Цитировать Сообщить модератору |
Mih_dim Member Откуда: Сообщений: 145 |
Можно ссылку на любой пример этих 4 пунктов, а то в теории это слишком размыто. Лично я не могу в своей задаче разделить на эти 4 пункта? |
||||
27 мар 13, 15:14 [14102286] Ответить | Цитировать Сообщить модератору |
Гость333 Member Откуда: Сообщений: 3683 |
Mih_dim, Например, на http://kit.kulichki.net/ есть "методические материалы по курсу "Основы построения трансляторов". |
27 мар 13, 16:06 [14102758] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |