Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Wzorzec regex wewnątrz funkcji SQL Replace?

Możesz użyć PATINDEX, aby znaleźć pierwszy indeks wystąpienia wzorca (łańcucha). Następnie użyj STUFF, aby wstawić kolejny ciąg do dopasowanego wzorca (ciągu).

Przeprowadź pętlę przez każdy rząd. Zastąp każdy nielegalny znak tym, co chcesz. W twoim przypadku zamień nienumeryczne na puste. Wewnętrzna pętla występuje, gdy w bieżącej komórce znajduje się więcej niż jeden niedozwolony znak niż w pętli.

DECLARE @counter int

SET @counter = 0

WHILE(@counter < (SELECT MAX(ID_COLUMN) FROM Table))
BEGIN  

    WHILE 1 = 1
    BEGIN
        DECLARE @RetVal varchar(50)

        SET @RetVal =  (SELECT Column = STUFF(Column, PATINDEX('%[^0-9.]%', Column),1, '')
        FROM Table
        WHERE ID_COLUMN = @counter)

        IF(@RetVal IS NOT NULL)       
          UPDATE Table SET
          Column = @RetVal
          WHERE ID_COLUMN = @counter
        ELSE
            break
    END

    SET @counter = @counter + 1
END

Uwaga:to jednak jest powolne! Posiadanie kolumny varchar może mieć wpływ. Więc użycie LTRIM RTRIM może trochę pomóc. Niezależnie od tego jest powolny.

Kredyt trafia do tej odpowiedzi StackOverFlow.

EDITCredit trafia również do @srutzky

Edytuj (by @Tmdean)Zamiast robić jeden wiersz na raz, tę odpowiedź można dostosować do rozwiązania bardziej opartego na zbiorach. Nadal iteruje maksymalną liczbę znaków nienumerycznych w jednym wierszu, więc nie jest to idealne rozwiązanie, ale myślę, że powinno być akceptowalne w większości sytuacji.

WHILE 1 = 1 BEGIN
    WITH q AS
        (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n
        FROM Table)
    UPDATE Table
    SET Column = STUFF(Column, q.n, 1, '')
    FROM q
    WHERE Table.ID_Column = q.ID_Column AND q.n != 0;

    IF @@ROWCOUNT = 0 BREAK;
END;

Możesz również znacznie poprawić wydajność, jeśli utrzymasz kolumnę bitów w tabeli, która wskazuje, czy pole zostało już wyczyszczone. (NULL oznacza „Nieznany” w moim przykładzie i powinien być domyślną kolumną.)

DECLARE @done bit = 0;
WHILE @done = 0 BEGIN
    WITH q AS
        (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n
        FROM Table
        WHERE COALESCE(Scrubbed_Column, 0) = 0)
    UPDATE Table
    SET Column = STUFF(Column, q.n, 1, ''),
        Scrubbed_Column = 0
    FROM q
    WHERE Table.ID_Column = q.ID_Column AND q.n != 0;

    IF @@ROWCOUNT = 0 SET @done = 1;

    -- if Scrubbed_Column is still NULL, then the PATINDEX
    -- must have given 0
    UPDATE table
    SET Scrubbed_Column = CASE
        WHEN Scrubbed_Column IS NULL THEN 1
        ELSE NULLIF(Scrubbed_Column, 0)
    END;
END;

Jeśli nie chcesz zmieniać schematu, łatwo jest go dostosować do przechowywania wyników pośrednich w zmiennej o wartości tabeli, która na końcu jest stosowana do rzeczywistej tabeli.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wprowadzenie do OPENJSON z przykładami (SQL Server)

  2. DATEDIFF_BIG() Przykłady w SQL Server

  3. Używanie DBCC CLONEDATABASE do generowania schematu i tylko kopii statystyk bazy danych użytkownika w programie SQL Server 2014 z dodatkiem SP2

  4. CONVERT() w SQL Server

  5. Jak używać instrukcji IF/ELSE do aktualizacji lub tworzenia nowego wpisu węzła XML w Sql