SQL Server: Buat semua kasus UPPER menjadi Kasus yang Tepat / Kasus Judul


97

Saya memiliki tabel yang diimpor sebagai semua UPPER CASE dan saya ingin mengubahnya menjadi Kasus yang Tepat. Skrip apa yang pernah kalian gunakan untuk menyelesaikan ini?


4
Perlu diingat bahwa mengubah teks huruf besar dengan benar ke teks huruf besar mungkin memerlukan koreksi manual dalam beberapa kasus. Dengan nama, misalnya: Saya tidak menghargai aplikasi yang salah mengeja nama saya.
Dave DuPlantis

2
Tidak akan ada fungsi di bumi yang akan mendapatkan hak 'DAVE DUPLANTIS'. Uppercasing data adalah WTF yang besar itu sendiri, karena sebagian besar waktu itu hanya masalah presentasi.
Tomalak

1
Saya kenal seorang Macdonald yang menjadi marah ketika dia ditata sebagai MacDonald. Dan saya juga akan menghargai casing O'Keefe yang tepat.
DOK

@Tomalak: benar, itulah mengapa Anda harus menerima data kasus campuran dan menyimpannya begitu pilihan ada di tangan Anda. Setuju sepenuhnya tentang bagian WTF ... terutama jika Anda menerima karakter "internasional".
Dave DuPlantis

Ini juga masalah budaya. Menurut pengalaman saya, orang Inggris dan Prancis terbiasa menggunakan huruf besar di mana pun mereka mendapat kesempatan. Saya hanya tidak mengerti, itu tidak menambah nilai.
Tomalak

Jawaban:


91

Inilah UDF yang akan melakukan trik ...

create function ProperCase(@Text as varchar(8000))
returns varchar(8000)
as
begin
  declare @Reset bit;
  declare @Ret varchar(8000);
  declare @i int;
  declare @c char(1);

  if @Text is null
    return null;

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

  while (@i <= len(@Text))
    select @c = substring(@Text, @i, 1),
      @Ret = @Ret + case when @Reset = 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 @Ret
end

Anda masih harus menggunakannya untuk memperbarui data Anda.


15
Ini akan meledak untuk masukan non-Inggris.
Tomalak

Terima kasih! bekerja pertama kali pergi, bahkan di Azure SQL Server :)
Aaron

bisakah saya bertanya ke database dan tabel apa ini?
v3nt

2
Mencoba ini dengan SQL Server 2008 dan semua jenis aksen, bekerja seperti pesona. Itu sebenarnya tergantung pada pemeriksaan
Baptiste

Terima kasih! Ini memberikan hasil seperti yang diharapkan.
Palak Patel

109

Fungsi ini:

  • "Kasus yang Benar" semua kata "KASUS ATAS" yang dibatasi oleh spasi
  • biarkan "kata huruf kecil" saja
  • berfungsi dengan baik bahkan untuk huruf non-Inggris
  • portabel karena tidak menggunakan fitur mewah dari versi server SQL terbaru
  • dapat dengan mudah diubah untuk menggunakan NCHAR dan NVARCHAR untuk dukungan unicode, serta panjang parameter yang Anda inginkan
  • definisi ruang putih dapat dikonfigurasi
CREATE FUNCTION ToProperCase(@string VARCHAR(255)) RETURNS VARCHAR(255)
AS
BEGIN
  DECLARE @i INT           -- index
  DECLARE @l INT           -- input length
  DECLARE @c NCHAR(1)      -- current char
  DECLARE @f INT           -- first letter flag (1/0)
  DECLARE @o VARCHAR(255)  -- output string
  DECLARE @w VARCHAR(10)   -- characters considered as white space

  SET @w = '[' + CHAR(13) + CHAR(10) + CHAR(9) + CHAR(160) + ' ' + ']'
  SET @i = 1
  SET @l = LEN(@string)
  SET @f = 1
  SET @o = ''

  WHILE @i <= @l
  BEGIN
    SET @c = SUBSTRING(@string, @i, 1)
    IF @f = 1 
    BEGIN
     SET @o = @o + @c
     SET @f = 0
    END
    ELSE
    BEGIN
     SET @o = @o + LOWER(@c)
    END

    IF @c LIKE @w SET @f = 1

    SET @i = @i + 1
  END

  RETURN @o
