Векторный итератор как параметр функции: что происходит в этом коде? [Дубликат]

Я знаю, что этот вопрос старше, но я смотрел через ответы и думал, что я могу расширить «динамическую» часть проблемы и, возможно, помочь кому-то.

Прежде всего Я построил это решение для решения проблемы, с которой несколько сотрудников столкнулись с непостоянными и большими наборами данных, которые необходимо быстро поворачивать.

Это решение требует создания хранимой процедуры, поэтому, если это не может быть и речи для ваших нужд, пожалуйста, прекратите читать сейчас.

Эта процедура будет принимать ключевые переменные сводной инструкции для динамического создания сводных операторов для разных таблиц, имен столбцов и агрегатов. Столбец Static используется как столбец / идентификатор группы для сводной таблицы (это может быть удалено из кода, если это не необходимо, но довольно часто используется в сводных операторах и было необходимо для решения исходной проблемы), столбец столбца - это то, где конечные имена столбцов будут генерироваться, а столбец значений - это то, к чему будет применяться совокупность. Параметр Table - это имя таблицы, включая схему (schema.tablename), эта часть кода может использовать некоторую любовь, потому что она не такая чистая, как мне бы хотелось. Это работало для меня, потому что мое использование не было публично, и SQL-инъекция не вызывала беспокойства. Параметр Aggregate примет любой стандартный sql-агрегат «AVG», «SUM», «MAX» и т. Д. Код также по умолчанию имеет значение MAX как совокупность, это необязательно, но аудитория, изначально построенная для не понимающих опорных точек, и, как правило, используя max как совокупность.

Давайте начнем с кода для создания хранимой процедуры. Этот код должен работать во всех версиях SSMS 2005 и выше, но я не тестировал его в 2005 или 2016 году, но я не понимаю, почему это не сработает.

