Наше приложение для хранения документов имеет уникальную базу данных для каждого из наших клиентов, которые практически идентичны друг другу, но одна таблица DocumentIndexes
уникальна для каждого клиента и может иметь любое количество столбцов и типов.
Я пытаюсь создать универсальную функцию (в нашей «основной» базе данных с именем MYAPP_MASTER
), которую я могу вызвать и просто передать имя базы данных и значение идентификатора документа и получить имена и значения столбцовиз таблицы DocumentIndexes
указанной базы данных.Поскольку мне нужно передать имя базы данных, я должен динамически генерировать SQL выбора и вызывать sp_executesql
.
У меня есть следующий код, который опрашивает таблицу INFORMATION_SCHEMA.COLUMNS
, чтобы определить необходимые столбцы, и она прекрасно работает в хранимой процедуре, но я ненавижу копировать весь этот код в каждую хранимую процедуру, которая нуждается в нихполучить эти значения динамического столбца.Я предпочел бы иметь одну функцию, которая возвращает строковое значение этих столбцов независимо от базы данных, и эта функция существует один раз в нашей базе данных MYAPP_MASTER
.Опять же, этот код работает, но SQL не позволит мне поместить его в функцию.Есть ли что-нибудь вокруг этого?
USE MYAPP_MASTER
GO
DECLARE @DatabaseName varchar(255)
DECLARE @DocumentId int
SET @DatabaseName = 'SAMPLE_CLIENT_DB'
SET @DocumentId = 1234
DECLARE @DynamicIndexes nvarchar(max)
DECLARE @DynamicIndexesParam nvarchar(max)
DECLARE @DynamicIndexesSql nvarchar(max)
SET @DynamicIndexesParam = '@Indexes varchar(max) OUTPUT'
SET @DynamicIndexesSql = 'SELECT @Indexes = COALESCE(@Indexes + ''+ '''', '', '''') + CAST(COLUMN_NAME as varchar(max)) + '': '''''' + '' + CASE WHEN DI.'' + COLUMN_NAME + '' IS NOT NULL THEN CAST(DI.'' + COLUMN_NAME + '' as varchar(max)) ELSE '''''''' END '' FROM ' + @DatabaseName + '.INFORMATION_SCHEMA.COLUMNS WHERE table_name = ''DocumentIndexes'' AND COLUMN_NAME <> ''DocumentID''; '
EXEC sp_executesql @DynamicIndexesSql, @DynamicIndexesParam, @Indexes = @DynamicIndexes OUTPUT
SET @DynamicIndexes = '''' + @DynamicIndexes
DECLARE @SelectionSql nvarchar(max)
SET @SelectionSql = 'SELECT ' + @DynamicIndexes + ' as DocumentIndexes FROM ' + @DatabaseName + '..Document D LEFT OUTER JOIN ' + @DatabaseName + '..DocumentIndexes DI ON D.DocumentId = DI.DocumentId WHERE D.DocumentID = ' + CAST(@DocumentId as varchar(10))
EXEC sp_executesql @SelectionSql
Если в таблице SAMPLE_CLIENT_DB
базы данных DocumentIndexes
есть столбцы для Имя, Офис и Классификация, этот код возвратит простую строку, которая выглядит следующим образом:
Name: Foo, Office: Bar, Classification: 123