END

Hasil:

dbo.ToProperCase('ALL UPPER CASE and    SOME lower ÄÄ ÖÖ ÜÜ ÉÉ ØØ ĈĈ ÆÆ')
-----------------------------------------------------------------
All Upper Case and      Some lower Ää Öö Üü Éé Øø Cc Ææ

1
Ini jelas merupakan solusi ramah paling internasional. Ini memiliki suara saya. Satu-satunya asumsi di sini adalah bahwa spasi memisahkan kata.
Cervo

3
Mungkinkah indeks harus dimulai dari 1? Substring pertama (, 0,1) mengembalikan <empty>. Aku berlari SQLServer2005
Januari

10
Anda mungkin harus menyertakan apostrof sebagai karakter spasi putih secara default sehingga nama seperti O'DONNELLtidak akan berubah menjadi O'donnell.
JustinStolle

2
@Tomalak variabel @i harus dimulai dari satu, jika tidak, spasi akan ditambahkan ke output
Jakub

5
Fungsi kecil yang luar biasa. Bukan berarti OP yang memintanya, tetapi jika ada yang ingin mengubahnya sehingga tidak mengabaikan kata-kata yang sudah huruf kecil, dan mengubahnya juga, misalnya "tom bombadil" menjadi "Tom Bombadil", ubah saja satu baris ini - SET @o = @o + @cuntuk SET @o = @o + UPPER(@c). =)
NateJ

42
UPDATE titles
  SET title =
      UPPER(LEFT(title, 1)) +
        LOWER(RIGHT(title, LEN(title) - 1))

http://sqlmag.com/t-sql/how-title-case-column-value


9
FYI ini berfungsi untuk nilai kata tunggal, tetapi tidak untuk beberapa nilai kata. Jadi, "Carolina Utara" menjadi "Carolina Utara", bukan "Carolina Utara".
molaro

4
+1 sebagai solusi kata tunggal sederhana yang bekerja dengan baik untuk saya. Satu-satunya - Anda bisa mendapatkan kesalahan jika titlekosong.
Serg

@molaro melakukan pemisahan spasi dan mengoperasikannya dengan setiap kata satu per satu. Solusi yang bagus tetapi sedikit membatasi panjang kemungkinan. Untuk pemirsa masa depan, mungkin ingin membagi terminator kalimat Anda dan Kasus Pertama kata pertama dalam kalimat.
GoldBishop

1
Tambahkan WHERE title IS NOT NULLke bagian akhir untuk menyelesaikan masalah @Serg.
Paul

@Serg Saya mengedit kodenya sehingga tidak berjalan pada kesalahan pada string panjang nol menggunakan SUBSTRINGalih-alihRIGHT
robotik

18

Jika Anda dapat mengaktifkan CLR di SQL Server (membutuhkan 2005 atau lebih baru) maka Anda dapat membuat fungsi CLR yang menggunakan fungsi bawaan TextInfo.ToTitleCase yang memungkinkan Anda membuat cara sadar budaya untuk melakukan ini hanya dalam beberapa baris kode.


Saya harus memilih di sini juga. TI aman secara internasional dan menggunakan perpustakaan orang lain yang mungkin penuh dengan segala macam pemeriksaan. Anda tidak bisa salah di sini :)
Cervo

8

Saya tahu ini adalah posting terlambat di utas ini tetapi, layak untuk dilihat. Fungsi ini bekerja untuk saya setiap saat. Jadi terpikir untuk membagikannya.

CREATE FUNCTION [dbo].[fnConvert_TitleCase] (@InputString VARCHAR(4000) )
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE @Index INT
DECLARE @Char CHAR(1)
DECLARE @OutputString VARCHAR(255)

SET @OutputString = LOWER(@InputString)
SET @Index = 2
SET @OutputString = STUFF(@OutputString, 1, 1,UPPER(SUBSTRING(@InputString,1,1)))

WHILE @Index <= LEN(@InputString)
BEGIN
    SET @Char = SUBSTRING(@InputString, @Index, 1)
    IF @Char IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&','''','(')
    IF @Index + 1 <= LEN(@InputString)
BEGIN
    IF @Char != ''''
    OR
    UPPER(SUBSTRING(@InputString, @Index + 1, 1)) != 'S'
    SET @OutputString =
    STUFF(@OutputString, @Index + 1, 1,UPPER(SUBSTRING(@InputString, @Index + 1, 1)))
