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

No автоинкрементный ключ
Company имя фирмы приставляемое к именам таблицы
bd имя БД
Server путь к серверу
Type тип (Store, Warehouse,Upr,Buh)
City регион/город(Moscow,Piter)
StoreName имя магазина/склада, может отличаться от названия фирмы
DC StoreName для Центрального склада этого магазина/склада
SubType подтип, н-р бренд для магазинов

Получаем что-то типа этого:

base

Ну а дальше элементарно, пишем ХП, которая будет выбирать по заданным параметрам из базы нужные строки и формировать из них запрос.

-- =============================================

CREATE PROCEDURE  [dbo].[EXECSQL]
@SQLSTR varchar(8000),  -- запрос
@ForStore  varchar(1) ='1', -- для магазинов
@ForWareHouse varchar(1)='1', --  для складов
-- если оба параметра =0 то для всех баз
@City  varchar(20) = 'Moscow', -- не обязательный параметр город, если  пусто  то все /Piter,Moscow/
@OnlyBase varchar(1) ='0', -- только 1 раз в  каждой базе
@UnionAll varchar(1)='0' -- только для селектов
--  если =1, то вернуть 1 таблицей, ахтунг! может не хватить 8000  символов

-- ибо формируется 1 запрос объединенный через union all !!!

Прежде чем показать код процедуры, немного пояснений:

Основная идея заключается в том,
что запрос пишется с использованием вместо имени сервера,базы и таблиц неких спец символов, которые при выполнении запроса для конкретной фирмы заменяются конкретными значениями, н-р:

запрос ‘select count(*) from [ShortSRV$Barcodes]’, где ShortSRV$ будет заменено на полный путь к базе+префикс таблицы — «[NAV-SRV].[SPb_Shop_MEXX].dbo.[MX030»

Отбираем по переданным параметрам нужные строчки из таблицы CompanyList и для удобства сохраняем их во временной табличке. Для удобства делаем параметр — общая таблица или нет. Если таблица общая (т.е. не содержит префикса фирмы), то для каждой базы отбираем только 1 фирму (любую), чтоб избежать не нужных запросов.

Далее создаём цикл по временной табличке и для каждой строчки таблицы делаем замену в переданном запросе на конкретные параметры. Для удобства сюда выведено и название магазина/склада (н-р нам надо в каждую фирму вставить кладовщика Иванова и указать что текущий склад для него является основным в этой фирме).

Созданный запрос в виде строки выполняем через EXEC(@строка) .

Пару слов о Exec…

На самом деле вместо exec рекомендуется использовать хранимую процедуру sp_executesql. Она обладает рядом преимуществ в быстродействии и оптимизации запроса. Но тут есть один тонкий момент. Она использует для передачи в качестве строки запроса тип nvarchar, максимальный размер которого 4000 символов, а менее оптимальная exec использует тип varchar с макс длиной 8000 символов.

К сожалению Навижн создаёт поля во всех таблицах со свойством not null и с полем типа timestamp, которое заполняется автоматически системой. А это означает, что нам придется перечислать названия всех полей таблицы (кроме timestamp) для insert-а и перечислять все поля в селекте. А таблички бывают весьма не маленькие по числу полей. Из-за этого пришлось отказаться от sp_executesql в пользу большего размера строки.

Для удобства статистических запросов (н-р когда мы хотим узнать сколько у нас штрихкодов в каждой базе) сделаем опцию — вывести результат запросов из разных баз одной таблицей. Для этого мы не будем выполнять запрос для каждой базы, а объединим их в один запрос через union all и в конце его и выполним. Тут есть один тонкий момент, для такого запроса запросто может не хватить 8000 символов. У меня это не отслеживается, но я уверен, что Вы в своей версии обязательно сделаете проверку длины и если она будет равна или больше (смотря как вы будите проверять) 8000, то вызовите RAISERROR.

зы: все формируемые запросы выводятся через print в «консоль», работе это не мешает, а в случае неправильного запроса позволяет легко найти где ошибка в составлении запроса…