Присвоить значения переменным в хранимой процедуре - PullRequest
0 голосов
/ 21 февраля 2020
 select  @numOfColumns =  count(distinct Col) from #b
 SET @sql2=
'SELECT'+ @columns +'+= QUOTENAME(Col) + '',''
 from (SELECT DISTINCT top @numOfColumns Col FROM #b ORDER BY Col) A';

 EXECUTE sp_executesql @sql2;

Я пытаюсь заставить эту хранимую процедуру работать. Попытка передать @numOfColumns в оператор, затем присвоить значения из QUOTENAME (Col) в @columns и затем выполнить Exe c для оператора.

Скрипт

DECLARE 
@columns NVARCHAR(MAX) = '',
@sql     NVARCHAR(MAX) = '',
 @sql2     NVARCHAR(MAX) = '',
@numOfColumns int = 0;

SELECT customerid, curbal,  Col = CAST (ROW_NUMBER() OVER (PARTITION BY 
convert(int,customerid) ORDER BY convert(float,curbal) desc) as int)
into #b
FROM [sav acc]

select  @numOfColumns =  count(distinct Col) from #b

SET @sql2= 'SELECT '+ @columns+' += QUOTENAME(Col) + '','' from (SELECT 
DISTINCT top (@numOfColumns) Col FROM #b ORDER BY Col) A';

EXECUTE sp_executesql @sql2, N'@numOfColumns', @numOfColumns int;

Это источник сообщения. ОРИГИНАЛЬНАЯ ПОЧТА . Решение сработало, но я проверил его с исходными данными, он разместит столбец в [3], [2], 1 , и я хотел, чтобы столбцы были 1 , [2 ], [3]

1 Ответ

2 голосов
/ 21 февраля 2020

Во-первых, то, как вы используете TOP, бессмысленно. Если у вас есть 5 различных значений для Col в #b, то SELECT DISTINCT Col FROM #b вернет только 5 записей, независимо от того, примените ли вы TOP 5 или нет. Кажется, вы используете его только для разрешения сортировки, но вы можете просто поместить сортировку во внешний запрос.

Во-вторых, вам не следует использовать присваивание переменных для объединения строк, поведение ненадежно и недокументировано вы должны использовать STRING_AGG, или для более ранних версий SQL Server вы можете использовать XML extensions , либо:

CREATE TABLE #B (Col CHAR(1));
INSERT #B (Col) VALUES ('A'), ('A'), ('B'), ('C');

DECLARE @Columns NVARCHAR(MAX) = 
    (   SELECT  STRING_AGG(QUOTENAME(Col), ',') WITHIN GROUP (ORDER BY Col)
        FROM    (SELECT DISTINCT Col FROM #B) AS b
    );

Или

DECLARE @Columns NVARCHAR(MAX) = 
        STUFF(( SELECT  CONCAT(',', QUOTENAME(Col))
                FROM    #B
                GROUP BY Col
                ORDER BY Col
                FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'), 1, 1, '');

Хотя вышеприведенное показывает, что динамические c sql не нужны, но также было бы ненужным, если вы используете @top, вы можете просто использовать:

DECLARE  @numOfColumns INT = (SELECT count(distinct Col) from #b);
DECLARE @Columns NVARCHAR(MAX) = '';

SELECT  @Columns += QUOTENAME(Col) + ','
FROM    (SELECT DISTINCT TOP (@numOfColumns) Col FROM #B) AS b
ORDER BY Col;

SELECT @Columns;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...