create PROCEDURE [dbo].[USP_DYNAMIC_PIVOT] ( @STATIC_COLUMN VARCHAR(255), @PIVOT_COLUMN VARCHAR(255), @VALUE_COLUMN VARCHAR(255), @TABLE VARCHAR(255), @AGGREGATE VARCHAR(20) = null ) AS BEGIN SET NOCOUNT ON; declare @AVAIABLE_TO_PIVOT NVARCHAR(MAX), @SQLSTRING NVARCHAR(MAX), @PIVOT_SQL_STRING NVARCHAR(MAX), @TEMPVARCOLUMNS NVARCHAR(MAX), @TABLESQL NVARCHAR(MAX) if isnull(@AGGREGATE,'') = '' begin SET @AGGREGATE = 'MAX' end SET @PIVOT_SQL_STRING = 'SELECT top 1 STUFF((SELECT distinct '', '' + CAST(''[''+CONVERT(VARCHAR,'+ @PIVOT_COLUMN+')+'']'' AS VARCHAR(50)) [text()] FROM '+@TABLE+' WHERE ISNULL('+@PIVOT_COLUMN+','''') <> '''' FOR XML PATH(''''), TYPE) .value(''.'',''NVARCHAR(MAX)''),1,2,'' '') as PIVOT_VALUES from '+@TABLE+' ma ORDER BY ' + @PIVOT_COLUMN + '' declare @TAB AS TABLE(COL NVARCHAR(MAX) ) INSERT INTO @TAB EXEC SP_EXECUTESQL @PIVOT_SQL_STRING, @AVAIABLE_TO_PIVOT SET @AVAIABLE_TO_PIVOT = (SELECT * FROM @TAB) SET @TEMPVARCOLUMNS = (SELECT replace(@AVAIABLE_TO_PIVOT,',',' nvarchar(255) null,') + ' nvarchar(255) null') SET @SQLSTRING = 'DECLARE @RETURN_TABLE TABLE ('+@STATIC_COLUMN+' NVARCHAR(255) NULL,'+@TEMPVARCOLUMNS+') INSERT INTO @RETURN_TABLE('+@STATIC_COLUMN+','+@AVAIABLE_TO_PIVOT+') select * from ( SELECT ' + @STATIC_COLUMN + ' , ' + @PIVOT_COLUMN + ', ' + @VALUE_COLUMN + ' FROM '+@TABLE+' ) a PIVOT ( '+@AGGREGATE+'('+@VALUE_COLUMN+') FOR '+@PIVOT_COLUMN+' IN ('+@AVAIABLE_TO_PIVOT+') ) piv SELECT * FROM @RETURN_TABLE' EXEC SP_EXECUTESQL @SQLSTRING END

Далее мы подготовим наши данные для примера. Я принял пример данных из принятого ответа с добавлением нескольких элементов данных, которые будут использоваться в этом доказательстве концепции, чтобы показать различные результаты совокупного изменения.

create table temp ( date datetime, category varchar(3), amount money ) insert into temp values ('1/1/2012', 'ABC', 1000.00) insert into temp values ('1/1/2012', 'ABC', 2000.00) -- added insert into temp values ('2/1/2012', 'DEF', 500.00) insert into temp values ('2/1/2012', 'DEF', 1500.00) -- added insert into temp values ('2/1/2012', 'GHI', 800.00) insert into temp values ('2/10/2012', 'DEF', 700.00) insert into temp values ('2/10/2012', 'DEF', 800.00) -- addded insert into temp values ('3/1/2012', 'ABC', 1100.00)

Следующие примеры показывают различные примеры выполнения, показывающие разнообразные агрегаты в качестве простого примера. Я не хотел менять столбцы статические, столбцы и значения, чтобы упростить пример. Вы должны иметь возможность просто скопировать и вставить код, чтобы начать возиться с ним самостоятельно

exec [dbo].[USP_DYNAMIC_PIVOT] 'date','category','amount','dbo.temp','sum' exec [dbo].[USP_DYNAMIC_PIVOT] 'date','category','amount','dbo.temp','max' exec [dbo].[USP_DYNAMIC_PIVOT] 'date','category','amount','dbo.temp','avg' exec [dbo].[USP_DYNAMIC_PIVOT] 'date','category','amount','dbo.temp','min'

Это выполнение возвращает следующие наборы данных соответственно.

17
задан Shafik Yaghmour 31 December 2013 в 07:01
поделиться

2 ответа

Как говорили другие, это связано с расширением Microsoft C ++. Хотя флаг /Za не рекомендуется, так как он может сломать вещи.

Вместо этого используйте переключатель /permissive- для лучшего соответствия стандартам, и вы получите здоровые ошибки для этих случаев. Обратите внимание, что этот флаг доступен с VS 2017.

Коммутатор / Za не поддерживает определенные файлы заголовков Microsoft SDK. В противоположность этому / permissive - предлагает полезный режим соответствия, где ввод кода C ++ интерпретируется в соответствии с правилами ISO C ++, но также позволяет соответствовать расширениям, необходимым для компиляции C ++ для целей, поддерживаемых Visual C ++.

Дополнительная информация находится на Visual C ++ Team Blog .

2
ответ дан Onur Gumus 26 August 2018 в 19:35
поделиться

Это старое расширение для Visual Studio, единственной ссылкой, которую я смог найти на сайте Microsoft, был этот отчет об ошибке: Временные объекты могут быть привязаны к ссылкам не-Const , который имеет следующий пример кода :

struct A {};

A     f1();
void f2(A&);

int main()
{
    f2(f1()); // This line SHALL trigger an error, but it can be compiled without any     errors or warnings.
}

Одна из комментариев:

Существует предупреждение уровня 4 (предупреждение уровня 4 включено, если вы передаете / W4 компилятору) для него

Это сообщение в блоге: Visual C ++ настолько либеральна , которая охватывает это расширение:

Использование отключенных языковых расширений (/ Za) делает ошибку:

19
ответ дан Shafik Yaghmour 26 August 2018 в 19:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: