Обработка скобок, созданных QUOTENAME - PullRequest
0 голосов
/ 21 октября 2019

У меня есть сценарий SQL, как показано ниже. Я использую QUOTENAME, чтобы создать имя таблицы для запроса. Это дает мне ошибку Invalid object name old.tb2018, потому что QUOTENAME генерирует имя таблицы в квадратных скобках, например так:

Я рассмотрел передачу имени таблицы в качестве параметра sp_executesql, но я использую @old_table_name в других местах кода. Я боюсь, что это создаст кучу дублирующегося кода из-за всех других мест, в которых он используется. Как передать имя таблицы в @trunc_success без генерации ошибки?

DECLARE @YEAR NVARCHAR(4) = year(DATEADD(YEAR, - 1, getdate()))
DECLARE @old_table_name NVARCHAR(500)
DECLARE @new_table_name NVARCHAR(500)

DECLARE @trunc_success NVARCHAR (3000)

SET @old_table_name = QUOTENAME('old.tb' + @year);
SET @new_table_name = QUOTENAME('new.tb' + @year);

SET @trunc_success = '
SELECT 
       CASE 
              WHEN EXISTS 
                     ( 
                            --This should no records
                            SELECT 
                            top 1
                             * 
                            FROM ' + @old_table_name + '
                            ) THEN ''Failed''
              ELSE ''Passed'' 
       END result 
UNION ALL 
SELECT 
       CASE 
              WHEN EXISTS 
                     ( 
                            --This should return no records
                            SELECT top 1 * 
                            FROM ' + @new_table_name + '
                ) THEN ''Failed''
              ELSE ''Passed'' 
       END'
print  @trunc_success
EXECUTE sp_executesql @trunc_success

1 Ответ

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

Имя вашей таблицы не 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)));

Если бы у вас действительно был объект с таким именем, я бы честно поставил под сомнение ваше здравомыслие.

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