Presisi, skala, dan panjang (Transact-SQL)

Berlaku untuk:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics AnalyticsPlatform System (PDW)Titik akhir analitik SQL di Microsoft FabricWarehouse di Microsoft Fabric

Presisi adalah jumlah digit dalam angka. Skala adalah jumlah digit di sebelah kanan titik desimal dalam angka. Misalnya, angka 123.45 memiliki presisi 5 dan skala 2.

Di SQL Server, presisi maksimum default jenis data numerik dan desimal adalah 38.

Panjang untuk jenis data numerik adalah jumlah byte yang digunakan untuk menyimpan angka. Untuk varchar dan karakter, panjang string karakter adalah jumlah byte. Untuk nvarchar dan nchar, panjang string karakter adalah jumlah byte-pairs. Panjang untuk jenis data biner, varbinary, dan gambar adalah jumlah byte. Misalnya, jenis data int dapat menampung 10 digit, disimpan dalam 4 byte, dan tidak menerima titik desimal. Jenis data int memiliki presisi 10, panjang 4, dan skala 0.

  • Saat Anda menggabungkan dua ekspresi karakter, varchar, biner, atau varbinary , panjang ekspresi yang dihasilkan adalah jumlah panjang dua ekspresi sumber, hingga 8.000 byte.

  • Saat Anda menggabungkan dua ekspresi nchar atau nvarchar , panjang ekspresi yang dihasilkan adalah jumlah panjang dua ekspresi sumber, hingga 4.000 byte-pairs.

  • Saat Anda membandingkan dua ekspresi dari jenis data yang sama tetapi panjang yang berbeda dengan menggunakan UNION, , EXCEPTatau INTERSECT, panjang yang dihasilkan adalah lebih panjang dari dua ekspresi.

Keterangan

Presisi dan skala jenis data numerik selain desimal diperbaiki. Ketika operator aritmatika memiliki dua ekspresi dengan jenis yang sama, hasilnya memiliki jenis data yang sama dengan presisi dan skala yang ditentukan untuk jenis tersebut. Jika operator memiliki dua ekspresi dengan jenis data numerik yang berbeda, aturan jenis data diutamakan menentukan jenis data hasilnya. Hasilnya memiliki presisi dan skala yang ditentukan untuk jenis datanya.

Tabel berikut menentukan bagaimana presisi dan skala hasil dihitung ketika hasil operasi berjenis desimal. Hasilnya desimal ketika:

  • Kedua ekspresi bersifat desimal.
  • Satu ekspresi bersifat desimal dan yang lainnya adalah jenis data dengan prioritas yang lebih rendah daripada desimal.

Ekspresi operand ditandai sebagai ekspresi e1, dengan presisi p1 dan skala s1, dan ekspresi e2, dengan presisi p2 dan skala s2. Presisi dan skala untuk ekspresi apa pun yang tidak desimal adalah presisi dan skala yang ditentukan untuk jenis data ekspresi. Fungsi max(a, b) menunjukkan untuk mengambil nilai yang lebih besar dari a atau b. Demikian pula, min(a, b) menunjukkan untuk mengambil nilai yang lebih kecil dari a atau b.

Operasi Presisi hasil Skala hasil 1
e1 + e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 max(s1, s2)
e1 - e2 max(s1, s2) + max(p1 - s1, p2 - s2) + 1 max(s1, s2)
e1 * e2 p1 + p2 + 1 s1 + s2
e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2 max(s1, s2) + max(p1 - s1, p2 - s2) max(s1, s2)
e1 % e2 min(p1 - s1, p2 - s2) + maks(s1, s2) max(s1, s2)

1 Presisi dan skala hasil memiliki maksimum absolut 38. Ketika presisi hasil lebih besar dari 38, itu dikurangi menjadi 38, dan skala yang sesuai dikurangi untuk mencoba mencegah pemotongan bagian integral dari hasil. Dalam beberapa kasus seperti perkalian atau pembagian, faktor skala tidak berkurang, untuk mempertahankan presisi desimal, meskipun kesalahan luapan dapat dimunculkan.

Selain itu dan pengurangan operasi, kita perlu max(p1 - s1, p2 - s2) tempat untuk menyimpan bagian integral dari angka desimal. Jika tidak ada cukup ruang untuk menyimpannya (yaitu, max(p1 - s1, p2 - s2) < min(38, precision) - scale), skala dikurangi untuk memberikan ruang yang cukup untuk bagian integral. Skala yang dihasilkan adalah min(precision, 38) - max(p1 - s1, p2 - s2), sehingga bagian pecahan mungkin dibulatkan agar sesuai dengan skala yang dihasilkan.

Dalam operasi perkalian dan pembagian, kita membutuhkan precision - scale tempat untuk menyimpan bagian integral dari hasilnya. Skala mungkin dikurangi menggunakan aturan berikut:

  1. Skala yang dihasilkan dikurangi menjadi min(scale, 38 - (precision-scale)) jika bagian integral kurang dari 32, karena tidak bisa lebih besar dari 38 - (precision-scale). Hasilnya mungkin dibulatkan dalam kasus ini.
  2. Skala tidak berubah jika kurang dari 6 dan jika bagian integral lebih besar dari 32. Dalam hal ini, kesalahan luapan mungkin muncul jika tidak dapat masuk ke desimal (38, skala).
  3. Skala diatur ke 6 jika lebih besar dari 6 dan jika bagian integral lebih besar dari 32. Dalam hal ini, bagian integral dan skala akan berkurang dan jenis yang dihasilkan adalah desimal(38, 6). Hasilnya mungkin dibulatkan ke 6 tempat desimal, atau kesalahan luapan dilemparkan jika bagian integral tidak dapat masuk ke dalam 32 digit.

Contoh

Ekspresi berikut mengembalikan hasil 0.00000090000000000 tanpa pembulatan, karena hasilnya bisa pas menjadi desimal(38, 17):

SELECT CAST(0.0000009000 AS DECIMAL(30, 20)) * CAST(1.0000000000 AS DECIMAL(30, 20)) [decimal(38, 17)];

Dalam hal ini presisi adalah 61, dan skalanya adalah 40.

Bagian integral (precision-scale = 21) kurang dari 32, jadi kasus ini adalah kasus pertama dalam aturan perkalian, dan skala dihitung sebagai min(scale, 38 - (precision-scale)) = min(40, 38 - (61-40)) = 17. Jenis hasil adalah desimal(38, 17).

Ekspresi berikut mengembalikan hasil 0.000001 agar pas dengan desimal(38, 6):

SELECT CAST(0.0000009000 AS DECIMAL(30, 10)) * CAST(1.0000000000 AS DECIMAL(30, 10)) [decimal(38, 6)];

Dalam hal ini presisi adalah 61, dan skalanya adalah 20.

Skala lebih besar dari 6 dan bagian integral (precision-scale = 41) lebih besar dari 32. Kasus ini adalah kasus ketiga dalam aturan perkalian, dan jenis hasilnya adalah desimal(38, 6).

Baca juga