Я думаю, вы найдете, что следующее более эффективно:
IF OBJECT_ID('dbo.ProperCase') IS NOT NULL
DROP FUNCTION dbo.ProperCase
GO
CREATE FUNCTION dbo.PROPERCASE (
@str VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
SET @str = ' ' + @str
SET @str = 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( @str, ' 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')
RETURN RIGHT(@str, LEN(@str) - 1)
END
GO
Оператор замены может быть вырезан и вставлен непосредственно в запрос SQL. Это крайне уродливо, однако, заменив @str на интересующий вас столбец, вы не будете платить цену за неявный курсор, как вы платите за опубликованные таким образом файлы udf. Я считаю, что даже используя мой UDF, он гораздо эффективнее.
Да, и вместо генерации оператора замены используйте это:
-- Code Generator for expression
DECLARE @x INT,
@c CHAR(1),
@sql VARCHAR(8000)
SET @x = 0
SET @sql = '@str' -- actual variable/column you want to replace
WHILE @x < 26
BEGIN
SET @c = CHAR(ASCII('a') + @x)
SET @sql = 'REPLACE(' + @sql + ', '' ' + @c+ ''', '' ' + UPPER(@c) + ''')'
SET @x = @x + 1
END
PRINT @sql
В любом случае, это зависит от количества строк. Я бы хотел, чтобы вы просто делали s / \ b ([a-z]) / uc $ 1 /, ну да ладно, мы работаем с инструментами, которые у нас есть.
ПРИМЕЧАНИЕ: вам придется использовать это, как если бы вы использовали его как ... SELECT dbo.ProperCase (LOWER (column)), так как столбец в верхнем регистре. На самом деле он работает довольно быстро на моей таблице, состоящей из 5000 записей (даже не одной секунды), даже при меньшем.
В ответ на поток комментариев, касающихся интернационализации, я представляю следующую реализацию, которая обрабатывает каждый символ ascii, полагаясь только на реализацию SQL Server верхнего и нижнего уровней. Помните, что переменные, которые мы используем здесь, являются VARCHAR, что означает, что они могут содержать только значения ASCII. Чтобы использовать другие международные алфавиты, вы должны использовать NVARCHAR. Логика была бы аналогичной, но вам нужно было бы использовать UNICODE и NCHAR вместо ASCII и CHAR, а оператор замены был бы гораздо более громоздким ....
-- Code Generator for expression
DECLARE @x INT,
@c CHAR(1),
@sql VARCHAR(8000),
@count INT
SEt @x = 0
SET @count = 0
SET @sql = '@str' -- actual variable you want to replace
WHILE @x < 256
BEGIN
SET @c = CHAR(@x)
-- Only generate replacement expression for characters where upper and lowercase differ
IF @x = ASCII(LOWER(@c)) AND @x != ASCII(UPPER(@c))
BEGIN
SET @sql = 'REPLACE(' + @sql + ', '' ' + @c+ ''', '' ' + UPPER(@c) + ''')'
SET @count = @count + 1
END
SET @x = @x + 1
END
PRINT @sql
PRINT 'Total characters substituted: ' + CONVERT(VARCHAR(255), @count)
По сути, предпосылка метода my заключается в обмене предварительными вычислениями на эффективность. Полная реализация ASCII выглядит следующим образом:
IF OBJECT_ID('dbo.ProperCase') IS NOT NULL
DROP FUNCTION dbo.ProperCase
GO
CREATE FUNCTION dbo.PROPERCASE (
@str VARCHAR(8000))
RETURNS VARCHAR(8000)
AS
BEGIN
SET @str = ' ' + @str
SET @str = 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(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(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@str, ' 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'), ' š', ' Š'), ' œ', ' Œ'), ' ž', ' Ž'), ' à', ' À'), ' á', ' Á'), ' â', ' Â'), ' ã', ' Ã'), ' ä', ' Ä'), ' å', ' Å'), ' æ', ' Æ'), ' ç', ' Ç'), ' è', ' È'), ' é', ' É'), ' ê', ' Ê'), ' ë', ' Ë'), ' ì', ' Ì'), ' í', ' Í'), ' î', ' Î'), ' ï', ' Ï'), ' ð', ' Ð'), ' ñ', ' Ñ'), ' ò', ' Ò'), ' ó', ' Ó'), ' ô', ' Ô'), ' õ', ' Õ'), ' ö', ' Ö'), ' ø', ' Ø'), ' ù', ' Ù'), ' ú', ' Ú'), ' û', ' Û'), ' ü', ' Ü'), ' ý', ' Ý'), ' þ', ' Þ'), ' ÿ', ' Ÿ')
RETURN RIGHT(@str, LEN(@str) - 1)
END
GO