Чтобы ответить на ваш вопрос буквально:
Когда SELECT не создает таблицу в качестве вывода
Никогда!
Возвращается SELECT
набор результатов, состоящий из строк, и каждая строка, состоящая из столбцов.
Существует особая ситуация, когда ваш набор результатов возвращается с точно одной строкой с одним столбцом. Это может быть взято как скалярное значение и, следовательно, может быть присвоено переменной.
Вы можете принудительно использовать одну строку с TOP 1
или с WHERE
-клаузой, которая гарантируетникогда не возвращайте больше одного ряда. Но двигатель не увидит этого заранее. В предоставленном вами коде упоминаются два столбца, один с QUOTENAME()
и - после запятой - еще раз category_name
. Вот почему вы получаете исключение.
Это аналогичная ситуация, когда вы хотите проверить список, например, с помощью
WHERE SomeID IN(SELECT TheId FROM AnotherTable)
SELECT в IN()
вернет списокЗначения идентификатора, но будет только один столбец.
ОБНОВЛЕНИЕ Некоторые подсказки для вашего кода ...
Что вы здесь делаете:
SELECT
@columns += QUOTENAME(category_name) + ',',
category_name
FROM
... называется причудливым обновлением и может работать без второго упоминания category_name
. Это примерно итерация через значения таблицы, где каждая строка добавляет к ранее установленному значению @column
.
Этот подход очень опасен и его следует избегать(или используется с некоторыми знаниями backgorund ).
Начиная с v2017, есть STRING_AGG()
, и прежде чем я предпочту подход с FOR XML PATH('')
Пример
Попробуйте это:
USE master;
DECLARE @columns VARCHAR(MAX)='';
- Ваш подход с необычным обновлением
SELECT
@columns += QUOTENAME(COLUMN_NAME) + ','
FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='spt_fallback_db';
SELECT @columns;
- Рекомендуемый подход с XML
SET @columns=
STUFF(
(SELECT ','+QUOTENAME(COLUMN_NAME)
FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='spt_fallback_db'
FOR XML PATH(''),TYPE).value('.','nvarchar(max)'),1,1,'');
SELECT @columns;
--и - v2017 + необходимо - с STRING_AGG ()
SELECT @columns=STRING_AGG(QUOTENAME(COLUMN_NAME),',')
FROM
INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='spt_fallback_db';
SELECT @columns;