2016-02-02 6 views
3

У меня есть две таблицы A и B. A имеет идентификатор и строку с некоторой вложенной информацией для некоторого текста и идентификаторов из таблицы C, который не показанКак обновить строки в таблице SQL-сервера на основе запроса?

Aid| AString 
1 "<thing_5"><thing_6">" 
2 "<thing_5"><thing_6">" 

Bid|Cid|Aid 
    1 5 1 
    2 6 1 
    3 5 2 
    4 6 2 

Я понимаю, что это безумная структура, но это жизнь.

мне нужно обновить строки в A так, что вместо того, чтобы в Cid они имеют соответствующие Bid (связаны Aid и Bid спаривания)

Это даже то, что я должен думать делать в SQL. .. A имеет около 300 статей и B около 1200 так не то, что делают вручную

для ясности я хочу для B остаются теми же и A, наконец, выглядеть

Aid| AString 
1 "<thing_1"><thing_2">" 
2 "<thing_3"><thing_4">" 
+0

Может ли число в 'AString' кроме' cid'-х годов? –

+0

У вас есть все два Cids для каждой строки из таблицы A? –

+0

@TT. хорошо заметил. Там может быть :( – Loofer

ответ

1

Этот сценарий основан на генерации динамических операторов SQL для обновления таблицы, затем выполняет эти операторы.

  • Принимая во внимание, что cid «s находятся в thing_ и ":
  • Первый заменяет cid» S, используя заполнитель ($$$$$$ в данном случае), чтобы учесть тот факт, что cid „s и bid“ ы могут перекрывать друг друга (например, изменение 3-> 2, а затем 2-> 1)
  • Затем изменяет заполнители к надлежащему bid

CREATE TABLE #a(aid INT,astr VARCHAR(MAX)); 
INSERT INTO #a(aid,astr)VALUES(1,'<thing_5"><thing_6">'),(2,'<thing_5"><thing_6">'); 

CREATE TABLE #rep(aid INT,bid INT,cid INT); 
INSERT INTO #rep(bid,cid,aid)VALUES(5,6,1),(6,5,1),(3,5,2),(4,6,2); 

DECLARE @cmd NVARCHAR(MAX)=(
    SELECT 
     'UPDATE #a '+ 
     'SET astr=REPLACE(astr,''thing_'+CAST(r.cid AS VARCHAR(16))+'"'',''thing_$$$$$$'+CAST(r.cid AS VARCHAR(16))+'"'') '+ 
     'WHERE aid='+CAST(a.aid AS VARCHAR(16))+';' 
    FROM 
     (SELECT DISTINCT aid FROM #a AS a) AS a 
     INNER JOIN #rep AS r ON 
      r.aid=a.aid 
    FOR 
     XML PATH('') 
); 
EXEC sp_executesql @cmd; 

SET @cmd=(
    SELECT 
     'UPDATE #a '+ 
     'SET astr=REPLACE(astr,''thing_$$$$$$'+CAST(r.cid AS VARCHAR(16))+'"'',''thing_'+CAST(r.bid AS VARCHAR(16))+'"'') '+ 
     'WHERE aid='+CAST(a.aid AS VARCHAR(16))+';' 
    FROM 
     (SELECT DISTINCT aid FROM #a AS a) AS a 
     INNER JOIN #rep AS r ON 
      r.aid=a.aid 
    FOR 
     XML PATH('') 
); 
EXEC sp_executesql @cmd; 

SELECT * FROM #a; 

DROP TABLE #rep; 
DROP TABLE #a; 

Результат:

+-----+----------------------+ 
| aid |   astr   | 
+-----+----------------------+ 
| 1 | <thing_6"><thing_5"> | 
| 2 | <thing_3"><thing_4"> | 
+-----+----------------------+ 
+0

Удивительный ответ спасибо за вашу помощь ... Теперь, о чем эта «резервная копия», о которой вы говорите: D – Loofer

+0

@Loofer =) Хехехе что-то таинственное, о котором я только что читал. Пожалуйста! –

0

Вы можете сделать это с помощью SQL с чем-то вроде ниже. Это не было для меня ясно, как был связан с, но вы можете настроить его по мере необходимости ...

create table a (
Aid int null, 
AString varchar(25) null) 

insert into a values(1,'"<thing_5"><thing_6">"') 
insert into a values(2,'"<thing_5"><thing_6">"') 

create table b (
Aid int null, 
Bid int null, 
Cid int null) 

insert into b values(1,1,5) 
insert into b values(1,2,6) 
insert into b values(2,3,5) 
insert into b values(2,4,6) 

UPDATE Ax 
SET Ax.ASTRING = REPLACE(Ax.ASTRING, 'thing_' + cast(cID as varchar(1)),'thing_' + cast(BID as varchar(1))) 
FROM A Ax 
INNER JOIN Bx 
on ax.Aid=bx.Aid 
and Ax.AString like '%thing_' + cast(Cid as varchar(1)) + '%' 
+0

Оператор UPDATE может менять строку не более одного раза. Это никогда не сработает. –

+0

Спасибо @TT. Я писал это со своего телефона. Если вы запустите его дважды, он запустит первую замену в строке, а затем запустит ее второй раз, выполнив вторую замену.Я немного обновляю свой код. –

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