END
    SET @Index = @Index + 1
END

RETURN ISNULL(@OutputString,'')
END

Tes panggilan:

select dbo.fnConvert_TitleCase(Upper('ÄÄ ÖÖ ÜÜ ÉÉ ØØ ĈĈ ÆÆ')) as test
select dbo.fnConvert_TitleCase(upper('Whatever the mind of man can conceive and believe, it can achieve. – Napoleon hill')) as test

Hasil:

masukkan deskripsi gambar di sini


Dapatkah Anda menjelaskan mengapa lebih baik daripada fungsi ToProperCase Tomalak stackoverflow.com/questions/230138/… ?
Michael Freidgeim

1
Berdasarkan contoh yang diberikan dengan jawaban ini dan Tomalak bersama dengan deskripsi Tomalak tentang apa yang dilakukannya ("tinggalkan kata huruf kecil saja") jawaban ini lebih baik. Saya tidak memverifikasi Tomalak, tetapi jawaban ini melakukan Masukan Kasus yang Benar (sejauh kebutuhan saya dapat memverifikasi). "Kapitalisasi yang tepat adalah teks apa pun yang ditulis dengan setiap huruf pertama dari setiap kata yang menggunakan huruf besar." - computerhope.com/jargon/p/proper-case.htm
Morvael

8

Saya agak terlambat dalam permainan ini, tapi saya yakin ini lebih fungsional dan bekerja dengan semua bahasa, termasuk Rusia, Jerman, Thailand, Vietnam dll. Huruf besar akan menjadi huruf besar setelah 'atau - atau. atau (atau) atau spasi (jelas :).

CREATE FUNCTION [dbo].[fnToProperCase]( @name nvarchar(500) )
RETURNS nvarchar(500)
AS
BEGIN
declare @pos    int = 1
      , @pos2   int

if (@name <> '')--or @name = lower(@name) collate SQL_Latin1_General_CP1_CS_AS or @name = upper(@name) collate SQL_Latin1_General_CP1_CS_AS)
begin
    set @name = lower(rtrim(@name))
    while (1 = 1)
    begin
        set @name = stuff(@name, @pos, 1, upper(substring(@name, @pos, 1)))
        set @pos2 = patindex('%[- ''.)(]%', substring(@name, @pos, 500))
        set @pos += @pos2
        if (isnull(@pos2, 0) = 0 or @pos > len(@name))
            break
    end
end

return @name
END
GO

Ini bekerja dengan baik kecuali bahwa "rumah jack" menjadi "Rumah Jack"
Damien

2
Jack's House bukanlah nama seseorang. O'Brian, O'Connell adalah nama :) Jika Anda tidak berurusan secara eksklusif dengan nama orang, perubahan diperlukan.
Alansoft

3

Jika Anda berada di SSIS mengimpor data yang memiliki cased campuran dan perlu melakukan pencarian pada kolom dengan kapitalisasi yang tepat, Anda akan melihat bahwa pencarian gagal saat sumber dicampur dan sumber pencarian sesuai. Anda juga akan melihat bahwa Anda tidak dapat menggunakan fungsi kanan dan kiri SSIS untuk SQL Server 2008r2 untuk kolom turunan. Inilah solusi yang berhasil untuk saya:

UPPER(substring(input_column_name,1,1)) + LOWER(substring(input_column_name, 2, len(input_column_name)-1))

2

Berikut adalah versi yang menggunakan tabel urutan atau angka daripada loop. Anda dapat mengubah klausa WHERE untuk menyesuaikan aturan pribadi Anda tentang kapan harus mengubah karakter menjadi huruf besar. Saya baru saja menyertakan satu set sederhana yang akan membuat huruf besar semua surat yang dilanjutkan dengan non-huruf dengan pengecualian apostrof. Ini berarti bahwa 123apel memiliki kecocokan pada "a" karena "3" bukan huruf. Jika Anda hanya menginginkan spasi (spasi, tab, carriage-return, line-feed), Anda dapat mengganti pola '[^a-z]'dengan '[' + Char(32) + Char(9) + Char(13) + Char(10) + ']'.


