Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

Konversi Unicode ke Non-Unicode

Ada beberapa hal yang perlu diperhatikan di sini:

  1. Jika Anda ingin melihat dengan tepat karakter mana yang ada, Anda dapat mengonversi nilainya menjadi VARBINARY yang akan memberi Anda nilai hex / biner dari semua karakter dalam string dan tidak ada konsep karakter "tersembunyi" dalam hex:

    DECLARE @PostalCode NVARCHAR(20);
    SET @PostalCode = N'053000'+ NCHAR(0x2008); -- 0x2008 = "Punctuation Space"
    SELECT @PostalCode AS [NVarCharValue],
           CONVERT(VARCHAR(20), @PostalCode) AS [VarCharValue],
           CONVERT(VARCHAR(20), RTRIM(@PostalCode)) AS [RTrimmedVarCharValue],
           CONVERT(VARBINARY(20), @PostalCode) AS [VarBinaryValue];
    

    Pengembalian:

    NVarCharValue   VarCharValue   RTrimmedVarCharValue   VarBinaryValue
    053000          053000?        053000?                0x3000350033003000300030000820
    

    NVARCHAR data disimpan sebagai UTF-16 yang bekerja dalam set 2-byte. Melihat 4 digit hex terakhir untuk melihat apa set 2-byte yang tersembunyi, kita melihat "0820". Karena Windows dan SQL Server adalah UTF-16 Little Endian (yaitu UTF-16LE), byte berada dalam urutan terbalik. Membalik 2 byte terakhir -- 08 dan 20 -- kita mendapatkan "2008", yang merupakan "Ruang Tanda Baca" yang kita tambahkan melalui NCHAR(0x2008) .

    Juga, harap perhatikan bahwa RTRIM tidak membantu sama sekali di sini.

  2. Sederhananya, Anda bisa mengganti tanda tanya dengan apa-apa:

    SELECT REPLACE(CONVERT(VARCHAR(20), [PostalCode]), '?', '');
    
  3. Lebih penting lagi, Anda harus mengonversi [PostalCode] bidang ke VARCHAR sehingga tidak menyimpan karakter ini. Tidak ada negara yang menggunakan huruf yang tidak terwakili dalam rangkaian karakter ASCII dan yang tidak valid untuk tipe data VARCHAR, setidaknya sejauh yang pernah saya baca (lihat bagian bawah untuk referensi). Faktanya, apa yang diperbolehkan adalah subset ASCII yang agak kecil, yang berarti Anda dapat dengan mudah memfilter saat masuk (atau cukup lakukan REPLACE yang sama seperti yang ditunjukkan di atas saat memasukkan atau memperbarui):

    ALTER TABLE [table] ALTER COLUMN [PostalCode] VARCHAR(20) [NOT]? NULL;
    

    Pastikan untuk memeriksa NULL saat ini / NOT NULL setting untuk kolom dan buat sama dengan pernyataan ALTER di atas, kalau tidak bisa diubah karena defaultnya adalah NULL jika tidak ditentukan.

  4. Jika Anda tidak dapat mengubah skema tabel dan perlu melakukan "pembersihan" berkala dari data yang buruk, Anda dapat menjalankan yang berikut:

    ;WITH cte AS
    (
       SELECT *
       FROM   TableName
       WHERE  [PostalCode] <>
                      CONVERT(NVARCHAR(50), CONVERT(VARCHAR(50), [PostalCode]))
    )
    UPDATE cte
    SET    cte.[PostalCode] = REPLACE(CONVERT(VARCHAR(50), [PostalCode]), '?', '');
    

    Harap diingat bahwa kueri di atas tidak dimaksudkan untuk bekerja secara efisien jika tabel memiliki jutaan baris. Pada saat itu perlu ditangani dalam set yang lebih kecil melalui loop.

Untuk referensi, berikut adalah artikel wikipedia untuk Kode pos , yang saat ini menyatakan bahwa satu-satunya karakter yang pernah digunakan adalah:

Dan mengenai ukuran maksimum bidang, berikut adalah Daftar kode pos Wikipedia



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara mendapatkan skrip data SQL Server?

  2. Linq to SQL - Gagal memperbarui

  3. Kunci Komposit Unik SQL Server dari Dua Bidang Dengan Peningkatan Otomatis Bidang Kedua

  4. Pilih ke pernyataan di mana sumbernya adalah database lain

  5. System.ArgumentException:Parameter tipe tabel harus memiliki nama tipe yang valid