Когда SELECT не создает таблицу в качестве вывода - PullRequest
0 голосов
/ 24 октября 2019

Я новичок в SQL, и я следую веб-учебник. Я обнаружил фрагмент кода, где инструкция SELECT присваивает значение переменной. Я подозреваю, что такие операторы SELECT не составляют таблицу в результате. Например, когда я хочу смешать назначение с именем столбца, как в:

DECLARE 
    @columns NVARCHAR(MAX) = '';

SELECT 
    @columns += QUOTENAME(category_name) + ',',
    category_name
FROM 
    production.categories
ORDER BY 
    category_name;

SET @columns = LEFT(@columns, LEN(@columns) - 1);

PRINT @columns;

, я получаю следующую ошибку:

Сообщение 141, уровень 15, состояние 1, строка 4
Оператор SELECT, который присваивает значение переменной, нельзя сочетать с операциями извлечения данных.

(После этого курс в Интернете с база данных )

Мой вопрос заключается в том, существует ли другая форма манипуляции данными (как присваивание), которая в операторе SELECT не создает таблицу (если мое предположение верно).

Ответы [ 3 ]

2 голосов
/ 24 октября 2019

Независимо от того, что вы делаете, SELECT всегда будет давать вам ТАБЛИЦУ. Создание хранимой процедуры с большим количеством критериев дает вам возможность либо возвращать ТАБЛИЦУ, либо возвращать переменную.

DECLARE @VARIABLE_INPUT VARCHAR(50);
DECLARE @VARIABLE_OUTPUT VARCHAR(50);

SET @VARIABLE_INPUT = 'THIS_IS_INPUT';
EXEC storeProcedureTEST @VARIABLE_INPUT, @VARIABLE_OUTPUT OUTPUT;

PRINT 'The Output of storeProcedureTEST is: ' + @VARIABLE_OUTPUT ;

В вашем storeProcedureTEST:

CREATE PROCEDURE storeProcedureTEST
    @VARIABLE_INPUT VARCHAR(50),
    @VARIABLE_OUTPUT VARCHAR(50)='' OUTPUT
AS
BEGIN
    SET @VARIABLE_OUTPUT = @VARIABLE_INPUT + '_ABC';
END

Результат:

The Output of storeProcedureTEST is: THIS_IS_INPUT_ABC
1 голос
/ 24 октября 2019

Чтобы ответить на ваш вопрос буквально:

Когда 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;
0 голосов
/ 24 октября 2019

Вы хотите преобразовать строку в столбец в одну строку справа

DECLARE 
    @columns NVARCHAR(MAX) = '';

set @columns = (select concat(quotename ,' : ', category_name) from production.categories order by category_name for xml path(''))


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