#sql-server #tsql #dynamic-sql
#sql-сервер #tsql #динамический-sql
Вопрос:
Я получаю эту ошибку:
Сообщение 120, уровень 15, состояние 1, строка 12
Список выбора для инструкции INSERT содержит меньше элементов, чем список insert. Количество выбранных значений должно соответствовать количеству столбцов ВСТАВКИ.
Как я могу выбрать строку из таблицы и insert into @t1
получить конечный результат, например :
| Date1 | Date2 | Date3 | Date4 | Date5 |
------------- ------------- -------------- ------------- ---------------
|'Feb 5 2019'|'Feb 4 2019'|'Feb 1 2019 '|'Jan 30 2019'|'Jan 18 2019 ' |
Я должен запустить хранимую процедуру для создания динамического столбца.
После нахождения максимального количества столбцов я создаю таблицы и пытаюсь вставить в таблицу.
Я хочу выбрать некоторый оператор из строки, и эти строки SQL хранятся в таблице следующим образом
Мой показанный код:
declare @t1 table (id0 datetime,id1 datetime,id2 datetime,id3 datetime,id4 datetime)
INSERT INTO @t1 (id0,id1,id2,id3,id4)
select Dates = STUFF((
SELECT ',''' TRSDate '''' FROM [StandaloneDWH].[zru].[r435_436tcr] where CLM_Id =90
FOR XML PATH('')
), 1, 1, '')
После выполнения кода:
select Dates = STUFF((
SELECT ',''' TRSDate '''' FROM [StandaloneDWH].[zru].[r435_436tcr] where CLM_Id =90
FOR XML PATH('')
), 1, 1, '')
он показывает:
| Dates |
|------------------------------------------------------------------------|
|'Feb 5 2019','Feb 4 2019','Feb 1 2019 ','Jan 30 2019','Jan 18 2019 ' |
Как я мог бы выполнить подобное и вставить в @t1
select
'Feb 5 2019','Feb 4 2019','Feb 1 2019 ','Jan 30 2019','Jan 18 2019 '
чтобы получить конечный результат?
Комментарии:
1. Какую СУБД вы используете? (Этот код зависит от продукта.)
Ответ №1:
Я думаю, вам нужна условная агрегация:
insert into @t1 (id0, id1, id2, id3, id4)
select max(case when seqnum = 1 then trsdate end),
max(case when seqnum = 2 then trsdate end),
max(case when seqnum = 3 then trsdate end),
max(case when seqnum = 4 then trsdate end),
max(case when seqnum = 5 then trsdate end)
from (select r.*,
row_number() over (order by trsdate) as seqnum
from [StandaloneDWH].[zru].[r435_436tcr] r
where CLM_Id = 90
) r;
Вы также можете использовать pivot
для логики. Или создайте динамический SQL с вашим подходом.
Комментарии:
1. Да, я генерировал динамический SQL, но условная агрегация спасла мне жизнь!
Ответ №2:
Я собираюсь принять (n информированное) предположение, что это SQL Server. Таким образом, вы можете использовать sp_executesql для запуска этого как динамического SQL. Большой совет, это вам не поможет, потому что, как только ваш запрос дойдет до точки, где он выполняет динамический SQL, вы покинете сеанс, и TABLE
переменная @t1 будет потеряна.
DECLARE @sql NVARCHAR(4000);
SELECT @sql = 'DECLARE @t1 TABLE (id0 DATETIME, id1 DATETIME, id2 DATETIME, id3 DATETIME, id4 DATETIME);';
SELECT @sql = 'INSERT INTO @t1 (id0, id1, id2, id3, id4) SELECT ';
--SELECT @sql = STUFF((
-- SELECT ',''' TRSDate '''' FROM [StandaloneDWH].[zru].[r435_436tcr]
-- WHERE CLM_Id = 90
-- FOR XML PATH('')), 1, 1, '');
SELECT @sql = '''Feb 5 2019'',''Feb 4 2019'',''Feb 1 2019'',''Jan 30 2019'',''Jan 18 2019'';';
SELECT @sql = 'SELECT * FROM @t1;';
EXEC sp_executesql @sql;
Обратите внимание, что я закомментировал ваш скрипт и жестко запрограммировал значения даты, чтобы показать, что это работает, но вам нужно будет раскомментировать свой раздел, а затем удалить строку под этим.
Результаты:
id0 id1 id2 id3 id4
2019-02-05 00:00:00.000 2019-02-04 00:00:00.000 2019-02-01 00:00:00.000 2019-01-30 00:00:00.000 2019-01-18 00:00:00.000
Ответ Гордона — это то, что вам действительно нужно, но я включил это, чтобы показать, как вы могли бы спасти свой существующий скрипт (вы, должно быть, потратили некоторое время на то, чтобы возиться FOR XML PATH
?), А также почему он не будет работать.