CREATE FUNCTION String.InitCap( @string nvarchar(4000) ) RETURNS nvarchar(4000) AS
BEGIN

-- 1. Convert all letters to lower case
    DECLARE @InitCap nvarchar(4000); SET @InitCap = Lower(@string);

-- 2. Using a Sequence, replace the letters that should be upper case with their upper case version
    SELECT @InitCap = Stuff( @InitCap, n, 1, Upper( SubString( @InitCap, n, 1 ) ) )
    FROM (
        SELECT (1 + n1.n + n10.n + n100.n + n1000.n) AS n
        FROM       (SELECT 0 AS n UNION SELECT    1 UNION SELECT    2 UNION SELECT    3 UNION SELECT    4 UNION SELECT    5 UNION SELECT    6 UNION SELECT    7 UNION SELECT    8 UNION SELECT    9) AS    n1
        CROSS JOIN (SELECT 0 AS n UNION SELECT   10 UNION SELECT   20 UNION SELECT   30 UNION SELECT   40 UNION SELECT   50 UNION SELECT   60 UNION SELECT   70 UNION SELECT   80 UNION SELECT   90) AS   n10
        CROSS JOIN (SELECT 0 AS n UNION SELECT  100 UNION SELECT  200 UNION SELECT  300 UNION SELECT  400 UNION SELECT  500 UNION SELECT  600 UNION SELECT  700 UNION SELECT  800 UNION SELECT  900) AS  n100
        CROSS JOIN (SELECT 0 AS n UNION SELECT 1000 UNION SELECT 2000 UNION SELECT 3000)                                                                                                             AS n1000
        ) AS Sequence
    WHERE 
        n BETWEEN 1 AND Len( @InitCap )
    AND SubString( @InitCap, n, 1 ) LIKE '[a-z]'                 /* this character is a letter */
    AND (
        n = 1                                                    /* this character is the first `character` */
        OR SubString( @InitCap, n-1, 1 ) LIKE '[^a-z]'           /* the previous character is NOT a letter */
        )
    AND (
        n < 3                                                    /* only test the 3rd or greater characters for this exception */
        OR SubString( @InitCap, n-2, 3 ) NOT LIKE '[a-z]''[a-z]' /* exception: The pattern <letter>'<letter> should not capatolize the letter following the apostrophy */
        )

-- 3. Return the modified version of the input
    RETURN @InitCap

END

1

Tautan yang saya posting di atas adalah opsi bagus yang membahas masalah utama: bahwa kami tidak pernah dapat menjelaskan semua kasus secara terprogram (Smith-Jones, von Haussen, John Smith MD), setidaknya tidak dengan cara yang elegan. Tony memperkenalkan konsep karakter pengecualian / penghentian untuk menangani kasus-kasus ini. Bagaimanapun, membangun ide Cervo (huruf besar semua lebih rendah didahului oleh spasi), pernyataan ganti dapat dibungkus dalam satu tabel berbasis ganti sebagai gantinya. Sungguh, kombinasi karakter rendah / atas apa pun dapat disisipkan ke @alpha dan pernyataan itu tidak akan berubah:

declare @str    nvarchar(8000)
declare @alpha  table (low nchar(1), up nchar(1))


set @str = 'ALL UPPER CASE and    SOME lower ÄÄ ÖÖ ÜÜ ÉÉ ØØ ĈĈ ÆÆ'

-- stage the alpha (needs number table)
insert into @alpha
    -- A-Z / a-z
    select      nchar(n+32),
                nchar(n)
    from        dbo.Number
    where       n between 65 and 90 or
                n between 192 and 223

-- append space at start of str
set @str = lower(' ' + @str)

-- upper all lower case chars preceded by space
select  @str = replace(@str, ' ' + low, ' ' + up) 
from    @Alpha

select @str

Namun satu-satunya solusi AS-ASCII lainnya.
Tomalak

Apakah Anda masih melihat ini sebagai solusi yang berpusat pada AS karena merujuk pada karakter unicode. Saya tahu posting asli menggunakan resultet AZ ascii, tetapi titik solusinya adalah bahwa pasangannya didorong tabel atas: karakter bawah. Pernyataan ganti hanya mengacu pada tabel.
Nathan Skerl

