Специальный SQL и встроенная функция, дающие разные результаты

В MS SQL Server 2012 SP1, когда я выполняю:

SELECT  rt.RoleId, ur.RoleName, app.ApplicationName
FROM    [TV_ClientPortal].[dbo].[UserRoleTie] rt
            JOIN [TV_ClientPortal].[dbo].[UserRoles] ur
                ON rt.RoleId = ur.RoleId
            JOIN [TV_ClientPortal].[dbo].[Applications] app
                ON app.ApplicationId = ur.ApplicationId
WHERE   rt.UserId = 255 AND
        ('SalesCRM' IS NULL OR app.ApplicationName = 'SalesCRM')

Я получаю один ряд. Теперь я написал встроенную функцию таким образом:

CREATE FUNCTION dbo.Func_GetRolesForUser 
(   
    @UserId int,
    @AppName varchar
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT  rt.RoleId, ur.RoleName, app.ApplicationName
    FROM    [TV_ClientPortal].[dbo].[UserRoleTie] rt
                JOIN [TV_ClientPortal].[dbo].[UserRoles] ur
                    ON rt.RoleId = ur.RoleId
                JOIN [TV_ClientPortal].[dbo].[Applications] app
                    ON app.ApplicationId = ur.ApplicationId
    WHERE   rt.UserId = @UserId AND
            (@AppName IS NULL OR app.ApplicationName = @AppName)
)
GO

Но когда я выполню

SELECT * FROM dbo.Func_GetRolesForUser(255, 'SalesCRM')

Я не получаю результатов. Есть идеи, почему это так? Я думал о проблемах с разрешениями, но, насколько мне известно, у меня есть полное разрешение на выполнение этой функции.

2 ответа

Решение

В SQL Server никогда не используйте varchar() без длины. Измените определение на что-то вроде:

CREATE FUNCTION dbo.Func_GetRolesForUser 
(   
    @UserId int,
    @AppName varchar(255)
)

И воссоздать функцию.

В этом контексте длина по умолчанию равна 1, поэтому значение передается как 'S',

Какова цель предложения "SalesCRM'NULL"? Вы можете просто переписать как

(app.ApplicationName IS NULL OR app.ApplicationName = 'SalesCRM')

Поэтому фильтр в коде вашей табличной функции будет:

(app.ApplicationName IS NULL OR app.ApplicationName = @AppNam)
Другие вопросы по тегам