#sql #sql-server #dynamic
#sql #sql-сервер #динамический
Вопрос:
Мне нужно создать динамический запрос для импорта данных в Azure DataFactory, используя пару таблиц в качестве источника запроса (у меня уже есть конвейер, который импортирует таблицы «как есть» на основе списка исходной таблицы в SQL).
В настоящее время используется SQL Server 2014, поскольку это то, что у меня есть в моей системе разработки.
Одна таблица содержит список исходных таблиц, которые будут импортированы, в то время как вторая содержит список фильтров для каждой таблицы.
Чтобы сделать его немного более сложным, для каждого включения может быть несколько вариантов на основе столбца «Счетчик».
Исходная таблица:
TableName
---------
Table1
Table2
Table3
Таблица запросов:
TableName ColumnName Counter Value
--------------------------------------
Table1, Column1, 1, abc
Table2, Column1, 1, def
Table2, Column1, 2, ghi
Table2, Column1, 3, jkl
Table3, Column1, 1, mno
Table3, Column2, 1, pqr
Поэтому в этом случае я хотел бы сгенерировать что-то вроде приведенного ниже в отдельную таблицу для чтения конвейером Azure:
(На основе выбора * из [исходных таблиц].[Имя таблицы] присоединяется к [QueryTable] в SourceTable.Имятаблицы = Таблица запросов.Имя таблицы)
select * from Table1 where Column1 in ('abc')
select * from Table2 where Column1 in ('def','ghi','jkl')
select * from Table3 where Column1 in ('mno') and Column2 in ('pqr')
Если есть какие-либо указания, я был бы признателен за помощь.
Примечание: На данный момент мне «только» действительно нужно, чтобы первые 2 сценария 2 работали (одна / несколько записей в одном столбце), хотя сценарий 3 вполне возможен.
Заранее благодарю.
Комментарии:
1. Действительно ли все ваши значения в таблице
QueryTable
имеют запятые (,
) в конце их?2. Нет. Это было мое форматирование.
Ответ №1:
Это действительно некрасиво, я не собираюсь лгать. Честно говоря, я бы предложил исправить дизайн здесь, но (говоря это) вы можете достичь того, что вам нужно. Однако это далеко не «просто» для понимания, поскольку при этом достигается результат с помощью агрегированной строки внутри агрегированной строки:
CREATE TABLE dbo.YourTable (--SchemaName sysname DEFAULT N'dbo', --This appears to be missing
TableName sysname,
ColumnName sysname,
Counter int,
Value varchar(128));
INSERT INTO dbo.YourTable (TableName,ColumnName,Counter, Value)
VALUES(N'Table1',N'Column1',1,'abc'),
(N'Table2',N'Column1',1,'def'),
(N'Table2',N'Column1',2,'ghi'),
(N'Table2',N'Column1',3,'jkl'),
(N'Table3',N'Column1',1,'mno'),
(N'Table3',N'Column2',1,'pqr');
GO
DECLARE @CRLF nchar(2) = NCHAR(13) NCHAR(10);
DECLARE @AND nchar(7) = @CRLF N' AND ';
SELECT N'SELECT *' @CRLF
N'FROM dbo.' QUOTENAME(TableName) @CRLF
N'WHERE '
STUFF((SELECT @AND N' ' QUOTENAME(sq1.ColumnName) N' IN ('
STUFF((SELECT N',' QUOTENAME(sq2.Value,'''')
FROM dbo.YourTable sq2
WHERE sq2.TableName = YT.TableName
AND sq2.ColumnName = sq1.ColumnName
ORDER BY Counter ASC
FOR XML PATH(''),TYPE).value('(./text())[1]','nvarchar(MAX)'),1,1,'')
N')'
FROM dbo.YourTable sq1
WHERE sq1.TableName = YT.TableName
GROUP BY sq1.ColumnName
ORDER BY sq1.ColumnName
FOR XML PATH(''),TYPE).value('(./text())[1]','nvarchar(MAX)'),1,LEN(@AND) 1,'') N';'
FROM dbo.YourTable YT
GROUP BY TableName;
GO
DROP TABLE dbo.YourTable;
Обратите внимание, что если [Value]
может иметь значение длиннее 128 символов, вам нужно будет заключить значение в одинарные кавычки ( '
) и REPLACE
те, что внутри них. Кроме того, если это an nvarchar
(не a varchar
), вам нужно будет префиксить эти одинарные кавычки символом nvarchar
обозначения ( N
).
Комментарии:
1. Спасибо, Ларну. Таблица, которая у вас есть как [YourTable], уже существует на моем сервере разработки как [QueryTable] , но мне нужно, чтобы она присоединилась к таблице [SourceTable], о которой я упоминал. Итак, в принципе, мне нужно прочитать столбец [TableName] из [SourceTable], затем проверить наличие любых соответствующих фильтров в [QueryTable] при объединении в столбце [TableName] в каждом.
2. Вы можете
JOIN
SourceTable
, если вам «нужно» @pieyed , но, учитывая, что в нем один столбец и те же значения, что и вQueryTable
, я не видел необходимости в решении.3. Извините. Моя ошибка. Это потому, что не в каждой таблице есть фильтры.
4. Хорошо, тогда вы можете добавить
JOIN
илиEXISTS
, если необходимо, @pieyed ; это не меняет базовое решение.