#sql #ms-access
#sql #ms-access
Вопрос:
У меня есть приложение, которое находится в разработке уже несколько лет, поэтому мы знаем, что SQL, который оно генерирует, в целом допустим, и в этом случае импорт таблиц в SQL Server 2016 позволяет запускать там одни и те же запросы без проблем. Фактический запрос намного сложнее (намного больше уровней вложенности и подзапросов с несколькими соединениями), чем тот, который я публикую здесь, и он всегда выполняется, за исключением случая, который показан в этом сильно упрощенном примере. Этот простой запрос не выполняется даже в самом окне запроса MS Access.
SELECT *
FROM (SELECT individual_tests.*
,(SELECT TOP 1 test_categories.id FROM test_categories INNER JOIN performance_categories ON performance_categories.test_category_id = test_categories.id
WHERE performance_categories.id = individual_tests.performance_category_id) AS UsedInWhere
, (SELECT TOP 1 standard_designations.inactive_flag
FROM ((standard_designations
INNER JOIN standard_designation_revision_levels ON standard_designation_revision_levels.standard_designation_id = standard_designations.id)
INNER JOIN individual_tests_standard_rev_levels ON individual_tests_standard_rev_levels.standard_designation_revision_level_id = standard_designation_revision_levels.id)
INNER JOIN individual_tests ON individual_tests.id = individual_tests_standard_rev_levels.individual_test_id
) AS UnusedResultAnyway
FROM individual_tests_standard_rev_levels INNER JOIN
individual_tests
ON individual_tests.id = individual_tests_standard_rev_levels.individual_test_id
) AS individual_tests
WHERE (UsedInWhere = 1);
Существуют различные изменения, которые я могу внести в запрос, чтобы он выполнялся без ошибок, но они не соответствуют его цели.
Если я изменю WHERE внизу, чтобы не ссылаться на результаты любого подзапроса, он выполняется. Если я упрощу любой из подзапросов, чтобы быть
(1) AS UsedInWhere
или
(1) AS UnusedResultAnyway
все работает нормально. IOW, мне не нужно упрощать подзапрос, который вычисляет UsedInWhere, чтобы иметь возможность использовать это значение в WHERE . Простое упрощение или удаление другого подзапроса заставляет запрос работать без
Запрос слишком сложный
ошибка. В некоторых случаях я обнаружил, что усложнение другого запроса путем добавления логически ненужных уровней вложенности привело к исчезновению ошибки, но мы не хотим полагаться на такие вещи.
Есть ли в моем подходе что-то концептуально слабое, и его не следует использовать, даже если SQL Server не жалуется? Должен ли я просто признать, что MS Access иногда не может обрабатывать одновременно действительный и простой SQL, и разработать обходной путь, используя что-то вроде таблицы в памяти, которую я могу заполнять частями вместо использования одного запроса?
Комментарии:
1. Это не очень полезный комментарий, но MS Access не является базой данных корпоративного уровня. Я предлагаю вам просто перейти на SQL Server и покончить с этим.
2. Я согласен с вами, и это единственное приложение Access, с которым я имею дело, и я унаследовал его, и как подрядчик из-за пределов очень крупного клиента, я не в состоянии продвигать проблему. Тем не менее, я был удивлен, что после моей работы по улучшению этого приложения оно поддерживает десятки одновременных пользователей и некоторые довольно сложные запросы. Похоже, что моя последняя проблема — это просто ошибка, находящаяся вне моего контроля, но я пришел сюда, чтобы получить подтверждение этого или предложение улучшенного кода, чтобы мы могли получить больше жизни от этого важного приложения без другого обхода.
3. Да, я вас слышу. Я просто привык говорить, что есть бизнес-риск и техническая задолженность, и это язык, который они могут понять. Я не эксперт MS Access, но да, все, что я могу придумать, это разбить его на биты. Возможно, вы также могли бы подумать о том, как вы можете каким-то образом использовать это для выполнения какой-то частичной миграции на SQL Server
4. В этом случае каждая из отдельных частей SQL работает как в T-SQL, так и в Access, включая использование вычисляемых значений, пока вложенный SELECT используется для получения значения во внутреннем SELECT, а затем ссылается на внешний SELECT . Я начал делать это как в Access, так и в T-SQL 20 лет назад. В текущем случае с Access что-то еще не так, и я не могу понять это, основываясь на симптомах, которые мы видим здесь. Каждый вложенный запрос работает нормально, но удаление или упрощение одного позволяет использовать значение другого в WHERE, но это не требуется в T-SQL.
5. На самый последний вопрос ответ определенно должен быть «да», если вам нужно продолжать использовать Access. Какой другой ответ есть? Если Access не поддерживает определенные запросы, то, конечно, единственный способ обойти это — создать другое решение, используя различные методы. Однако я мог бы переписать ваше утверждение как один рабочий запрос, но прежде всего… Является ли результат запросов TOP 1 произвольным? Если у вас нет предложения ORDER BY , результаты не гарантируют возврат какой-либо конкретной записи. Или вы можете гарантировать, что для каждого есть только одна запись?