edit: Saya memperbarui contoh untuk menggunakan input sampel Anda. Terima kasih atas umpan baliknya
Nathan Skerl

Adakah cara yang "tidak elegan" untuk menangani variasi yang paling dikenal untuk nama yang tidak diberi tanda hubung? Seperti 'Mc', O'C, dan apa yang tidak?
Merritt

1

Masuk akal untuk mempertahankan pencarian pengecualian untuk menangani The von Neumann, McCain, DeGuzman, dan Johnson-Smith.


1

Dipinjam dan diperbaiki pada jawaban @Richard Sayakanit. Ini menangani banyak kata. Seperti jawabannya, ini tidak menggunakan UDF, hanya fungsi bawaan ( STRING_SPLITdan STRING_AGG) dan ini cukup cepat. STRING_AGGmembutuhkan SQL Server 2017 tetapi Anda selalu dapat menggunakan STUFF/XMLtrik ini. Tidak akan menangani setiap pengecualian tetapi dapat berfungsi dengan baik untuk banyak persyaratan.

SELECT StateName = 'North Carolina' 
INTO #States
UNION ALL
SELECT 'Texas'


;WITH cteData AS 
(
    SELECT 
        UPPER(LEFT(value, 1)) +
            LOWER(RIGHT(value, LEN(value) - 1)) value, op.StateName
    FROM   #States op
    CROSS APPLY STRING_SPLIT(op.StateName, ' ') AS ss
)
SELECT 
    STRING_AGG(value, ' ')
FROM cteData c 
GROUP BY StateName

1

Sedikit modifikasi pada jawaban @ Galwegian - yang mengubah mis . St Elizabeth'sMenjadi St Elizabeth'S.

Modifikasi ini membuat apostrof-s sebagai huruf kecil di mana s muncul di akhir string yang disediakan atau s diikuti oleh spasi (dan hanya dalam keadaan itu).

