Я сделал динамический процесс, который превращает любой случайный запрос в таблицу HTML, поэтому вам не нужно жестко кодировать столбцы, как в других ответах.
-- Description: Turns a query into a formatted HTML table. Useful for emails.
-- Any ORDER BY clause needs to be passed in the separate ORDER BY parameter.
-- =============================================
CREATE PROC [dbo].[spQueryToHtmlTable]
(
@query nvarchar(MAX), --A query to turn into HTML format. It should not include an ORDER BY clause.
@orderBy nvarchar(MAX) = NULL, --An optional ORDER BY clause. It should contain the words 'ORDER BY'.
@html nvarchar(MAX) = NULL OUTPUT --The HTML output of the procedure.
)
AS
BEGIN
SET NOCOUNT ON;
IF @orderBy IS NULL BEGIN
SET @orderBy = ''
END
SET @orderBy = REPLACE(@orderBy, '''', '''''');
DECLARE @realQuery nvarchar(MAX) = '
DECLARE @headerRow nvarchar(MAX);
DECLARE @cols nvarchar(MAX);
SELECT * INTO #dynSql FROM (' + @query + ') sub;
SELECT @cols = COALESCE(@cols + '', '''''''', '', '''') + ''['' + name + ''] AS ''''td''''''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET @cols = ''SET @html = CAST(( SELECT '' + @cols + '' FROM #dynSql ' + @orderBy + ' FOR XML PATH(''''tr''''), ELEMENTS XSINIL) AS nvarchar(max))''
EXEC sys.sp_executesql @cols, N''@html nvarchar(MAX) OUTPUT'', @html=@html OUTPUT
SELECT @headerRow = COALESCE(@headerRow + '''', '''') + '''' + name + '' ''
FROM tempdb.sys.columns
WHERE object_id = object_id(''tempdb..#dynSql'')
ORDER BY column_id;
SET @headerRow = '''' + @headerRow + '' '';
SET @html = '''' + @headerRow + @html + ''
'';
';
EXEC sys.sp_executesql @realQuery, N'@html nvarchar(MAX) OUTPUT', @html=@html OUTPUT
END
GO
Использование:
DECLARE @html nvarchar(MAX);
EXEC spQueryToHtmlTable @html = @html OUTPUT, @query = N'SELECT * FROM dbo.People', @orderBy = N'ORDER BY FirstName';
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'Foo',
@recipients = 'bar@baz.com;',
@subject = 'HTML email',
@body = @html,
@body_format = 'HTML',
@query_no_truncate = 1,
@attach_query_result_as_file = 0;
Связанный: Вот аналогичный код для преобразования любого произвольного запроса в строку CSV .
Лично я предпочитаю разделение команд и запросов - т. Е. Методы, возвращающие результат, не должны быть мутаторами, и наоборот. Я понимаю аргументы в пользу того, что вернет эту
толпу, то есть простоту «цепочки» вызовов:
foo.ChangeThis(23).ChangeThat(45).AndAlso(67);
но это '
Выбор, возвращать экземпляр объекта или нет, будет зависеть от ситуации.
Типичный случай возврата объекта методом рассматривается в шаблоне построителя , например, класс StringBuilder
:
new StringBuilder("Hello").Append(" ").Append("World!").ToString();
Но в целом, если такое связывание методов не будет выполняться, я бы предпочел ничего не возвращать. Если распространенный вариант использования - не использовать возвращаемый объект (а просто отбросить его), это может показаться пустой тратой.
Самое интересное в том, чтобы сделать это первым способом, при котором вы фактически возвращаете элемент после его изменения, заключается в том, что он позволяет использовать цепочку методов. Это означает, что вы можете сделать что-то вроде этого:
c.ModifyIt("hello").MessWithIt("World").ReallyScrewWithIt("!!!");
Если это имеет смысл с вашим конкретным классом, где вы можете предвидеть необходимость объединения в цепочку, то верните экземпляр. Если нет, то вы можете просто аннулировать его. Хорошим примером этого является класс StringBuilder, который позволяет вам делать что-то вроде:
myStringBuilder.Replace("!", "?").Append("Something").Remove(4,3);
Лично я предпочел бы создать такую функцию, как ModifyIt, и поместить ее в создаваемый мной класс, если это возможно. Причина, по которой я говорю это, заключается в том, что в обоих методах я изменяю вызывающую переменную, потому что передаю ее по ссылке. Естественно, я не могу сделать это для всех функций, но включение ref в вызове функции помогает пояснить, что я передаю переменную по ссылке, а не по значению. Пример:
public Class ModifyIt(ref Class c)
Почему? Потому что, когда я возвращаюсь и читаю код, я могу забыть, что я передал значение по ссылке, и тогда я, скорее всего, сделаю что-то «плохое» с кодом.
Во-первых, если вы меняете только одно свойство, у меня вообще не было бы отдельной функции модификации; Я бы просто поменял собственность напрямую. Разобравшись с этим, давайте предположим, что вы даете простой пример чего-то более сложного, возможно, с несколькими различными изменениями внутри функции модификации.
Я бы использовал тот, который возвращает объект 'Class'. Это позволяет объединить несколько вызовов в цепочку. Опять же, я предполагаю, что это простой пример более сложной системы; предположим, что вместо этого у вас есть MakeModification (), MakeAnotherModification () и MakeAThirdModification (). Если вы вернете объект Class, вы получите следующую синтаксическую точность:
Class c = new Class();
c.MakeModification().MakeAnotherModification().MakeAThirdModification();
На самом деле я предпочитаю второй стиль, поскольку метод является мутатором, поэтому не ожидается возврата нового значения, вместо этого ожидается изменение фактического значения. Однако вам может потребоваться указать, что ModifyIt принимает переменную ref, чтобы указать, что фактический c будет изменен. c здесь передается по значению, хотя это ссылочный тип, все же существует разница между передачей ссылочных типов по значению и передачей ссылочных типов по ссылке. См. Следующее:
public void ModifyIt(Myclass c) { c = new MyClass(); }
в приведенном выше случае переменная c будет передана по значению (т. Е. Копия из ссылки будет передана и изменена, чтобы указывать на новый экземпляр объекта, что, в свою очередь, означает, что у вас будет два объекта в данном случае введите MyClass. Вот пример для иллюстрации:
Myclass s = new MyClass () { prop = "value" }; ModifyIt(s); Console.WriteLine(s.prob); // this will print "value"
хотя MOdifyIT создал экземпляр ссылки на новый объект, что должно означать, что проблема будет инициализирована значением null, на самом деле он не создавал экземпляр s, он создавал экземпляр s. в отличие от случая, если s было передано ref.
Надеюсь это поможет!