Это мой первый пост здесь, не говоря уже о том, что я не захожу сюда по большинству своих вопросов! К сожалению, я не смог найти существующий ответ на этот вопрос!

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

Ожидаемые результаты

ValidAccount = TRUE или FALSE errorMsg = NULL или определенная ошибка, основанная на том, какие условия WHERE не были выполнены

Это мой существующий оператор, и я смог определить сообщение об ошибке для каждого отдельного предложения WHERE, если оно не выполнено, но я хотел бы иметь возможность перебирать весь оператор и определять, есть ли более одного «сбоя». ". Является ли это возможным? Я хотел бы указать на некоторые рекомендации о том, как этого добиться! А также было бы интересно узнать, есть ли лучший способ добиться того, что у меня уже есть ниже - это работает, но не очень элегантно!

SELECT CASE WHEN EXISTS (
    SELECT *
    FROM customer_database_dummy
    WHERE 
    
    account_reference =  {accNumber}
    and replace(replace(name,' ',''),'.','') = replace(replace({Rent_Full_Name},' ',''),'.','')
    and period_start_date = {DateOfBirth_f}
    and replace(postcode,' ','') =  replace({PostcodeUpper},' ','') 
    and property_code not in ('Shed','Garage','Parking Space')
    and (tenancy_end_date > getdate() or tenancy_end_date is null)

)
--VALID RESULT
THEN  'TRUE'

--INVALID RESULT HANDLING
ELSE   'FALSE'  END as validAccount,

--ACC_NOT_FOUND
CASE WHEN NOT EXISTS (
    SELECT *
    FROM rent_account_customer_summary
    WHERE 
    
    account_reference = {accNumber})
THEN 'ACC_NOT_FOUND'

--NAME_MISMATCH
WHEN EXISTS (
    SELECT *
    FROM rent_account_customer_summary
    WHERE 
    
    account_reference =  {accNumber}
    and replace(replace(name,' ',''),'.','') != replace(replace({Rent_Full_Name},' ',''),'.',''))
THEN  'NAME_MISMATCH' 

--DOB_MISMATCH
WHEN EXISTS (
    SELECT *
    FROM rent_account_customer_summary
    WHERE 
    
    account_reference =  {accNumber}
    and period_start_date != {DateOfBirth_f})
THEN 'DOB_MIMSMATCH'

--POSTCODE_MISMATCH#
WHEN EXISTS (
    SELECT *
    FROM rent_account_customer_summary
    WHERE 
    
    account_reference =  {accNumber}
    and replace(postcode,' ','') !=  replace({PostcodeUpper},' ',''))
THEN 'POSTCODE_MISMATCH'

--PROPERTY_TYPE_INVALID
WHEN EXISTS (
    SELECT *
    FROM rent_account_customer_summary
    WHERE 
    
    account_reference =  {accNumber}
    and property_code in ('Shed','Garage','Parking Space'))
THEN 'PROPERTY_TYPE_INVALID'
    
--TENANCY_ISSUE
WHEN EXISTS (
    SELECT *
    FROM rent_account_customer_summary
    WHERE 
    
    account_reference =  {accNumber}
    and (tenancy_end_date < getdate() or tenancy_end_date != null))
THEN 'TENANCY_ISSUE'


ELSE   ''  END as errorMsg

0
rich 26 Янв 2022 в 15:59
Привет, добро пожаловать в СО! :-) Какую базу данных вы используете? МС SQL сервер?
 – 
Fabian Pijcke
26 Янв 2022 в 16:05
Спасибо! да - но через сторонний веб-интерфейс - это немного странно, и некоторые вещи просто не работают, но мы справляемся! :D
 – 
rich
26 Янв 2022 в 18:44

2 ответа

Лучший ответ

Предполагая, что вы используете MS SQL Server, вот возможное решение, которое, я надеюсь, вы найдете чище :-)

SELECT IIF(errorMsg = '', 'TRUE', 'FALSE') AS validAccount, errorMsg
FROM (SELECT {accNumber} AS accNumber) accNumberTable
LEFT JOIN rent_account_customer_summary ON account_reference = accNumber
CROSS APPLY (
  SELECT COALESCE(
    IIF(account_reference IS NOT NULL, NULL, 'ACC_NOT_FOUND'),
    IIF(replace(replace(name,' ',''),'.','') = replace(replace({Rent_Full_Name},' ',''),'.',''), NULL, 'NAME_MISMATCH'),
    IIF(period_start_date = {DateOfBirth_f}, NULL, 'DOB_MISMATCH'),
    IIF(replace(postcode,' ','') =  replace({PostcodeUpper},' ',''), NULL, 'POSTCODE_MISMATCH'),
    IIF(property_code not in ('Shed','Garage','Parking Space'), NULL, 'PROPERTY_TYPE_INVALID'),
    IIF(tenancy_end_date >= getdate() or tenancy_end_date = null, NULL, 'TENANCY_ISSUE'),
    ''
  ) AS errorMsg
) t

Идея состоит в том, чтобы проверить, есть ли сообщение об ошибке для искомого номера счета. Мы сохраняем эту ошибку в «боковой таблице» (терминология из PostgreSQL) и используем это сообщение об ошибке, чтобы определить, действительна ли учетная запись, а затем возвращаем само сообщение об ошибке.

0
Dharman 26 Янв 2022 в 16:37
Удивительно спасибо! Я выбрал это как «правильный» ответ, так как в нем было меньше кода и это позволило мне получить все сообщения об ошибках, которые были помечены (я просто изменил COALESCE на CONCAT.
 – 
rich
26 Янв 2022 в 18:41

Вам просто нужно включить все условия, которые вы используете, в поля выбора с оператором IIF.

У вас будет результат со всеми вашими полями в вашем выборе плюс флаг, указывающий, какие условия прошли или не прошли, например:

'all other fields names'  | valid_account | valid_name | ...etc
'all other record values' |      1        |      0     | ...etc

Пример кода

SELECT *,
    IIF (account_reference =  {accNumber}, 1, 0) AS valid_account,
    IIF (replace(replace(name,' ',''),'.','') = replace(replace({Rent_Full_Name},' ',''),'.',''), 1, 0) AS valid_name,
    IIF (period_start_date = {DateOfBirth_f}, 1, 0) AS valid_start_date,
    IIF (replace(postcode,' ','') =  replace({PostcodeUpper},' ',''), 1, 0) AS valid_post_code,
    IIF (property_code not in ('Shed','Garage','Parking Space'), 1, 0) AS valid_property_code,
    IIF ((tenancy_end_date > getdate() or tenancy_end_date is null), 1, 0) AS valid_tenancy_date
    FROM customer_database_dummy
    WHERE 
    account_reference =  {accNumber}
    and replace(replace(name,' ',''),'.','') = replace(replace({Rent_Full_Name},' ',''),'.','')
    and period_start_date = {DateOfBirth_f}
    and replace(postcode,' ','') =  replace({PostcodeUpper},' ','') 
    and property_code not in ('Shed','Garage','Parking Space')
    and (tenancy_end_date > getdate() or tenancy_end_date is null)
0
Ariel Perez 26 Янв 2022 в 16:57