2015-11-17 2 views
0

У меня есть представление SQL, которое вызывает скалярную функцию со строковым параметром. Проблема состоит в том, что строка иногда имеет специальные символы, которые приводят к сбою функции.Escape SQL function string параметр в запросе

Вид запроса выглядит следующим образом:

SELECT TOP (100) PERCENT 
    Id, Name, StartDate, EndDate 
    ,dbo.[fnGetRelatedInfo] (Name) as Information 
FROM dbo.Session 

Функция выглядит следующим образом:

ALTER FUNCTION [dbo].[fnGetRelatedInfo](@Name varchar(50)) 
RETURNS varchar(200) 
AS 
BEGIN 
    DECLARE @Result varchar(200) 

    SELECT @Result = '' 

    SELECT @Result = @Result + Info + CHAR(13)+CHAR(10) 
    FROM [SessionInfo] 
    WHERE SessionName = @Name 

    RETURN @Result 
END 

Как избежать значение имени, так что будет работать, когда передаются функции?

+0

что такое специальные символы? Какая ошибка вы получаете? –

ответ

1

Я предполагаю, что проблема заключается в символах не-Юникод в dbo.Session.Name. Поскольку параметр функции равен VARCHAR, он будет содержать только символы Юникода, поэтому символы, отличные от юникода, теряются при передаче функции. Решением для этого было бы изменить параметр NVARCHAR(50).

Однако, если вы заботитесь о производительности, и, что еще важнее, последовательные, надежные результаты немедленно прекращают использовать эту функцию. Alter ваш взгляд просто:

SELECT s.ID, 
     s.Name, 
     s.StartDate, 
     s.EndDate, 
     ( SELECT si.Info + CHAR(13)+CHAR(10) 
      FROM SessionInfo AS si 
      WHERE si.SessionName = s.Name 
      FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') AS Information 
FROM dbo.Session AS s; 

Использование переменной конкатенации может привести к неожиданным результатам, которые зависят от внутренних путей плана выполнения. Поэтому я бы немедленно решил это решение. Мало того, характер RBAR скалярного UDF означает, что это не будет хорошо масштабироваться.

Различные способы выполнения этой группировки состоят из benchmarked here, где CLR на самом деле является победителем, но это не всегда вариант.

+0

Спасибо за дополнительное объяснение. Я принял ваш совет и удалил функцию. – sreimer