Имя вашей таблицы не old.tb2018
, это tb2018
и оно в схеме old
. Это должно быть:
DECLARE @old_table_name sysname; --Correct data type for object names
DECLARE @new_table_name sysname; --Correct data type for object names
...
SET @old_table_name = N'old.' + QUOTENAME(N'tb' + @year);
SET @new_table_name = N'new.' + QUOTENAME(N'tb' + @year);
...
Если вы тоже хотите заключить в кавычки имя схемы (хорошо, если не использовать буквальное значение), это будет:
QUOTENAME(N'new') + N'.' + QUOTENAME(N'tb' + @year);
Хотя я 'мы использовали sysname
здесь, во-вторых, идея должна быть другой. Это действительно должно быть
DECLARE @old_table_name sysname; --Correct data type for object names
DECLARE @new_table_name sysname; --Correct data type for object names
...
SET @old_table_name = QUOTENAME(N'tb' + @year);
SET @new_table_name = QUOTENAME(N'tb' + @year);
...
И тогда в вашем запросе вы получите:
'...FROM old.' + QUOTENAME(@old_table_name) + '...'
Причина этого в том, что sysname
является синонимом nvarchar(128) NOT NULL
, однакоQUOTENAME
возвращает nvarchar(258)
;поэтому цитирование 2 объектов, схемы и таблицы с разделителем (.
), может потенциально привести к nvarchar(517)
(258 + 1 + 258). Поэтому лучше разделить отдельные части на их собственные параметры / переменные и использовать QUOTENAME
в точке впрыска. Это позволит избежать непредвиденного усечения, если у вас есть слишком длинные имена объектов или вы (по глупости) использовали множество ]
символов в своем имени.
Конечно, единственный способ, которым вы мог бы получить 258 символов для имени реального объекта из QUOTENAME
, если бы имя объекта состояло из 128 ]
символов ([
для начала и ]
для конца,и 128 ]
символов перешли на ]]
):
SELECT LEN(QUOTENAME(REPLICATE(']',128)));
Если бы у вас действительно был объект с таким именем, я бы честно поставил под сомнение ваше здравомыслие.