Почему NVarchar (MAX) не может выполнить полный динамический запрос с использованием SP_ExecuteSQL? - PullRequest
0 голосов
/ 22 сентября 2018

Я создал хранимую процедуру, которая будет иметь два запроса, эти два запроса обновят записи в двух таблицах.

Итак, я упомяну, что она показывает

Моя процедура похожа на

ALTER PROC UpdateMissingItemONPoe 
    @StoreID INT,
    @Name VARCHAR(20)
AS
BEGIN
    DECLARE @UpdateRec NVARCHAR(MAX) = '';
    DECLARE @StoreIP SYSNAME = ''

    SET @StoreIP = CASE @StoreID 
                      WHEN 1111 THEN '[192.168.1.45].[Store1].[dbo]'
                      WHEN 2222 THEN '[192.168.2.45].[Store2].[dbo]'
                      WHEN 3333 THEN '[192.168.3.45].[Store3].[dbo]'
                   END
    SET @UpdateRec = N' IF((SELECT NameID from '+@StoreIP+'.Details WHERE Name = '''+@Name+''') = 2 )
BEGIN
    INSERT INTO ' + @StoreIP + '.PurchaseOrderEntry(
            /*  InsertField Name  */
        )

        select
            Name,
            Standard,
            Department,
            Category,
            SubDescription,
            Rank
        from
            '+@StoreIP+'.Details 
        where
            Name = '''+@Name+'''

        INSERT INTO '+@StoreIP+'.HeadQuarter(
            /*  InsertField Name  */
        )
        select
            Name,
            Standard,
            Department,
            Category,
            SubDescription,
            Rank
        from
            '+@StoreIP+'.Details 
        where
            Name = '''+@Name+'''
    END'

    print @UpdateRec
    EXEC sp_executesql @UpdateRec
END

Когда я выполняю эту хранимую процедуру, сообщение об ошибке не отображается.Но этот динамический запрос не имеет полного запроса при печати.

Напечатанный запрос похож на

INSERT INTO '+@StoreIP+'.PurchaseOrderEntry(
    /*  InsertField Name  */
)

select
    Name,
    Standard,
    Department,
    Category,
    SubDescription,
    Rank
from
    '+@StoreIP+'.Details 
where
    Name = '''+@Name+'''

INSERT INTO '+@StoreIP+'.HeadQuarter(
    /*  InsertField Name  */
)

select
    Name,
    Standard,
    Department,
    Category,     

Остальные строки отсутствуют

Ответы [ 3 ]

0 голосов
/ 22 сентября 2018

Ваш запрос определенно превышает 4000 символов.

измените инструкцию SET на

SET @UpdateRec = CONVERT(NVARCHAR(MAX), '') + N' IF(('

, это приведет к тому, что строка запроса N' IF ((... будет преобразована в nvarchar (max).

0 голосов
/ 23 сентября 2018

Раньше SQL Server использовал для преобразования таких операторов из нескольких частей в nvarchar (4000), если эти части не были явно преобразованы в тип nvarchar (max).

То есть, если у вас была переменная

DECLARE @UpdateRec NVARCHAR(MAX) = '';

Затем использовался синтаксис этого типа

SET @UpdateRec = N' IF((SELECT NameID from '+@StoreIP+'.Details WHERE
 Name = '''+@Name+''') = 2 ) BEGIN
 INSERT INTO ' + @StoreIP + '.PurchaseOrderEntry( (...)'

Результат будет преобразован тихо в nvarchar (4000) и усечет любое превышениесимволы без предупреждения.

0 голосов
/ 22 сентября 2018

Я бы переписал его как:

ALTER PROC UpdateMissingItemONPoe 
    @StoreID INT,
    @Name VARCHAR(20)
AS
BEGIN
    DECLARE @UpdateRec NVARCHAR(MAX) = N'';
    DECLARE @StoreIP NVARCHAR(128) = N'';

    SET @StoreIP = CASE @StoreID 
                      WHEN 1111 THEN '[192.168.1.45].[Store1].[dbo]'
                      WHEN 2222 THEN '[192.168.2.45].[Store2].[dbo]'
                      WHEN 3333 THEN '[192.168.3.45].[Store3].[dbo]'
                   END;

    SET @UpdateRec = N' IF((SELECT NameID from <@StoreIP>.Details 
                           WHERE Name = @Name) = 2 )
BEGIN
    INSERT INTO <StoreIP>.PurchaseOrderEntry(
            /*  InsertField Name  */
        )

        select
            Name,
            Standard,
            Department,
            Category,
            SubDescription,
            Rank
        from
            <@StoreIP>.Details 
        where
            Name = @Name

        INSERT INTO <@StoreIP>.HeadQuarter(
            /*  InsertField Name  */
        )
        select
            Name,
            Standard,
            Department,
            Category,
            SubDescription,
            Rank
        from
            <@StoreIP>.Details 
        where
            Name = @Name
    END';

   SET @UpdateRec = REPLACE(@UpadteRec, N'<@StoreIP>', @StoreIp);

    print @UpdateRec
    EXEC sp_executesql @UpdateRec, N'@Name NVARCHAR(20)', @Name;
END

Использование параметризованного динамического SQL и обмен имени таблицы с использованием REPLACE вместо конкатенации.

...