SQL Server 2012.
Существует таблица с инструкциями sql, поддерживаемая разработчиками.
CREATE TABLE t
(
id INT PRIMARY KEY CLUSTERED NOT NULL IDENTITY(1, 1)
, sql_statement NVARCHAR(MAX) NOT NULL
, recipient NVARCHAR(MAX) NOT NULL
);
INSERT INTO t
SELECT 'select 1 as one, 2 as two, 3 as three'
, 'some-email-address@host.com'
Время от времени автоматизированный процесс запускает и выполняет одно из утверждений, проверяет, вернул ли он какие-либо строки и, если да, отправляет их по электронной почте. Важным моментом является то, что процесс добавляет некоторые дополнительные элементы к электронному письму в зависимости от различных условий, поэтому это не простая задача «генерировать и отправить данные в формате csv» (мы не можем просто использовать встроенную функцию прикрепления результатов запроса к электронному письму) .
Процесс должен быть максимально динамичным. В частности, он должен поддерживать любые допустимые операторы SQL, которые возвращают строки.
Текущая реализация для извлечения и обработки данных из столбца sql_statement выглядит примерно так:
DECLARE @sql NVARCHAR(MAX);
SELECT @sql = sql_statement
FROM dbo.t
WHERE id = 1;
DECLARE @actual_sql NVARCHAR(MAX) = N'SELECT * INTO ##t from (' + @sql + N') t;';
EXECUTE(@actual_sql)
DECLARE @msg NVARCHAR(MAX);
SELECT @msg = 'plenty of heavy-lifting here, building the email message body based on the contents of ##t and various conditions'
DROP TABLE ##t
EXECUTE msdb.dbo.sp_send_dbmail
@recipients = @recipients
, ... ...
, @body = @msg
Проблема с вышеприведенным решением заключается в том, что оно не позволяет разработчикам использовать операторы WITH
в столбце sql_statement
, поскольку они вызывают синтаксическую ошибку в строке EXECUTE(@actual_sql)
(по очевидным причинам: вы не можете select from (with...)
). Они могут использовать подзапросы в блоке FROM
, но я хочу, чтобы они могли использовать любой код SQL, который возвращает строки.
Есть ли обходной путь?