Как обойти SQL Server «Было превышено максимальное количество таблиц в запросе (260)».

#sql-server-2000

#sql-server-2000

Вопрос:

у меня есть запрос, который содержит серию из 21 UNIONs , например:

 CREATE VIEW dbo.USGovCurrencyOnHandBreakdown AS

   SELECT ... FROM a
   UNION ALL
   SELECT ... FROM b
   UNION ALL
   SELECT ... FROM c
   UNION ALL
   SELECT ... FROM d
   ...
   UNION ALL
   SELECT ... FROM u
  

Запрос выполняется нормально, когда выполняется один. Но когда запрос выполняется через содержащее представление:

 SELECT * FROM USGovCurrencyOnHandBreakdown 

Msg 4414, Level 16, State 1, Line 1
Could not allocate ancillary table for view or function resolution. The maximum number of tables in a query (260) was exceeded.
  

я попытался разбить свое USGovFedExpentiures представление на более мелкие фрагменты:

 CREATE VIEW dbo.USGovCurrencyOnHandBreakdown AS

   SELECT x FROM TreasuryAuditResults
   UNION ALL
   SELECT x FROM USGovCurrencyOnHandBreakdown_Additions
   UNION ALL
   SELECT x FROM USGovCurrencyOnHandBreakdown_Subtractions
  

С USGovCurrencyOnHandBreakdown_Additions и USGovCurrencyOnHandBreakdown_Subtractions , каждый из которых содержит примерно половину запросов:

 CREATE VIEW USGovCurrencyOnHandBreakdown_Additions AS
   SELECT ... FROM b
   UNION ALL
   SELECT ... FROM c
   ...
   SELECT ... FROM k

CREATE VIEW USGovCurrencyOnHandBreakdown_Subtractions AS
   SELECT ... FROM l
   UNION ALL
   SELECT ... FROM m
   ...
   SELECT ... FROM u
  

Но выбор из «родительского» представления по-прежнему не выполняется:

 SELECT * FROM USGovCurrencyOnHandBreakdown

Msg 4414, Level 16, State 1, Line 1
Could not allocate ancillary table for view or function resolution. The maximum number of tables in a query (260) was exceeded.
  

Как я могу обойти ограничение в 256 таблиц?

Смотрите также

Комментарии:

1. 1) Проверьте рекурсию (просмотр чтения из просмотра чтения из предыдущего просмотра). 2) Все эти a .. u действительно просто таблицы или какие-либо из них являются представлениями? Очевидно, что в вашем запросе нет 260 таблиц, поэтому должно быть что-то еще.

2. Можете ли вы взглянуть на план запроса?

3. Было несколько соединений с представлением, которое само объединяет 3 таблицы. Ситуация быстро умножалась.

Ответ №1:

Коллега придумал отличный ответ. Используйте функцию для возврата табличной переменной; вставляйте результаты в табличную переменную постепенно:

 CREATE VIEW dbo.USGovCurrencyOnHandBreakdown AS
    SELECT * FROM fn_USGovCurrencyOnHandBreakdown()
  

с представлением, которое теперь вызывает UDF:

 CREATE FUNCTION dbo.fn_USGovCurrencyOnHandBreakdown()
    RETURNS @Results TABLE
    (
        Total money, 
        ...
    )

    INSERT INTO @Results SELECT ... FROM a
    INSERT INTO @Results SELECT ... FROM b
    INSERT INTO @Results SELECT ... FROM c
    INSERT INTO @Results SELECT ... FROM d
      ...
    INSERT INTO @Results SELECT ... FROM u

    RETURN 
END
  

Насколько известно любым клиентам, view значение не изменилось. (За исключением того, что теперь это работает!)

Ответ №2:

Вы могли бы сохранить подзапросы во временных таблицах, например, в USGovCurrencyOnHandBreakdown_Additions и USGovCurrencyOnHandBreakdown_Subtractions , которые вы упомянули, а не выбирать из этих временных таблиц вместо представлений.

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