#sql #sql-server
#sql #sql-сервер
Вопрос:
Пытаюсь использовать функцию SQL string_split в динамическом запросе, но я продолжаю получать следующую ошибку. Недопустимое имя столбца «Описание счета». Тип данных аргумента тип void недопустим для аргумента 1 функции string_split. Я не могу разобраться в проблеме. Любая помощь приветствуется.
DECLARE @AuthFile nvarchar(max); DECLARE @TableName AS SYSNAME;
DECLARE @sql nvarchar(max);
SET @TableName = '__tTransactions_' REPLACE(CONVERT(CHAR(10), GETDATE(), 103), '/', '');
SET @AuthFile = '__Authorization';
create table #temp (TransactionID nvarchar(1000), CartID int, TotalAmount nvarchar(1000))
SET @sql = 'select [Transaction ID] as TransactionID, cs.value as CartID, [Total Amount] as TotalAmount
into #temp
from ' @TableName '
cross apply string_split([Invoice Description], ''|'') cs
where (isnull([Invoice Description], '''') <> '''')';
print(@sql);
EXEC(@sql);
SET @sql = '';
select * from #temp
drop table #temp
Комментарии:
1. Я бы посоветовал вам предоставить образцы данных, желаемые результаты и четкое объяснение того, что должен делать код.
2. Разделение строк не работает с некоторыми типами данных, и в результате вам приходится приводить тип данных к тому, что он может использовать. Я предполагаю, что вы используете varchar(max) или какой-либо другой тип данных, который иногда обрабатывается как большой двоичный объект. Сообщите нам, что это за тип данных и исправляет ли его CAST() для varhcar(8000) для вас.
3. Если я извлекаю этот запрос из переменной и запускаю его не как динамический запрос, он работает просто отлично.
4. «тип void» звучит немного странно. Не знаю, почему в нем не указан фактический тип данных. Вы увидите это, если
__tTransactions_05042021
вообще не содержит столбцаInvoice Description
, но также наряду с другими ошибками дляInvalid column name 'Invoice Description'
5. В любом случае вы не хотите использовать
SELECT ...INTO
здесь, поскольку это создаст новую временную таблицу в области динамического SQL, которая будет уничтожена, как только она завершится
Ответ №1:
Можно создать примерную таблицу для запуска вашего динамического sql.
drop table if exists #__tTransactions_05042021;
create table #__tTransactions_05042021 (
[Transaction ID] int,
[Total Amount] float,
[Invoice Description] varchar(255)
);
insert #__tTransactions_05042021 values
(1, 100, '1|2|3'),
(2, 200, '4|5|6')
Этот пример представляет собой временную таблицу, поэтому я изменил ваш код, чтобы указывать на временную таблицу вместо реальной, но в остальном это то же самое:
DECLARE @AuthFile nvarchar(max);
DECLARE @TableName AS SYSNAME;
DECLARE @sql nvarchar(max);
SET @TableName = '#__tTransactions_' REPLACE(CONVERT(CHAR(10), GETDATE(), 103), '/', '');
SET @AuthFile = '__Authorization';
create table #temp (TransactionID nvarchar(1000), CartID int, TotalAmount nvarchar(1000))
SET @sql = 'select [Transaction ID] as TransactionID, cs.value as CartID, [Total Amount] as TotalAmount
into #temp
from ' @TableName '
cross apply string_split([Invoice Description], ''|'') cs
where (isnull([Invoice Description], '''') <> '''')';
print(@sql);
EXEC(@sql);
SET @sql = '';
select * from #temp
drop table #temp;
Этот код НЕ выдает ошибку. Это не код. Это структура таблицы, на которую вы указываете. Посмотрите, какая таблица предназначена для вашего распечатанного предложения from, и посмотрите на структуру таблицы. Вы должны обнаружить, что в нем нет столбца «описание счета».
Теперь в вашем коде больше проблем. А именно, вы пытаетесь перекачать свои данные в ‘#temp’ внутри динамического sql. Ваш код не завершится ошибкой, но он также не будет работать, потому что контекст отличается между кодом внутри динамического sql и кодом вне его.
Вы захотите либо использовать глобальную временную таблицу (например, ##temp), либо использовать insert-exec . Ниже показано, как вы изменили бы последнюю часть своего кода, чтобы выполнить последнее:
create table #temp (TransactionID nvarchar(1000), CartID int, TotalAmount nvarchar(1000))
SET @sql = 'select [Transaction ID] as TransactionID, cs.value as CartID, [Total Amount] as TotalAmount
from ' @TableName '
cross apply string_split([Invoice Description], ''|'') cs
where (isnull([Invoice Description], '''') <> '''')';
print(@sql);
insert #temp
EXEC(@sql);
SET @sql = '';