Похоже, что #temptables, созданные с использованием динамического SQL с помощью строкового метода EXECUTE, имеют разную область видимости и не могут ссылаться на «исправленные» SQL-запросы в той же хранимой процедуре. Тем не менее, я могу ссылаться на временную таблицу, созданную динамическим оператором SQL в динамическом SQL подпоследовательности, но кажется, что хранимая процедура не возвращает результат запроса вызывающему клиенту, если SQL не исправлена.T-SQL Динамические таблицы SQL и Temp
Простой сценарий с двумя таблицами: У меня есть 2 стола. Назовем их «Заказы и предметы». У ордена есть первичный ключ OrderId, а элементы имеют первичный ключ ItemId. Items.OrderId - это внешний ключ для идентификации родительского ордера. Заказ может содержать от 1 до n элементов.
Я хочу иметь возможность предоставить очень гибкий интерфейс типа «запрос строителя», чтобы пользователь мог выбрать, какие элементы он хочет видеть. Критерии фильтра могут быть основаны на полях из таблицы Items и/или из родительской таблицы заказов. Если элемент соответствует условию фильтра, включая условие и условие для родительского ордера, если он существует, элемент должен быть возвращен в запросе, а также родительский заказ.
Обычно, я полагаю, большинство людей создавали бы соединение между таблицей Item и родительскими таблицами заказов. Вместо этого я хотел бы выполнить 2 отдельных запроса. Один, чтобы вернуть все квалификационные элементы и другие, чтобы вернуть все отдельные родительские ордеры. Причина в два раза, и вы можете или не можете согласиться.
Первая причина заключается в том, что мне нужно запросить все столбцы в родительской таблице заказов, и если бы я сделал один запрос, чтобы присоединиться к таблице Orders в таблице Items, я бы несколько раз возвращал информацию о заказе. Поскольку на заказ обычно имеется большое количество предметов, я бы хотел этого избежать, потому что это привело бы к тому, что гораздо больше данных было передано жировому клиенту. Вместо этого, как уже упоминалось, я хотел бы вернуть две таблицы отдельно в наборе данных и использовать две таблицы внутри, чтобы заполнить пользовательские объекты Order и child Items. (Я еще недостаточно знаю о LINQ или Entity Framework. Я строю свои объекты вручную). Вторая причина, по которой я хотел бы вернуть две таблицы вместо одной, состоит в том, что у меня уже есть другая процедура, которая возвращает все элементы для данного OrderId вместе с родительским ордером, и я хотел бы использовать один и тот же подход из 2 таблиц, чтобы я может повторно использовать код клиента для заполнения моих пользовательских объектов Order и Client из возвращаемых 2 возвращаемых данных.
То, что я надеялся сделать, это:
Построить динамическую строку SQL на клиенте, который связывает таблицу заказов на таблицу Элементы и фильтры соответствующих каждой таблицы, как указано в пользовательском фильтре, созданного на Winform жирное клиентское приложение. SQL сборки на клиенте выглядел бы примерно так:
TempSQL = "
INSERT INTO #ItemsToQuery
OrderId, ItemsId
FROM
Orders, Items
WHERE
Orders.OrderID = Items.OrderId AND
/* Some unpredictable Order filters go here */
AND
/* Some unpredictable Items filters go here */
"
Тогда, я бы вызвать хранимую процедуру,
CREATE PROCEDURE GetItemsAndOrders(@tempSql as text)
Execute (@tempSQL) --to create the #ItemsToQuery table
SELECT * FROM Items WHERE Items.ItemId IN (SELECT ItemId FROM #ItemsToQuery)
SELECT * FROM Orders WHERE Orders.OrderId IN (SELECT DISTINCT OrderId FROM #ItemsToQuery)
Проблема с этим подходом является то, что #ItemsToQuery стол, так как это было созданный динамическим SQL, недоступен из следующих 2 статических SQL-запросов, и если я изменил статические SQL-запросы на динамические, результаты не будут возвращены жировому клиенту.
3 вокруг прийти на ум, но я искать лучше один:
1) Первый SQL может быть выполнена путем выполнения динамически построенного SQL от клиента. Затем результаты могут быть переданы в виде таблицы в модифицированную версию вышеупомянутой хранимой процедуры. Я знаком с передачей данных таблицы как XML. Если я это сделаю, сохраненный proc может затем вставить данные во временную таблицу, используя статический SQL, который, поскольку он был создан динамическим SQL, затем может быть запрошен без проблем.(Я мог бы также расследовать передачу нового параметра типа таблицы вместо XML.) Однако я хотел бы избежать переноса потенциально больших списков в хранимую процедуру.
2) Я мог выполнять все запросы от клиента.
Первое будет что-то вроде этого:
SELECT Items.* FROM Orders, Items WHERE Order.OrderId = Items.OrderId AND (dynamic filter)
SELECT Orders.* FROM Orders, Items WHERE Order.OrderId = Items.OrderId AND (dynamic filter)
Это все еще дает мне возможность повторно использовать мой клиент стороннего код объекта-население, так как заказы и товары продолжают быть возвращены в двух различных таблицах.
У меня есть ощущение, что у меня могут быть некоторые параметры, используя тип данных таблицы в моей хранимой процедуре, но это также ново для меня, и я был бы признателен за немного ложки, питающейся этим.
Если вы даже отсканировали это далеко в том, что я написал, я удивлен, но если это так, я буду обесценивать любые ваши мысли о том, как это сделать лучше всего.
TLDR: http://www.urbandictionary.com/define.php?term=TLDR –