SQL Server цикл через динамический запрос - PullRequest
0 голосов
/ 10 мая 2018

У меня есть процедура, где я передаю временное имя таблицы в качестве параметра. Для каждого набора данных внутри мне нужно получить количество строк. Как этого добиться?

Мне нужно что-то вроде:

CREATE PROCEDURE sp_processing 
  @temp_table_name varchar(50)
AS
  DECLARE @log varchar(max)

/* get list of keys inside temp_table_name */
/* just a pseudo-code example */
SET @l_cursor = CURSOR FOR 
SELECT Key1, Key2, Key3, count(*) 
  FROM @temp_table_name -- table name passed as text 
 GROUP by Key1, Key2, Key3;

WHILE "there are results"
BEGIN
  @log += @Key1 +', '+ @Key2 +', '+ @Key3 +', '+ @count + CHAR(13)+CHAR(10);
END

UPDATE log_table SET log_column = @log WHERE....;

END /* procedure */

Есть ли способ зациклить это?

Я знаю, что могу выбрать результаты для типа table и цикла THEN, но для этого требуется использовать тип таблицы, поэтому интересно, достижимо ли это без табличной переменной.

РЕДАКТИРОВАТЬ : мне просто нужно распечатать счетчик для каждого набора ключей.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Это сработало для меня:

DECLARE @l_sql nvarchar(max)
DECLARE @temp_table_name varchar(50) = 'SOME_TABLE'
DECLARE @combinedString varchar(max)
SET @l_sql = 'SELECT @combinedString = COALESCE(@combinedString, '''') + convert(varchar,[Key1]) +'', ''+ convert(varchar,[Key3]) +'': ''+ convert(varchar,COUNT(*)) + ''| '' + CHAR(13)+CHAR(10) '
           + '  FROM ' + @temp_table_name  
           + ' GROUP BY [Key1], [Key3]'
           + ' ORDER BY [Key1], [Key3]';

EXECUTE sp_executesql @l_sql, N'@combinedString varchar(max) OUTPUT', @combinedString = @combinedString OUTPUT ;

SELECT @combinedString 

Результат:

1, 1: 4| 
1, 2: 2| 
1, 3: 1| 
2, 5: 1| 
0 голосов
/ 10 мая 2018

Вы всегда должны стараться избегать зацикливания и курсора. Это комплексное решение для вашего случая. Пожалуйста, просмотрите (особенно фильтр обновления) и посмотрите, соответствует ли он вашим потребностям.

CREATE PROCEDURE sp_processing 
  @temp_table_name varchar(50)
AS
BEGIN

    DECLARE @DynamicSQL VARCHAR(MAX) = '

        ;WITH LogRecords AS
        (
            SELECT
                LogRecord = 
                    ISNULL(T.Key1, '''') + '','' + 
                    ISNULL(T.Key2, '''') + '','' +  
                    ISNULL(T.Key2, '''') + '','' + 
                    CONVERT(VARCHAR(20), COUNT(1))
            FROM
                QUOTENAME(''' + @temp_table_name + ''') AS T
            GROUP BY
                T.Key1,
                T.Key2,
                T.Key3
        )
        UPDATE L SET
            log_column = STUFF(
                (
                    SELECT
                        R.LogRecord + CHAR(13) + CHAR(10)
                    FROM
                        LogRecords AS R
                    FOR XML
                        PATH('')
                ),
                1, 1, '')
        FROM
            log_table AS L
        WHERE
            L.IdFilter = 999999999'

    PRINT @DynamicSQL

    -- EXEC (@DynamicSQL)

END
...