#sql-server
#sql-сервер
Вопрос:
Пожалуйста, укажите способ преобразования snake_case в camelCase в SQL
Например:
created_by
last_updated_by
item
item_id
Предыдущие поля должны быть преобразованы как
createdBy
lastUpdatedBy
item
itemId
Комментарии:
1. Это непростая задача для SQL, который вообще не очень хорош в обработке строк. в SQL Server все еще хуже, у него нет надлежащей поддержки регулярных выражений. Вам потребуется какой-то итеративный или рекурсивный процесс, который кажется чрезмерно сложным для задачи, которую можно легко выполнить на стороне приложения.
Ответ №1:
SQL Server — не лучший инструмент для этой работы. Но если вы всегда используете лучший инструмент для каждой работы, у вас будет слишком много инструментов.
Вот краткий пример в TSQL с некоторыми каркасами, оставшимися в:
create or alter function ToCamelCase(@in nvarchar(128))
returns nvarchar(128)
as
/*
highlight and run to test cases
select dbo.ToCamelCase('last_updated_by')
select dbo.ToCamelCase('LAST')
select dbo.ToCamelCase(null)
select dbo.ToCamelCase('_LAST_UPDATED_BY_')
*/
--uncomment single-line comments for dev and to debug
--declare @in nvarchar(128) = 'last_updated_by'
begin
declare @i int = 1;
declare @len int = len(@in);
declare @rv nvarchar(128) = '';
declare @nextUpper bit = 0;
while @i <= @len
begin
--print(@i)
declare @c nchar(1);
set @c = substring(@in,@i,1);
--print(@c)
if @c = '_'
begin
set @nextUpper = 1;
set @i = @i 1;
continue;
end
else
begin
set @rv = @rv case when @nextUpper = 1 then upper(@c) else lower(@c) end;
set @i = @i 1;
set @nextUpper = 0;
continue;
end
end
--print(@rv)
return @rv
end
Ответ №2:
Вы могли бы использовать разделитель строк с учетом порядковой позиции, такой как DelimitedSplit8K_LEAD
, и разделить и перестроить. Это, вероятно, будет намного быстрее, чем итеративный процесс:
WITH CTE AS(
SELECT V.YourString,
CASE DS.ItemNumber WHEN 1 THEN DS.Item ELSE STUFF(DS.Item,1,1,UPPER(LEFT(DS.Item,1))) END AS Camel,
DS.ItemNumber
FROM (VALUES('created_by'),
('last_updated_by'),
('item'),
('item_id'))V(YourString)
CROSS APPLY dbo.DelimitedSplit8K_LEAD(V.YourString,'_') DS)
SELECT STRING_AGG(Camel,'') WITHIN GROUP (ORDER BY ItemNumber) AS CamelCase
FROM CTE
GROUP BY YourString;
Ответ №3:
Используйте функцию;
CREATE function [dbo].[CamelCase](@Text as varchar(8000))returns varchar(8000)as
begin
declare @Reset bit;
declare @Ret varchar(8000);
declare @i int;
declare @c char(1);
select @Reset = 1, @i=1, @Ret = '';
while (@i <= len(@Text))
select @c= substring(@Text,@i,1),
@Ret = @Ret case when @Reset=1 and @i > 1 then UPPER(@c) else LOWER(@c) end,
@Reset = case when @c like '[a-zA-Z]' then 0 else 1 end,
@i = @i 1
return replace(@Ret,'_','')
end