2015-02-10 3 views
0

У меня есть столбец XML в моей таблице SQL Server 2008. То, что я пытаюсь сделать, заключается в том, что для данного параметра моя хранимая процедура вычеркивает любые пробелы (используя REPLACE) в параметре и использует это в критериях WHERE, но затем с использованием предложения XQuery exist также использует метод REPLACE для данных xml :Запрос данных XML в SQL Server с использованием замены в критериях

-- Add the parameters for the stored procedure here 
@PostCode varchar(20) = '' 
AS 
BEGIN 
    -- strip out any spaces from the post code param 
    SET @PostCode = REPLACE(@PostCode, ' ','') 

    SELECT TOP 1 * 
    FROM sd_LocalAuthorities 
    WHERE PostCodes.exist(N'REPLACE(/PostCodes/PostCode/text(), '' '','''')[. = sql:variable("@PostCode")]') = 1 
END 

Я получаю сообщение об ошибке при XQuery sd_LocalAuthorities.PostCodes.exist()

Там нет функции «{http://www.w3.org/2004/07/xpath-functions}: REPLACE()

при запуске процедуры. Есть ли альтернативы REPLACE() Я могу использовать для выделения пробелов только для этого критерия WHERE, я не хочу изменять таблицу.

+0

Функция Exist нуждается в выражении XQuery в качестве параметра, а не в функции T-SQL. Рабочий, но неэффективный метод заключается в том, чтобы использовать PostCodes как varchar, заменять двойные пробелы и отличать как xml. – EKOlog

+0

Спасибо за указатель Я пробовал это, и, как вы говорите, он не очень эффективен, он занимает 10 секунд плюс для выполнения запроса – user3783297

ответ

0

Существует функция XQuery «replace», но она недоступна в TSQL, где вы хотите ее использовать. В качестве альтернативного подхода вы можете вывести почтовые индексы из XML и выполнить замену на собственные значения. Что-то вроде этого;

declare @sd_LocalAuthorities table (id int, postcodes xml) 
declare @PostCode varchar(20); set @PostCode = 'BB11BB' 

insert @sd_LocalAuthorities values (1, N'<PostCodes><PostCode>AA1 1AA</PostCode></PostCodes>') 
insert @sd_LocalAuthorities values (2, N'<PostCodes><PostCode>BB1 1BB</PostCode></PostCodes>') 
insert @sd_LocalAuthorities values (3, N'<PostCodes><PostCode>CC1 1CC</PostCode></PostCodes>') 

select top 1 
    la.* 
from 
    @sd_LocalAuthorities la 
     cross apply la.postcodes.nodes('/PostCodes/PostCode') as t(c) 
where 
    replace(t.c.value('.', 'varchar(20)'), ' ', '') = @PostCode 

Этого подход является более точным, чем преобразование всего XML документа/фрагмента для VARCHAR, потому что он только выполняет замену на значениях почтового индекса. В зависимости от ваших обстоятельств индекс XML может помочь в производительности.

+0

Спасибо, хорошо работает, хотя на удивление он только слабее более эффективен, чем литье колонки в Varchar (Max) замените, а затем верните xml. – user3783297