2010-12-08 3 views
6

Можно ли преобразовать текст из столбца таблицы в SQL Server в PascalCase только с использованием правильного кода SQL?Преобразование текста в PascalCase

TABLE DEFINITION 
---------------------- 
ID int 
CITTA varchar(50) 
PROV varchar(50) 
CAP varchar(50) 
COD varchar(50) 

Поле, содержащее текст для конвертации - CITTA. Он содержит все заглавные значения, такие как «ABANO TERME», «ROMA» и т. Д. Слова ограничены пробелом.

EDIT

Я забыл упомянуть, что некоторые слова имеют характер акцент в нем '. Этот символ можно найти либо в конце слова, либо посередине.

EDIT 2:

Некоторых причуд найдены на результатах:

  • Если у меня есть имя, как "ISOLA Бальба" это имя переводятся на "IsolaBalba" (правильный случай, но пропущенное пространство)
  • Если у меня есть имя, как «ISOLA D'ASTI» это преобразуется в «IsolaD'asti» (пропущенное пространство, как и раньше, и неправильный случай. в этом случае правильный результат «Isola D'Asti»

Не могли бы вы дать мне несколько советов по этой небольшой проблеме?

+2

Возможно. Не уверен, что SQL - лучшая среда для этого, но если вы дадите пример ввода и вывода, я пойду! Являются ли слова в настоящее время разделены пробелом? т. е. нужно ли преобразовать `pascal case` в` PascalCase`? – 2010-12-08 00:17:21

+0

@ Мартин: спасибо за ваш быстрый ответ. посмотрите на мой вопрос, отредактируйте, пожалуйста, – Lorenzo 2010-12-08 00:28:06

+0

@Lorenzo - do UDFs считаются правильным кодом SQL для ваших целей? – 2010-12-08 00:29:56

ответ

4
DECLARE @T TABLE 
(
ID INT PRIMARY KEY, 
CITTA VARCHAR(50) 
) 
INSERT INTO @T 
SELECT 1, 'ABANO TERME' UNION ALL SELECT 2, 'ROMA' UNION ALL SELECT 3, 'ISOLA D''ASTI'; 

IF OBJECT_ID('tempdb..#HolderTable') IS NOT NULL 
    DROP TABLE #HolderTable 

CREATE TABLE #HolderTable 
(
Idx INT IDENTITY(1,1) PRIMARY KEY, 
ID INT, 
Word VARCHAR(50) 
) 

CREATE NONCLUSTERED INDEX ix ON #HolderTable(ID) 
; 

WITH T1 AS 
(
SELECT ID, CAST(N'<root><r>' + REPLACE(REPLACE(CITTA, '''', '''</r><r>'), ' ', ' </r><r>') + '</r></root>' AS XML) AS xl 
FROM @T 
) 
INSERT INTO #HolderTable 
SELECT ID, 
     r.value('.','NVARCHAR(MAX)') AS Item 
FROM T1 
CROSS APPLY 
xl.nodes('//root/r') AS RECORDS(r) 

SELECT 
     ID, 
     (SELECT STUFF(LOWER(Word),1,1,UPPER(LEFT(Word,1))) FROM #HolderTable WHERE [@T].ID = #HolderTable.ID ORDER BY Idx FOR XML PATH('')) 
FROM @T [@T] 
2

Попробуйте выполнить функцию ниже (при необходимости отрегулируйте тип строки). Просто не используйте это в предложении WHERE - и рассмотрите разницу в производительности в другом месте. 12345678 - это просто какое-то сколь угодно большое значение, которое вы, возможно, захотите заменить чем-то более подходящим!

CREATE FUNCTION dbo.ufn_PascalCase(@str AS VARCHAR(MAX)) RETURNS VARCHAR(MAX) 
BEGIN 
    SET @str = LOWER(@str) 

    DECLARE @result VARCHAR(MAX) = '' 

    DECLARE @spaceIndex INTEGER = CHARINDEX(' ', @str) 
    WHILE @spaceIndex > 0 
    BEGIN 
     SET @result += UPPER(SUBSTRING(@str, 1, 1)) + SUBSTRING(@str, 2, @spaceIndex - 2) 
     SET @str = SUBSTRING(@str, @spaceIndex + 1, 12345678) 
     SET @spaceIndex = CHARINDEX(' ', @str) 
    END 

    SET @result += UPPER(SUBSTRING(@str, 1, 1)) + SUBSTRING(@str, 2, 12345678) 

    RETURN @result 
END 
3

Я предлагаю вам попробовать код, который я разместил в блоге некоторое время назад. Я подозреваю, что он удовлетворит ваши требования очень хорошо, а также будет работать лучше, чем многие другие методы.

SQL Server Proper Case Function

CREATE FUNCTION dbo.Proper(@DATA VARCHAR(8000)) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 
    DECLARE @Position INT 

    SELECT @DATA = STUFF(LOWER(@DATA), 1, 1, UPPER(LEFT(@DATA, 1))), 
     @Position = PATINDEX('%[^a-zA-Z][a-z]%', @DATA COLLATE Latin1_General_Bin) 

    WHILE @Position > 0 
    SELECT @DATA = STUFF(@DATA, @Position, 2, UPPER(SUBSTRING(@DATA, @Position, 2))), 
      @Position = PATINDEX('%[^a-zA-Z][a-z]%', @DATA COLLATE Latin1_General_Bin) 

    RETURN @DATA 
END 

Эта функция немного быстрее, чем большинство, потому что только петли один раз для каждого слова, которое требует заглавной буквы.

Смежные вопросы