2010-12-31 11 views

Odpowiedz

6

Zakładając SQL Server 2005 lub później, ten modyfikowany kod brane tutaj: http://www.kodyaz.com/articles/case-sensitive-sql-split-function.aspx

CREATE FUNCTION SpaceBeforeCap 
(
@str nvarchar(max) 
) 
returns nvarchar(max) 
as 
begin 

declare @i int, @j int 
declare @returnval nvarchar(max) 
set @returnval = '' 
select @i = 1, @j = len(@str) 

declare @w nvarchar(max) 

while @i <= @j 
begin 
if substring(@str,@i,1) = UPPER(substring(@str,@i,1)) collate Latin1_General_CS_AS 
begin 
    if @w is not null 
    set @returnval = @returnval + ' ' + @w 
    set @w = substring(@str,@i,1) 
end 
else 
    set @w = @w + substring(@str,@i,1) 
set @i = @i + 1 
end 
if @w is not null 
set @returnval = @returnval + ' ' + @w 

return ltrim(@returnval) 

end 

Można to wówczas nazywano tak jak sugerują powyżej.

+1

Zakłada się, że dane nie zawierają żadnych specjalnych znaków XML. Prawdopodobnie bezpieczniej jest po prostu zhakować funkcję bezpośrednio, aby wykonać konkatenację zamiast wstawiania do zmiennej tabeli. –

+0

@Martin - uzgodniony; Zmodyfikowałem to tak, aby zrobić proste połączenie. – LittleBobbyTables

1

CLR i wyrażeń regularnych sprawozdań lub 26 zastąpić wrażliwą na sprawy klauzulę sortowania i wykończenia.

11

Spowoduje to dodanie spacji tylko wtedy, gdy poprzedni i następny znak są małymi literami. W ten sposób "MyABCAnalysis" będzie "Moja analiza ABC".

Dodałem też czek na poprzednie miejsce. Ponieważ niektóre z naszych ciągów są prefiksem „GR_” a niektóre zawierają także podkreślenia, możemy użyć funkcji Replace następująco:

wybrać dbo.GR_SpaceBeforeCap (zastąpić („GR_ABCAnalysis_Test”, „_”,”„)) „GR ABC Analiza testu” zwraca

CREATE FUNCTION GR_SpaceBeforeCap (
    @str nvarchar(max) 
) 
returns nvarchar(max) 
as 
begin 

declare 
    @i int, @j int 
, @cp nchar, @c0 nchar, @c1 nchar 
, @result nvarchar(max) 

select 
    @i = 1 
, @j = len(@str) 
, @result = '' 

while @i <= @j 
begin 
    select 
     @cp = substring(@str,@i-1,1) 
    , @c0 = substring(@str,@i+0,1) 
    , @c1 = substring(@str,@i+1,1) 

    if @c0 = UPPER(@c0) collate Latin1_General_CS_AS 
    begin 
     -- Add space if Current is UPPER 
     -- and either Previous or Next is lower 
     -- and Previous or Current is not already a space 
     if @c0 = UPPER(@c0) collate Latin1_General_CS_AS 
     and (
       @cp <> UPPER(@cp) collate Latin1_General_CS_AS 
      or @c1 <> UPPER(@c1) collate Latin1_General_CS_AS 
     ) 
     and @cp <> ' ' 
     and @c0 <> ' ' 
      set @result = @result + ' ' 
    end -- if @co 

    set @result = @result + @c0 
    set @i = @i + 1 
end -- while 

return @result 
end 
+0

To działa dla mnie i mojego heterogenicznego środowiska, w którym mamy nazwę stylu Oracle wymieszaną z Camel Case. Często otrzymujemy kombinację nazw obiektów UNDERSCORES_ i_FirstLetterCapitalized. –

1

Inną strategią byłoby sprawdzić wartość aSCII każdego znaku:

create function SpaceBeforeCap 
(@str nvarchar(max)) 
returns nvarchar(max) 
as 
begin 
    declare @result nvarchar(max)= left(@str, 1), 
      @i int = 2 

    while @i <= len(@str) 
    begin 
    if ascii(substring(@str, @i, 1)) between 65 and 90 
     select @result += ' ' 
    select @result += substring(@str, @i, 1) 
    select @i += 1 
    end 

    return @result 
end 

/*** 
    SELECT dbo.SpaceBeforeCap('ThisIsATestString') 
**/ 
3

funkcja ta łączy wcześniejsze odpowiedzi. Selektywnie wybierz zachowanie sąsiadujących CAPS:

CREATE FUNCTION SpaceBeforeCap (
    @InputString NVARCHAR(MAX), 
    @PreserveAdjacentCaps BIT 
) 
RETURNS NVARCHAR(MAX) 
AS 
BEGIN 

DECLARE 
    @i INT, @j INT, 
     @previous NCHAR, @current NCHAR, @next NCHAR, 
     @result NVARCHAR(MAX) 

SELECT 
    @i = 1, 
     @j = LEN(@InputString), 
     @result = '' 

WHILE @i <= @j 
BEGIN 
    SELECT 
     @previous = SUBSTRING(@InputString,@i-1,1), 
       @current = SUBSTRING(@InputString,@i+0,1), 
       @next = SUBSTRING(@InputString,@i+1,1) 

    IF @current = UPPER(@current) COLLATE Latin1_General_CS_AS 
    BEGIN 
     -- Add space if Current is UPPER 
     -- and either Previous or Next is lower or user chose not to preserve adjacent caps 
     -- and Previous or Current is not already a space 
     IF @current = UPPER(@current) COLLATE Latin1_General_CS_AS 
     AND (
          @previous <> UPPER(@previous) COLLATE Latin1_General_CS_AS 
          OR @next <> UPPER(@next) collate Latin1_General_CS_AS 
          OR @PreserveAdjacentCaps = 0 
     ) 
     AND @previous <> ' ' 
     AND @current <> ' ' 
      SET @result = @result + ' ' 
    END 

    SET @result = @result + @current 
    SET @i = @i + 1 
END 

RETURN @result 
END 

GO 
SELECT dbo.SpaceBeforeCap('ThisIsASampleDBString', 1) 
GO 
SELECT dbo.SpaceBeforeCap('ThisIsASampleDBString', 0) 
Powiązane problemy