Возвращает результат запроса SELECT в виде строки CSV

#sql #sql-server #tsql #csv

#sql #sql-сервер #tsql #csv

Вопрос:

У меня есть следующий оператор Sql Server 2016 SELECT, который возвращает только 1 строку:

 SELECT TOP 1 * FROM tempdb.dbo.IMTD
  

Как я могу объединить значения в виде строки, разделенной запятыми? ПРИМЕЧАНИЕ: имена столбцов этой временной таблицы неизвестны, поскольку они могут меняться.

Спасибо.

Комментарии:

1. Как вы выполняете этот запрос? SSMS? Powershell? Ваше собственное приложение?

2. @alroc Я использую SSMS

Ответ №1:

Возможно, что-то вроде этого:

 -- Sample data
DECLARE @someTable TABLE (SomeID int identity, SomeTxt varchar(100));
INSERT @someTable VALUES ('row1'),('row2'),('row3');

-- Solution
SELECT ConcatinatedString = 
STUFF
((
  SELECT ',' SomeTxt
  FROM @someTable
  FOR XML PATH(''), TYPE
).value('.','varchar(100)'),1,1,'');
  

Комментарии:

1. Не могли бы вы, пожалуйста, указать, что такое «SomeTxt», у меня нет никакой информации об именах столбцов во временной таблице?

Ответ №2:

Вы можете использовать динамический запрос, как показано ниже:

 DECLARE @COLS VARCHAR(MAX) = ''

SELECT @COLS = @COLS   ','   COLUMN_NAME
FROM tempdb.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE '#table[_]%' -- Dynamic Table (here, Temporary table)

DECLARE @COLNAMES VARCHAR(MAX) = REPLACE(STUFF(@COLS, 1, 1, ''), ',', '  '',''  ')

Declare @cmd varchar(max) = 'Select '   @COLNAMES   ' as CSVCol from #table'
-- will generate
-- Select Column1  ','  Column2  ','  Column3 as CSVCol from #table
EXEC (@cmd)
  

Комментарии:

1. Странно, @COLUMNNAMES усекается до 256 символов (но код должен работать правильно). Есть предложения? Спасибо!

2. Я думаю, это может быть связано с типом данных. Можете ли вы попробовать с nvarchar заменой varchar ?

3. Да, я сделал: ОБЪЯВИТЬ @COLNAMES NVARCHAR(MAX) = ЗАМЕНИТЬ (STUFF(@COLS, 1, 1, «), ‘,’, ‘ «,» ‘)

4. Какую длину вы получаете SELECT LEN(@COLS) ?

5. ВЫБЕРИТЕ len (@COLS) = 171; ВЫБЕРИТЕ LEN (@COLNAMES)=346

Ответ №3:

Другое решение, которое вы можете попробовать, это.

 SELECT LTRIM(RTRIM(<ColumnName1>))   ',',
       LTRIM(RTRIM(<ColumnName2>))   ',',
       ...
       LTRIM(RTRIM(<ColumnNamen>))   ','
FROM tempdb.dbo.IMTD
  

Если вам нужна только одна строка, сохраните эту верхнюю 1, например

     SELECT TOP 1
       LTRIM(RTRIM(<ColumnName1>))   ',',
       LTRIM(RTRIM(<ColumnName2>))   ',',
       ...
       LTRIM(RTRIM(<ColumnNamen>))   ','
FROM tempdb.dbo.IMTD
  

LTRIM и RTRIM удалят все пробелы, и это должно позволить вам скопировать и вставить результирующий набор везде, где он может вам понадобиться. Вам нужно будет сделать это для каждого имени столбца.

Комментарии:

1. Я попробовал оба запроса, я получаю: неправильный синтаксис рядом с ‘*’.

2. @M.R. извините, я забыл, что вы должны указать имя каждого столбца, как в редактировании выше.

Ответ №4:

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

  DECLARE @ColumnNames NVARCHAR(MAX)

 SELECT 
    @ColumnNames= COALESCE(@ColumnNames  ',','') COLUMN_NAME  
 FROM 
    TempDB.INFORMATION_SCHEMA.COLUMNS 
 WHERE 
    TABLE_NAME = '#TempTableName'
  

Комментарии:

1. Я вижу… Я думал, что смогу избежать этого, это становится сложным… Спасибо за предложение.