1

У меня есть таблица базы данных с шаблоном html, отформатированная как «текст {var1} text {othervar}". Я хотел бы применить строку замены в более прагматично, чем:Множественный поиск и замена строк на SQL Server (для шаблонов)

set @template = replace(@template, '{var1}', field.value); 
set @template = replace(@template, '{othervar}', field.othervalue); 
-- notice I don't have matching template variables and data fields 

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

Я пришел к следующему, но я получил неправильный синтаксис возле TABLE. Я запустил это на Microsoft SQL Server версии 10.50.2500 (2008). БД была установлена ​​на 90 совместимости (2005), но даже после того, как я изменил ее на 100 (SQL Server 2008), я получил ту же ошибку.

CREATE FUNCTION applyTemplate 
(
    @subject nvarchar(max), 
    @replacements as TABLE (
    search nvarchar(64), 
    replacement nvarchar(max) 
) 
) 
RETURNS nvarchar(max) 
AS BEGIN 
    DECLARE @return nvarchar(max) 
    set @return = @subject 

    select @return = replace(@return, search, replacement) from @replacements 
    RETURN @return 
END 

SELECT applyTemplate(
    'Hello, {planet}! Welcome to the {galaxy}.', 
    (select '{planet}','World' union select '{galaxy}', 'MilkyWay') 
) 

Реальный запрос исходных данных происходит в функцию ApplyTemplate , вероятно, не будет поступать из союза, как это, и может быть коррелируется подзапрос ..

select 
    person.email, 
    applyTemplate(
    template.body, 
    (select n,v from person_vars pv where pv.person=person.id) 
) as body 
from template 
cross join person 
where template.id = 1 

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

+0

основе: http://msdn.microsoft.com/en-us/library/bb675163.aspx 'CREATE TYPE dbo.templateVarsType AS TABLE ( \t поиска NVARCHAR (64) первичный ключ, \t замена NVARCHAR (макс) ) ' Затем заменил второй параметр с' @replacements templateVarsTyp e READONLY 'но: SELECT dbo.applyTemplate ( 'Здравствуйте, {planet}! Добро пожаловать в {galaxy}., (выберите '{planet}', 'World' union '{galaxy}', 'MilkyWay') ) Msg 116, Level 16, State 1, Line 4 Только один выражение может быть указано в списке выбора, когда подзапрос не вводится с EXISTS. –

ответ

1
DECLARE @t AS templateVarsType 

INSERT INTO @t 
SELECT '{planet}','World' 
UNION 
SELECT '{galaxy}','MilkyWay' 

SELECT dbo.applyTemplate('Hello, {planet}! Welcome to the {galaxy}.' 
         , @t) 

Проверить эту скрипку http://sqlfiddle.com/#!3/edda3/10

+0

Это работает, хотя и не так гибко, как я надеялся. Можете ли вы посмотреть на http://sqlfiddle.com/#!3/eba56/13/0 для чего-то менее надуманного. Почему я не могу использовать коррелированный подзапрос как параметр table-valued-parameter (или я могу)? (Я дам вам ответ, но я надеялся на большее.) Я не понимаю, почему примеры, похоже, указывают на то, что вы можете использовать подзапрос в качестве параметра, но здесь вам нужно было сначала назначить его переменной (который предотвращает сравнение с внешними таблицами). Благодарю. –

+0

В этой скрипке я использовал запрос, как второй, который я представил в исходном вопросе. 'SELECT dbo.applyTemplate ('Hello, {planet}! Добро пожаловать в {galaxy}., (SELECT n, v from planet_variables где planet.id = planet_id) ) с планеты где id> 0' на основе 'CREATE TABLE planet (первичный ключ id int, имя varchar (64)) CREATE TABLE planet_variables (planet_id int, n varchar (64), v varchar (max)); Вставить в значения планет (1, 'Земля'), (2, 'Glep Glop'), вставить в значения планет_вариабелей (1, '{planet}', 'Earth'), (1, '{galaxy}', MilkyWay '), (2,' {planet} ',' Gleep Glop '), (2,' {galaxy} ',' Glopulon ') ' –

+0

Стоит также отметить, что я попытался заменить @t в списке параметров функции с 'cast ((SELECT n, v from planet_variables где planet.id = planet_id) как templateVarsType)' .. но не радость. –

0
-- Applying a template using a single replace 
DECLARE @return NVARCHAR(MAX) = 'Hello, {planet}! Welcome to the {galaxy}.'; 

SELECT @return = REPLACE(@return, [search], [replacement]) 
FROM 
(VALUES 
    ('{planet}', 'World') 
, ('{galaxy}', 'MilkyWay') 
) AS templateVars([search], [replacement]); 

SELECT @return; 
+2

Только ответы на код должны содержать несколько строк пояснений –

Смежные вопросы