2016-11-30 2 views
1

Ich möchte eine SQL-UPDATE-Abfrage verwenden, um alles mit beginnt mit „http://example.combis zum nächsten Doppel Zitat mit „http://new-example.com“ zu ersetzen. Ich möchte auch alle Inhalte nach diesem doppelten Zitat beibehalten.MS SQL Ersetzen vollständige Zeichenfolge basiert auf teilweise Übereinstimmung

Zum Beispiel dieses:

ID | CONTENT 
-------------- 
1 | Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more. 
2 | Read our <a href="http://example.com/terms">Terms</a> by clicking here. 

würde:

ID | CONTENT 
-------------- 
1 | Visit our <a href="http://new-example.com">About Us Page</a> to learn more. 
2 | Read our <a href="http://new-example.com">Terms</a> by clicking here. 

I SQLServer 2012 für diese Operation mit bin.

+0

Was ist der Datentyp und die Länge der CONTENT-Spalte? –

+0

Wenn es varchar (max) oder nvarchar (max) war, verwenden Sie Aktualisieren mit.WRITE (Ausdruck, @ Offset, @ Länge) –

Antwort

3

können Sie

  • PATINDEX verwenden den Start der URL zu finden,
  • CHARINDEX den Schlusskurs und
  • STUFF zu finden, um den Inhalt zu ersetzen.

Code:

UPDATE myTable 
    SET content = STUFF(content, 
         PATINDEX('%http://example.com%"%', content), 
         CHARINDEX('"', content, PATINDEX('%http://example.com%"%', content)) - PATINDEX('%http://example.com%"%', content), 
         'http://new-example.com') 
WHERE PATINDEX('%http://example.com%"%', content) > 0; 

Vollarbeitsbeispiel mit Testdaten:

CREATE TABLE #test (content nvarchar(max)); 
INSERT INTO #test VALUES ('Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more.'); 
INSERT INTO #test VALUES ('Read our <a href="http://example.com/terms">Terms</a> by clicking here.'); 
INSERT INTO #test VALUES ('Some other text'); 

UPDATE #test 
    SET content = STUFF(content, 
         PATINDEX('%http://example.com%"%', content), 
         CHARINDEX('"', content, PATINDEX('%http://example.com%"%', content)) - PATINDEX('%http://example.com%"%', content), 
         'http://new-example.com') 
WHERE PATINDEX('%http://example.com%"%', content) > 0; 

SELECT * FROM #test; 

DROP TABLE #test; 

Eingang:

Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more. 
Read our <a href="http://example.com/terms">Terms</a> by clicking here. 
Some other text 

Ausgang:

Visit our <a href="http://new-example.com">About Us Page</a> to learn more. 
Read our <a href="http://new-example.com">Terms</a> by clicking here. 
Some other text 

Verbesserungsvorschlag:

  • Wenn es Sie stört, dass die gleiche PATINDEX Ausdruck viermal wiederholt (es würde mich stören), wickeln Sie es in einem WAK und den CTE in der UPDATE-Anweisung beizutreten.
+1

genial, ich tippte eine Antwort über die Verwendung von Update WRITE (Ausdruck, @ Offset, @ Länge), aber ich war fest mit der genauen Länge. glücklicher Code. –

+0

Toll Ich mag das, +1 – Shnugo

2

Sie könnten diese auf XML Basis lösen:

DECLARE @tbl TABLE(ID INT, CONTENT VARCHAR(MAX)); 
INSERT INTO @tbl VALUES 
(1,'Visit our <a href="http://example.com/about-us">About Us Page</a> to learn more.') 
,(2,'Read our <a href="http://example.com/terms">Terms</a> by clicking here.'); 

DECLARE @ReplaceWith VARCHAR(100)='http://new-example.com'; 

WITH UpdateableCTE AS 
(
    SELECT ID 
      ,CONTENT 
      ,CAST 
      (
       CAST('<root>' + CONTENT + '</root>' AS XML).query 
       (N' 
        <r> 
        {(root/text())[1]} 
        <a href="{sql:variable("@ReplaceWith")}"> 
        {(/root/a/text())[1]} 
        </a> 
        {(root/text())[2]} 
        </r> 
       ') AS varchar(MAX) 
      ) AS NewContent 
    FROM @tbl 
) 
UPDATE UpdateableCTE SET CONTENT=SUBSTRING(NewContent,4,LEN(NewContent)-7); 

SELECT * FROM @tbl; 

Kurze Erklärung: eine <root> am Anfang Hinzufügen und eine </root> bis das Ende Ihrer Snippets gültige XML transformiert. Die XML-Methode .query ermöglicht die Verwendung von FLWOR-Code. Das angegebene Beispiel beginnt mit einem Stammknoten <r>, liest die erste text() und fügt dann das <a> -Element mit dem Attribut href hinzu, das mit dem Wert der Variablen sql: gefüllt ist. Dann gibt es die text() innerhalb <a>, die schließende </a> und der zweite Text des Wurzelknotens.

Das zurückgegebene XML wird in VARCHAR umgewandelt und SUBSTRING wird verwendet, um die <r>...</r> zu entfernen.

+0

Schöne Idee. Wie funktioniert das? – Heinzi

+0

@Heinzi, nur eine Erklärung hinzugefügt ... – Shnugo

Verwandte Themen