0
4

5 回答 5

1

这是实现它的功能:

create function f_test
(
@a varchar(max)

)
returns varchar(max)
as
begin
  set @a = lower(@a)
  while @a LIKE '%\_%' ESCAPE '\'
  begin
    select @a = stuff(@a, v, 2, upper(substring(@a, v+1,1)))
    from (select charindex('_', @a) v) a
  end
  return @a
end

例子:

select dbo.f_test( HRM_APPLICATION_DELAY_IN')

结果:

hrmApplicationDelayIn

要更新您的表,这里是一个如何使用函数编写语法的示例:

UPDATE <yourtable>
SET <yourcolumn> = dbo.f_test(col)
WHERE <yourcolumn> LIKE '%\_%' ESCAPE '\'
于 2012-10-08T07:37:33.763 回答
0

对于一个变量,这是矫枉过正,但我​​用它来演示一个模式

declare @str varchar(100) = 'HRM_APPLICATION_DELAY_IN';
;with c(one,last,rest) as (
  select cast(lower(left(@str,1)) as varchar(max)),
         left(@str,1), stuff(lower(@str),1,1,'')
  union all
  select one+case when last='_'
             then upper(left(rest,1))
             else left(rest,1) end,
         left(rest,1), stuff(rest,1,1,'')
  from c
  where rest > ''
)
select max(one)
from c;

可以扩展到表中的列

-- Sample table
declare @tbl table (
  id int identity not null primary key clustered,
  str varchar(100)
);
insert @tbl values
  ('HRM_APPLICATION_DELAY_IN'),
  ('HRM_APPLICATION_DELAY_OUT'),
  ('_HRM_APPLICATION_DELAY_OUT'),
  (''),
  (null),
  ('abc<de_fg>hi');

-- the query
;with c(id,one,last,rest) as (
  select id,cast(lower(left(str,1)) as varchar(max)),
         left(str,1), stuff(lower(str),1,1,'')
  from @tbl
  union all
  select id,one+case when last='_'
             then upper(left(rest,1))
             else left(rest,1) end,
         left(rest,1), stuff(rest,1,1,'')
  from c
  where rest > ''
)
select id,max(one)
from c
group by id
option (maxrecursion 0);

-- result
ID  COLUMN_1
1   hrm_Application_Delay_In
2   hrm_Application_Delay_Out
3   _Hrm_Application_Delay_Out
4   
5   (null)
6   abc<de_Fg>hi
于 2012-10-08T06:42:04.187 回答
0

我想向您展示我的漂亮而简单的解决方案。它使用 Tally 函数按模式分割字符串,在我们的例子中是通过下范围。要了解 Tally 功能,请阅读本文

所以,这就是我的计数功能的样子:

CREATE FUNCTION [dbo].[tvf_xt_tally_split](      
     @String NVARCHAR(max)
    ,@Delim   CHAR(1))
RETURNS  TABLE
as
return
    (

        WITH Tally AS (SELECT top (select isnull(LEN(@String),100)) n = ROW_NUMBER() OVER(ORDER BY [name]) from master.dbo.syscolumns)      
        (
            SELECT LTRIM(RTRIM(SUBSTRING(@Delim + @String + @Delim,N+1,CHARINDEX(@Delim,@Delim + @String + @Delim,N+1)-N-1))) Value, N as Ix
            FROM Tally
            WHERE N < LEN(@Delim + @String + @Delim)
            AND SUBSTRING(@Delim + @String + @Delim,N,1) = @Delim 
         )
    )

这个函数返回一个表,其中每一行代表@Delim 之间的字符串的一部分(在我们的例子中是在下范围之间)。剩下的工作很简单,只是结合了 LEFT、RIGHT、LEN、UPPER 和 LOWER 功能。

   declare @string varchar(max)
    set @string = ' HRM_APPLICATION_DELAY_IN'

    -- convert to lower case 
    set @string = LOWER(@string)
    declare @output varchar(max)

    -- build string 
    select @output = coalesce(@output + '_','') +
        UPPER(left(Value,1)) + RIGHT(Value, LEN(Value) - 1) 
            from dbo.tvf_xt_tally_split(@string, '_')

-- lower first char
select left(lower(@output),1) + RIGHT(@output, LEN(@output) - 1)
于 2012-10-08T07:08:54.697 回答
0

下面两个步骤可以解决问题,例如我使用 sys.table.user 可以使用任何一个

declare @Ret varchar(8000), @RetVal varchar(8000), @i int, @count int = 1;
declare @c varchar(10), @Text varchar(8000), @PrevCase varchar, @ModPrefix varchar(10);

DECLARE @FileDataTable TABLE(TableName varchar(200))

INSERT INTO @FileDataTable
select name FROM sys.tables where object_name(object_id) not like 'sys%'  order by name

SET @ModPrefix = 'Pur'


DECLARE crsTablesTruncIns CURSOR 
FOR select TableName FROM @FileDataTable
    OPEN crsTablesTruncIns
    FETCH NEXT FROM crsTablesTruncIns INTO @Text

    WHILE @@FETCH_STATUS = 0
    BEGIN


            SET @RetVal = '';

            select @i=1, @Ret = '';

               while (@i <= len(@Text))
               begin

                        SET @c = substring(@Text,@i,1)

                        --SET  @Ret = @Ret + case when @Reset=1 then UPPER(@c) else LOWER(@c)       


                        IF(@PrevCase = '_' OR @i = 1)
                            SET  @Ret = UPPER(@c)
                        ELSE
                            SET  @Ret = LOWER(@c)
                                   --@Reset = case when @c like '[a-zA-Z]' then 0 else 1 end,

                        if(@c like '[a-zA-Z]')
                            SET  @RetVal = @RetVal +  @Ret    

                        if(@c = '_')
                            SET @PrevCase = '_'
                        else
                            SET @PrevCase = ''

                        SET @i = @i +1

                end


            SET @RetVal = @ModPrefix + @RetVal

            print cast(@count as varchar) + ' ' + @RetVal 
            SET @count = @count + 1

            EXEC sp_RENAME @Text , @RetVal

            SET @RetVal = ''

    FETCH NEXT FROM crsTablesTruncIns INTO @Text
    END
CLOSE crsTablesTruncIns
DEALLOCATE crsTablesTruncIns
于 2012-10-08T09:32:35.483 回答
0
select 
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(lower('HRM_APPLICATION_DELAY_IN'),'_a','A'),'_b','B'),'_c','C'),'_d','D'),'_e','E'),'_f','F'),
'_g','G'),'_h','H'),'_i','I'),'_j','J'),'_k','K'),'_l','L'),
'_m','M'),'_n','N'),'_o','O'),'_p','P'),'_q','Q'),'_r','R'),
'_s','S'),'_t','T'),'_u','U'),'_v','V'),'_w','W'),'_x','X'),
'_y','Y'),'_z','Z'),'_','')
于 2012-10-08T06:33:08.170 回答