Хочу получить строку, оцененную во второй раз, чтобы я мог изменить одно правило для независимых запросов

Я хочу, чтобы работал следующий запрос, где [Tryme] — это записанное правило, которое будет истинным или ложным, чтобы я мог проверить таблицу показателей контроля качества и получить таблицу всех, в данном случае, Employee и проверить пары, которые нарушают мой правила.

SELECT 
    Temp.*, FunctionIWant([Temp.TryMe]) AS Checked
FROM 
    (SELECT 
         Employee.ID, Employee.[First Name], Employee.[Last Name], 
         Employee.Wage, Employee.Tenure, 
         TheseRules.ID, TheseRules.Check AS Tryme
     FROM 
         Employee, TheRules AS TheseRules) AS Temp;

Ниже приведен оператор, который возвращает [Checked], возвращая логическое значение так, как я хочу. Текст, записанный для столбца Checked, — это точный текст, который находится в Temp.Tryme (чтобы быть более понятным, "1.05*[Tenure]+37>[Wage]" — это строка).

SELECT 
    Temp.*, **1.05*[Tenure]+37>[Wage]** AS Checked
FROM 
    (SELECT 
         Employee.ID, Employee.[First Name], Employee.[Last Name], Employee.Wage, 
         Employee.Tenure, TheseRules.ID, TheseRules.Check AS Tryme
     FROM 
         Employee, TheRules AS TheseRules) AS Temp;

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

Я пробовал Eval(), который возвращает либо саму строку, либо #Error.

В настоящее время я пытаюсь создать функцию, которая бы это сделала, но не могу понять, как просто передать все поля функции, чтобы они могли быть оценены там.

Сколько «правил» вам нужно оценить? Сколько полей будет задействовано?

June7 08.07.2024 00:45

Сейчас в нем 39 правил, но если бы это сработало, я бы увеличил это число, чтобы упростить задачу. Всего задействовано около 25 различных полей.

Mike Sinclair 08.07.2024 01:36

Поля берутся из разных таблиц, а выражения содержат разное количество полей? Да, это становится сложнее.

June7 08.07.2024 01:58
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
3
102
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы функция Eval() работала, необходимо заменить строку [Tenure] значением поля Tenure (аналогично для Wage). Возможно, можно создать функцию, которая будет получать значения полей (включая строку выражения, хранящуюся в поле «Проверка») и выполнять соответствующие операции замены для создания строки выражения, которую может обработать Eval(). Я ожидаю, что это будет довольно сложно в зависимости от разнообразия оцениваемых «правил».

Функция может получать в качестве аргументов: имя таблицы данных, идентификатор записи, имя расчета, строку выражения. Откройте набор записей данной таблицы, отфильтрованный по идентификатору. Блок SELECT CASE будет определять имя вычисления и выполнять операции замены строки выражения, извлекая данные из полей набора записей.

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

В любом из этих подходов по мере добавления «правил» процедура должна быть расширена для их соответствия. Чтобы избежать этого и упростить процедуру, можно использовать таблицу «сопоставления», в которой указаны имена полей и связанные строки в выражении, которое они заменяют. Вместо SELECT CASE откройте набор записей таблицы «сопоставления» и зациклите ее записи для выполнения соответствующих операций замены строкового выражения, после чего Eval() сможет обработать строку.

Пример таблицы сопоставления:

ФлдНме ФлдМаск Таблица Срок владения Срок владения Сотрудники Заработная плата Заработная плата Сотрудники

Функция:

Function CheckCalc(intI As Integer, strT As String, strE As String) As Boolean
Dim rsData As DAO.Recordset, rsMap As DAO.Recordset
Set rsData = CurrentDb.OpenRecordset("SELECT * FROM [" & strT & "] WHERE ID = " & intI)
Set rsMap = CurrentDb.OpenRecordset("SELECT * FROM ExpMap WHERE TblNme ='" & strT & "'")
Do While Not rsMap.EOF
    strE = Replace(strE, rsMap!FldMask, rsData(rsMap!FldNme))
    rsMap.MoveNext
Loop
CheckCalc = Eval(strE)
End Function

Предполагается, что каждая таблица имеет ключевое поле с именем ID. Если это не так, функцию придется изменить, чтобы передать это имя поля в качестве другого аргумента и построить оператор SQL с этой переменной. Маска в выражении может быть какой угодно, просто убедитесь, что все, что есть в выражении, находится в таблице сопоставления, например символы [ ], которые я удалил из выражения во время тестирования и поэтому не отображается в таблице сопоставления.

Если в выражении в качестве маски используется точное имя поля, можно исключить таблицу сопоставления и ее набор записей. Вместо этого процедура будет перебирать поля rsData и проверять с помощью InStr() его присутствие в строке выражения, и если оно есть, выполнять операцию замены.

Function CheckCalc(intI As Integer, strT As String, strE As String) As Boolean
Dim rsData As DAO.Recordset, fld As DAO.Field
Set rsData = CurrentDb.OpenRecordset("SELECT * FROM [" & strT & "] WHERE ID = " & intI)
For Each fld In rsData.Fields
    If InStr(strE, fld.Name) Then
        strE = Replace(strE, fld.Name, fld)
    End If
Next
CheckCalc = Eval(strE)
End Function

Другие вопросы по теме