create function properCase(@text as varchar(8000))
returns varchar(8000)
as
begin
    declare @reset int;
    declare @ret varchar(8000);
    declare @i int;
    declare @c char(1);
    declare @d char(1);

    if @text is null
    return null;

    select @reset = 1, @i = 1, @ret = '';

    while (@i <= len(@text))
    select
        @c = substring(@text, @i, 1),
        @d = substring(@text, @i+1, 1),
        @ret = @ret + case when @reset = 1 or (@reset=-1 and @c!='s') or (@reset=-1 and @c='s' and @d!=' ') then upper(@c) else lower(@c) end,
        @reset = case when @c like '[a-za-z]' then 0 when @c='''' then -1 else 1 end,
        @i = @i + 1
    return @ret
end

Itu berputar:

  • st elizabeth's ke St Elizabeth's
  • o'keefe ke O'Keefe
  • o'sullivan ke O'Sullivan

Komentar orang lain bahwa solusi yang berbeda lebih disukai untuk masukan non-Inggris tetap berlaku.


0

Saya pikir Anda akan menemukan bahwa yang berikut ini lebih efisien:

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

Pernyataan replace dapat dipotong dan disisipkan langsung ke dalam kueri SQL. Ini sangat buruk, namun dengan mengganti @str dengan kolom yang Anda minati, Anda tidak akan membayar harga untuk kursor implisit seperti yang Anda lakukan dengan udfs yang diposting. Saya menemukan bahwa bahkan menggunakan UDF saya, ini jauh lebih efisien.

Oh dan alih-alih membuat pernyataan ganti dengan tangan, gunakan ini:

-- 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

Pokoknya itu tergantung jumlah barisnya. Saya berharap Anda dapat melakukan s / \ b ([az]) / uc $ 1 /, tapi oh baiklah kami bekerja dengan alat yang kami miliki.

CATATAN Anda harus menggunakan ini karena Anda harus menggunakannya sebagai .... SELECT dbo.ProperCase (LOWER (kolom)) karena kolom dalam huruf besar. Ini sebenarnya bekerja cukup cepat di tabel saya yang terdiri dari 5.000 entri (bahkan tidak satu detik) bahkan dengan yang lebih rendah.

Menanggapi kebingungan komentar tentang internasionalisasi, saya menyajikan implementasi berikut yang menangani setiap karakter ascii hanya mengandalkan Implementasi SQL Server atas dan bawah. Ingat, variabel yang kita gunakan di sini adalah VARCHAR yang artinya hanya dapat menampung nilai ASCII. Untuk menggunakan huruf internasional lebih lanjut, Anda harus menggunakan NVARCHAR. Logikanya akan serupa tetapi Anda perlu menggunakan UNICODE dan NCHAR sebagai pengganti ASCII AND CHAR dan pernyataan ganti akan jauh lebih besar ....

-- 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)

Pada dasarnya premis metode saya adalah melakukan perdagangan pra-komputasi untuk efisiensi. Implementasi ASCII lengkap adalah sebagai berikut:

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

1
Ya. Alfabet Anda hanya memiliki 26 karakter. Punyaku memiliki lebih banyak. Bagaimana dengan bahasa Yunani? Atau Turki?
Tomalak

Saya berpendapat bahwa solusi lain melakukan hal yang sama. Tapi saya sudah memasukkan pembuat kode. Anda bisa menambahkan bagian tambahan untuk alfabet Anda. Anda harus memiliki semuanya sebagai NVARCHAR dan menggunakan NCHAR dan UNICODE untuk mengonversi.
Cervo

Saya pikir semakin banyak karakter yang Anda miliki semakin kurang efisien itu akan didapat. Tapi sih dalam beberapa himpunan karakter setiap simbol mewakili seluruh kata sehingga masalah kasus yang sesuai tidak berlaku ....
Cervo

Juga saya ragu ada orang yang menggunakan setiap karakter unicode sekaligus. Jadi mungkin hanya menghasilkan kode yang menggantikan 2 atau 3 huruf yang Anda gunakan.
Cervo

1
Itu tidak berarti Anda harus menggunakan solusi bahasa Inggris setengah matang hanya karena Anda mengharapkan datanya "ada dalam alfabet Anda, mungkin". Sejauh sistem penulisan Latin, ada huruf kecil / besar yang ditentukan untuk (hampir) semua karakter. Fungsi konversi lebih banyak tentang kebenaran daripada kecepatan.
Tomalak

0

Apakah sudah terlambat untuk kembali dan mendapatkan data tanpa huruf besar?

Basis klien Anda dari von Neumann, McCain, DeGuzman, dan Johnson-Smith mungkin tidak menyukai hasil pemrosesan Anda ...

Juga, saya menduga bahwa ini dimaksudkan sebagai peningkatan data satu kali? Mungkin lebih mudah untuk mengekspor, memfilter / memodifikasi, dan mengimpor ulang nama yang dikoreksi ke db, dan kemudian Anda dapat menggunakan pendekatan non-SQL untuk memperbaiki nama ...


Seluruh masalah penamaan muncul sebagai kerugian yang mungkin terjadi jika dibahas - tidak ada indikasi bahwa penulis pertanyaan mengacu pada data yang berisi nama.
Tomalak

0

Berikut adalah variasi lain yang saya temukan di Forum SQLTeam.com @ http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=47718

create FUNCTION PROPERCASE
(
--The string to be converted to proper case
@input varchar(8000)
)
--This function returns the proper case string of varchar type
RETURNS varchar(8000)
AS
BEGIN
IF @input IS NULL
BEGIN
--Just return NULL if input string is NULL
RETURN NULL
END

--Character variable declarations
DECLARE @output varchar(8000)
--Integer variable declarations
DECLARE @ctr int, @len int, @found_at int
--Constant declarations
DECLARE @LOWER_CASE_a int, @LOWER_CASE_z int, @Delimiter char(3), @UPPER_CASE_A int, @UPPER_CASE_Z int

--Variable/Constant initializations
SET @ctr = 1
SET @len = LEN(@input)
SET @output = ''
SET @LOWER_CASE_a = 97
SET @LOWER_CASE_z = 122
SET @Delimiter = ' ,-'
SET @UPPER_CASE_A = 65
SET @UPPER_CASE_Z = 90

WHILE @ctr <= @len
BEGIN
--This loop will take care of reccuring white spaces
WHILE CHARINDEX(SUBSTRING(@input,@ctr,1), @Delimiter) > 0
BEGIN
SET @output = @output + SUBSTRING(@input,@ctr,1)
SET @ctr = @ctr + 1
END

IF ASCII(SUBSTRING(@input,@ctr,1)) BETWEEN @LOWER_CASE_a AND @LOWER_CASE_z
BEGIN
--Converting the first character to upper case
SET @output = @output + UPPER(SUBSTRING(@input,@ctr,1))
END
ELSE
BEGIN
SET @output = @output + SUBSTRING(@input,@ctr,1)
END

SET @ctr = @ctr + 1

WHILE CHARINDEX(SUBSTRING(@input,@ctr,1), @Delimiter) = 0 AND (@ctr <= @len)
BEGIN
IF ASCII(SUBSTRING(@input,@ctr,1)) BETWEEN @UPPER_CASE_A AND @UPPER_CASE_Z
BEGIN
SET @output = @output + LOWER(SUBSTRING(@input,@ctr,1))
END
ELSE
BEGIN
SET @output = @output + SUBSTRING(@input,@ctr,1)
END
SET @ctr = @ctr + 1
END

END
RETURN @output
END



GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

0

Saya tahu masalah detailnya (terutama jika menyangkut data pribadi orang), dan akan sangat menyenangkan untuk memiliki nama yang dikapitalisasi dengan benar, tetapi kerumitan di atas adalah mengapa pragmatis, sadar waktu di antara kita menggunakan yang berikut ini :

SELECT UPPER('Put YoUR O'So oddLy casED McWeird-nAme von rightHERE here')

Menurut pengalaman saya, orang baik-baik saja melihat NAMA MEREKA ... meskipun itu setengah kalimat.

Lihat: Rusia menggunakan pensil!


3
Menyangkal pertanyaan tidak membantu. "Jawaban" ini adalah komentar AT BEST.
Phil

0

Baru saja belajar tentang InitCap() .

Berikut beberapa contoh kode:

SELECT ID
      ,InitCap(LastName ||', '|| FirstName ||' '|| Nvl(MiddleName,'')) AS RecipientName
FROM SomeTable

2
OP ditentukan Sql Server, 'InitCap ()' adalah hal Oracle.
mxmissile

0

Ini bekerja di SSMS:

Select Jobtitle,
concat(Upper(LEFT(jobtitle,1)), SUBSTRING(jobtitle,2,LEN(jobtitle))) as Propercase
From [HumanResources].[Employee]

0

Jika Anda tahu semua data hanyalah satu kata, inilah solusinya. Pertama perbarui kolom ke semua lebih rendah dan kemudian jalankan yang berikut ini

    update tableName set columnName = 
    upper(SUBSTRING(columnName, 1, 1)) + substring(columnName, 2, len(columnName)) from tableName

0

Baru-baru ini harus mengatasi ini dan muncul dengan yang berikut setelah tidak ada yang cukup memukul semua yang saya inginkan. Ini akan melakukan seluruh kalimat, kasus untuk penanganan kata khusus. Kami juga memiliki masalah dengan satu karakter 'kata' yang ditangani oleh banyak metode sederhana tetapi tidak dengan metode yang lebih rumit. Variabel pengembalian tunggal, tidak ada loop atau kursor juga.

CREATE FUNCTION ProperCase(@Text AS NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS BEGIN

    DECLARE @return NVARCHAR(MAX)

    SELECT @return = COALESCE(@return + ' ', '') + Word FROM (
         SELECT CASE
            WHEN LOWER(value) = 'llc' THEN UPPER(value)
            WHEN LOWER(value) = 'lp' THEN UPPER(value) --Add as many new special cases as needed
            ELSE
               CASE WHEN LEN(value) = 1
               THEN UPPER(value)
               ELSE UPPER(LEFT(value, 1)) + (LOWER(RIGHT(value, LEN(value) - 1)))
              END
            END AS Word
         FROM STRING_SPLIT(@Text, ' ')
     ) tmp

     RETURN @return
END

0

Salin dan tempel data Anda ke MS Word dan gunakan konversi teks bawaan menjadi "Capitalize Each Word". Bandingkan dengan data asli Anda untuk mengatasi pengecualian. Tidak dapat melihat jalan keluar secara manual untuk menghindari pengecualian jenis "MacDonald" dan "IBM" tetapi ini adalah bagaimana saya menyelesaikannya FWIW.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.