Pertama-tama, Anda tidak dapat melakukannya tanpa mereka, bukan?
Konversi data SQL atau, lebih khusus lagi, konversi tipe data adalah bagian penting dari pekerjaan pemrograman reguler pengembang database atau DBA.
Sekarang, bagaimana jika bos Anda menandatangani kontrak dengan perusahaan lain untuk menyediakan file dalam format teks yang berasal dari database SQL Server Anda?
Ini terdengar seperti tantangan yang mengasyikkan!
Tetapi Anda menemukan bahwa Anda harus berurusan dengan tanggal ke string, nomor ke string, dan banyak konversi data SQL lainnya. Apakah Anda masih siap menghadapi tantangan?
Bukan tanpa gudang trik konversi data Anda!
Apa yang Tersedia Langsung?
Ketika saya pertama kali memulai pemrograman T-SQL, hal pertama yang saya lihat yang sesuai dengan tujuan konversi adalah CONVERT () fungsi.
Selain itu, ada kata “convert”, kan?
Meskipun ini mungkin benar, itu hanya salah satu dari 4 cara untuk melakukan pekerjaan ini. Dan saya menggunakannya untuk hampir SEMUA konversi data SQL saya. Saya senang saya melewati itu. Karena saya telah belajar bahwa 4 metode memiliki tempatnya sendiri dalam kode Anda.
Sebelum kita masuk ke topik posting, izinkan saya menyajikan 4 metode out-of-the-box untuk melakukan konversi data SQL:
- PASTIKAN ()
- KONVERSI ()
- PARSE ()
- COBA_CAST (), COBA_KONVERSI (), COBA_PARSE ()
Setiap bagian di bawah ini akan:
- Jelaskan apa itu
- Beri tahu kapan harus menggunakannya (kasus penggunaan)
- Berikan batasannya
- Berikan contoh dan jelaskan
Semua yang disajikan dalam artikel ini sebisa mungkin dalam bahasa Inggris yang sederhana dan sederhana. Pada saat Anda selesai membaca seluruh postingan, Anda akan tahu metode mana yang sesuai untuk situasi tertentu.
Jadi, tanpa basa-basi lagi, mari selami.
1. Konversi Data SQL Menggunakan CAST()
Meskipun semua metode yang akan Anda lihat dapat mengonversi tipe data, pilihan pertama Anda dalam mengonversi harus CAST ().
Berikut alasannya:
- Ini adalah fungsi konversi yang berjalan paling cepat dari semuanya. Kami akan coba buktikan nanti di postingan ini.
- Ini termasuk dalam standar spesifikasi bahasa SQL-92. Jadi, ketika Anda perlu mem-porting kode Anda ke produk SQL lainnya, seperti MySQL, fungsinya juga tersedia.
Berikut sintaks yang sangat sederhana untuk CAST ():
CAST( <expression> AS <data_type>[(length)] )
Pertama, mari kita periksa sintaksnya:
- <ekspresi> adalah ekspresi valid apa pun yang menghasilkan nilai yang dapat dikonversi ke tipe data target.
- <tipe_data> adalah tipe data target.
- panjang bersifat opsional dan berkaitan dengan ukuran data.
Kapan Menggunakannya
Jika satu-satunya hal yang Anda perlukan adalah mengonversi nilai ke tipe data lain, maka CAST () adalah yang Anda butuhkan.
Batasan
Sisi negatifnya, CAST () tidak dapat memberi Anda keluaran yang diformat secara langsung seperti nilai tanggal dan waktu yang diformat.
Contoh
A. Mengonversi string menjadi tanggal:
SELECT CAST('09/11/2004 4:30PM' as datetime2)
Dan menjalankan pernyataan di atas akan menghasilkan:
B. Mengonversi angka menjadi string:
SELECT CAST(10.003458802 as varchar(max))
Dan hasil dari konversi di atas adalah:
Sekarang, jika Anda memerlukan hal lain seperti memformat data yang dikonversi, metode selanjutnya dapat membantu Anda.
2. Konversi Data SQL Menggunakan CONVERT()
Opsi konversi data selanjutnya adalah menggunakan CONVERT (). Seperti yang saya katakan sebelumnya, ini adalah yang paling sering saya gunakan di hari-hari sebelumnya.
Berikut sintaksnya:
CONVERT( <data_type>[(length)], <expression> [, <style>])
Dari sintaks di atas, perhatikan bahwa <style> parameter adalah opsional. Dan kecuali Anda menyediakannya, fungsinya akan mirip dengan CAST ().
Di situlah kebingungan saya dimulai ketika saya baru mengenal SQL.
Kapan Menggunakannya
Jika Anda mengonversi data dengan format instan, maka CONVERT () adalah teman Anda. Yang berarti Anda memperlakukan <gaya> parameter dengan benar.
Batasan
- PASTIKAN () lebih cepat dari CONVERT (), jadi jika Anda hanya perlu mengonversi data, gunakan CAST (). Jika output harus diformat, gunakan CONVERT ().
- KONVERSI () bukan standar SQL-92, jadi jika Anda perlu mem-porting-nya ke RDBMS lain, hindari menggunakannya.
Contoh
A. Mengonversi tanggal ke format string yyyymmdd
Dalam contoh berikut, saya akan menggunakan database sampel AdventureWorks dan ubah [Tanggal Mulai ] kolom ke yyyymmdd :
USE AdventureWorks
GO
SELECT
[BillOfMaterialsID]
,CONVERT(varchar(10), [StartDate],112) as StartDate
FROM [Production].BillOfMaterials]
GO
Perhatikan bahwa gaya 112 digunakan untuk memformat tanggal menjadi yyyymmdd .
B. Ubah angka menjadi string dengan koma pada setiap 3 digit di sebelah kiri titik desimal.
Demikian pula, contoh berikut akan mengilustrasikan AdventureWorks database sampel, dan kami akan memformat angka dengan koma dan dengan 2 tempat desimal.
USE AdventureWorks
GO
SELECT
[TransactionID]
,[ProductID]
,CONVERT(varchar(10),[TransactionDate] ,112) as StartDate
,[Quantity]
,CONVERT(varchar(10),[ActualCost],1) as ActualCost
FROM [Production].TransactionHistory
GO
Perhatikan bahwa format 1 digunakan untuk [ActualCost ]. Dan terima kasih kepada CONVERT (), kita dapat memformat kolom ini dalam sekejap.
Namun, bagaimana jika Anda perlu mengonversi ekspresi tanggal yang lebih panjang? Akan KONVERSI () bekerja dalam kasus itu? Baca terus untuk mengetahui metode selanjutnya.
3. Konversi Data SQL Menggunakan PARSE()
Metode selanjutnya yang akan kita pertimbangkan adalah PARSE ().
Lihat sintaksnya:
PARSE( <string value> AS <datatype> [USING <culture>])
Kapan Menggunakannya
- Untuk mengonversi string menjadi tanggal atau angka menggunakan budaya tertentu.
- Bila string tidak dapat dikonversi menjadi tanggal atau angka menggunakan CAST () atau KONVERSI (). Lihat contoh untuk informasi lebih lanjut.
Batasan
- Konversi hanya dimungkinkan untuk string ke tanggal dan string ke angka
- Bergantung pada keberadaan .Net Framework Common Language Runtime (CLR) di server.
- Tidak termasuk dalam spesifikasi standar SQL-92, sehingga porting ke RDBMS lain menjadi masalah.
- Memiliki overhead kinerja dalam hal penguraian string.
Contoh
A. Mengonversi string tanggal yang panjang
SELECT PARSE('Monday, June 8, 2020' as datetime USING 'en-US')
Contoh di atas adalah string tanggal panjang yang akan dikonversi menjadi waktu-tanggal nilai menggunakan budaya Inggris AS. Dan di sinilah PARSE () akan melakukan yang terbaik.
Itu karena kode di atas akan gagal jika Anda menggunakan CAST () atau KONVERSI ().
B. Mengonversi nilai uang dengan simbol mata uang
SELECT PARSE('€1024,01' as money using 'de-DE')
Sekarang, coba lakukan konversi menggunakan CAST () dan KONVERSI ()
SELECT CONVERT(money,'€1024,01')
SELECT CAST('€1024,01' as money)
Pernyataan itu tidak akan menimbulkan kesalahan, tetap saja, lihat hasil yang tidak terduga ini:
Hasilnya, nilai telah dikonversi menjadi 102401.00, bukan 1024.01.
Sejauh ini, kami telah menemukan bahwa 3 metode pertama rentan terhadap kesalahan kecuali Anda memeriksanya. Namun demikian, metode ke-4 dapat menjadi solusi Anda untuk hasil yang salah.
4. Konversi Data SQL menggunakan TRY_CAST(), TRY_CONVERT(), atau TRY_PARSE()
Terakhir, metode terakhir untuk konversi data SQL menggunakan varian dari 3 yang pertama tetapi dengan awalan TRY_.
Tapi meski begitu, apa bedanya?
Mereka memiliki parameter yang sama seperti 3 sebelumnya tanpa awalan TRY_. Namun perbedaannya adalah, mereka mengembalikan NULL jika nilainya tidak dapat dikonversi. Sekarang, jika nilai tidak dapat dikonversi oleh salah satu dari 3 secara eksplisit, terjadi kesalahan. Lihat contoh di bawah untuk pemahaman yang lebih baik.
Kapan Menggunakannya
Anda dapat menggunakan salah satu dari 3 dengan pernyataan bersyarat seperti CASE KAPAN atau IIF untuk menguji kesalahan.
Batasan
Ketiganya memiliki batasan yang sama dengan yang tanpa awalan TRY_, kecuali untuk nilai yang tidak dapat dikonversi.
Contoh
A. Gunakan TRY_CAST() untuk menguji apakah konversi akan berhasil menggunakan IIF:
SELECT IIF(TRY_CAST('111b' AS real) IS NULL, 'Cast failed', 'Cast succeeded') AS Result
Kode di atas akan menampilkan 'Cast Failed' karena '111b' tidak dapat dikonversi ke nyata . Hapus 'b' dari nilainya, dan itu akan mengembalikan 'Pemeran berhasil'.
B. Menggunakan TRY_CONVERT() pada tanggal dengan format tertentu
SET DATEFORMAT dmy;
SELECT TRY_CONVERT(datetime2, '12/31/2010') AS Result
Ini akan mengembalikan NULL karena formatnya menggunakan dmy atau hari-bulan-tahun. Dan ekspresi input untuk TRY_CONVERT () dalam format mdy atau bulan-hari-tahun. Kesalahan dipicu karena nilai bulan adalah 31.
C. Menggunakan TRY_PARSE() yang akan menghasilkan kesalahan runtime
SELECT
CASE WHEN TRY_PARSE('10/21/2133' AS smalldatetime USING 'en-US') IS NULL
THEN 'True'
ELSE 'False'
END AS Result
Kode ini akan menghasilkan kesalahan runtime seperti yang terlihat di bawah ini:
Itu saja untuk 4 metode out-of-the-box dalam konversi data SQL. Tapi masih ada lagi yang akan datang.
Bagaimana Dengan Konversi Data SQL Menggunakan Konversi Implisit?
Sekarang mari kita pertimbangkan konversi implisit. Ini adalah metode diam.
Kenapa diam?
Karena Anda mungkin sudah melakukannya, tetapi Anda tidak menyadarinya. Atau setidaknya, Anda tahu itu terjadi, tetapi Anda mengabaikannya.
Dengan kata lain, ini adalah jenis konversi yang dilakukan SQL secara otomatis tanpa fungsi apa pun.
Biarkan saya memberi Anda sebuah contoh:
DECLARE @char CHAR(25)
DECLARE @varchar VARCHAR(25)
DECLARE @nvarchar NVARCHAR(25)
DECLARE @nchar NCHAR(25)
SET @char = 'Live long and prosper'
SET @varchar = @char
SET @nvarchar = @varchar
SET @nchar = @nvarchar
SELECT @char AS [char], @varchar AS [varchar], @nvarchar AS [nvarchar], @nchar AS [nchar]
Kode di atas akan berhasil dijalankan. Cobalah sendiri, dan Anda akan mendapatkan hasil yang serupa dengan yang di bawah ini:
Mari kita coba ini dengan tanggal:
DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2
SET @datetime = '12/31/2050 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime
SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]
Seperti yang diharapkan, ini akan menghasilkan hasil yang sukses:
Mari kita coba kali ini dengan angka:
DECLARE @int int
DECLARE @real real
DECLARE @decimal decimal
DECLARE @float float
SET @int = 1701
SET @real = @int
SET @decimal = @real
SET @float = @decimal
SELECT @int as [int], @real as [real], @decimal as [decimal], @float as [float]
Masih sukses, kan?
Sejauh ini, kami telah menggunakan nilai sederhana yang akan cocok untuk tipe data yang agak mirip. Mari masuk ke level berikutnya:angka menjadi string.
DECLARE @number int
DECLARE @string varchar(5)
SET @number = 1701
SET @string = @number
SELECT @number as [number], @string as [string]
Ini akan berhasil dikonversi seperti yang Anda lihat dari hasil di bawah ini:
Ada banyak lagi contoh ketika SQL Server akan mencoba "menebak" cara mengonversi data. Seperti yang Anda lihat dari referensi ini, ada banyak contoh dibandingkan dengan yang memerlukan konversi eksplisit.
Karena SQL Server mengizinkan ini, apakah ini berarti Anda dapat dengan bebas mengizinkan ini terjadi di seluruh kode Anda?
Peringatan dalam Konversi Implisit
Untuk satu hal, mungkin nyaman. Namun begitu batas setiap tipe data tercapai, Anda akan menyadari bahwa konversi implisit agak berbahaya jika dibiarkan.
Perhatikan contoh di bawah ini:
DECLARE @char char(25)
DECLARE @varchar varchar(25)
DECLARE @nvarchar nvarchar(25)
DECLARE @nchar nchar(25)
SET @nvarchar = N'I ❤ U!'
SET @nchar = @nvarchar
SET @char = @nchar
SET @varchar = @nchar
SELECT @char as [char], @varchar as [varchar], @nvarchar as [nvarchar], @nchar as [nchar]
Apakah Anda melihat nilai emoji? Itu akan dihitung sebagai nilai unicode.
Sementara semua pernyataan di atas akan berhasil dijalankan, variabel dengan tipe non-unicode seperti varchar dan char akan mendapatkan hasil yang tidak terduga. Lihat hasilnya di bawah ini:
Meskipun demikian, itu bukan satu-satunya masalah. Kesalahan akan muncul ketika nilainya menjadi di luar jangkauan. Pertimbangkan contoh dengan tanggal:
DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2
SET @datetime = '12/31/2374 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime
SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]
Penetapan waktu-tanggal nilai ke smalldatetime variabel akan memicu kesalahan seperti yang Anda lihat di bawah ini:
Namun ada peringatan lain, yang juga harus Anda waspadai saat menangani konversi implisit:overhead kinerja. Melihat bahwa ini adalah topik hangat, layak untuk memiliki bagian terpisah.
Implikasi Kinerja dari Berbagai Metode Konversi Data SQL
Percaya atau tidak, metode konversi data SQL yang berbeda akan memiliki kinerja yang berbeda dalam situasi aktual. Dan Anda setidaknya harus menyadari hal ini sehingga Anda dapat menghindari jebakan kinerja.
Bagaimana Kinerja CAST(), CONVERT() dan PARSE()
Pertama, mari kita periksa bagaimana CAST (), KONVERSI (), dan PARSE () tampil di bawah kondisi alami dengan membandingkan mana yang lebih cepat. Kami mengadaptasi dan membuktikan konsep contoh kami diambil dari sini. Perhatikan kode di bawah ini:
USE AdventureWorks
GO
SET STATISTICS TIME ON
SELECT CAST([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SELECT CONVERT(int,[NationalIDNumber]) FROM [HumanResources].[Employee]
SELECT PARSE([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SET STATISTICS TIME OFF
GO
Sekarang, mari kita periksa kode yang menggunakan AdventureWorks basis data dari Microsoft:
- ATUR WAKTU STATISTIK AKTIF akan menampilkan waktu CPU dan waktu yang telah berlalu di setiap PILIH pernyataan
- Lalu, kolom yang kita pilih untuk dikonversi untuk tujuan demonstrasi adalah [NationalIDNumber ], yang memiliki tipe nvarchar(15) .
- Juga, konversi dari string ke integer:nvarchar(15) ke masuk .
- Dan terakhir, kami memulihkan SET STATISTIK WAKTU ke nilai sebelumnya
Perhatikan output di Pesan tab hasil Kueri:
Inilah yang kami dapatkan dengan menggunakan contoh ini:
- Ini membuktikan bahwa CAST () melakukan yang tercepat (1 md.) dan PARSE () tampil paling lambat (318 md).
- Kami mengikuti prioritas ini saat memutuskan fungsi mana yang akan digunakan untuk mengonversi data:(1 ) CAST () (2 ) KONVERSI () (3 ) PARSE ().
- Ingat saat setiap fungsi relevan dan pertimbangkan batasannya saat memutuskan fungsi mana yang akan digunakan.
Bagaimana Performa Konversi Implisit
Pada titik ini, Anda seharusnya dapat melihat bahwa saya merekomendasikan penggunaan fungsi seperti CAST() untuk mengonversi data. Dan di bagian ini, Anda akan melihat alasannya.
Pertimbangkan kueri ini menggunakan WideWorldImporters basis data dari Microsoft. Sebelum menjalankannya, harap aktifkan Sertakan Rencana Eksekusi Aktual di Studio Manajemen SQL Server .
USE WideWorldImporters
GO
SELECT
[CustomerID]
,[OrderID]
,[OrderDate]
,[ExpectedDeliveryDate]
FROM [Sales].[Orders]
WHERE [CustomerID] like '487%'
Dalam kueri di atas, kami memfilter hasil pesanan penjualan dengan [CustomerID ] seperti '487%'. Ini hanya untuk menunjukkan apa efek konversi implisit dari int tipe data ada di varchar .
Selanjutnya, kita periksa rencana eksekusi di bawah ini:
Seperti yang Anda lihat, ada peringatan di PILIH ikon. Oleh karena itu, arahkan mouse Anda untuk melihat tooltip. Selanjutnya perhatikan pesan peringatannya yaitu CONVERT_IMPLICIT .
Sebelum kita melanjutkan, CONVERT_IMPLICIT . ini peringatan terjadi ketika diperlukan untuk melakukan konversi implisit untuk SQL Server. Mari kita lihat lebih dekat masalahnya. Seperti dijelaskan di bawah, peringatan memiliki 2 bagian:
- CONVERT_IMPLICIT dapat memengaruhi “Estimate Kardinalitas” dalam pilihan paket kueri.
- CONVERT_IMPLICIT dapat memengaruhi “SeekPlan” dalam pilihan paket kueri.
Keduanya menunjukkan bahwa kueri Anda akan berjalan lebih lambat. Tapi kita tahu mengapa, tentu saja. Kami sengaja memaksakan konversi implisit dengan menggunakan LIKE operator untuk nilai integer.
Apa gunanya itu?
- Konversi data implisit menyebabkan SQL Server menggunakan CONVERT_IMPLICIT , yang memperlambat eksekusi kueri Anda.
- Untuk memperbaiki masalah ini, hilangkan penggunaan konversi implisit. Dalam kasus kami, kami menggunakan [CustomerID ] SUKA ‘487%’, kami dapat memperbaikinya dengan mengubah [CustomerID ] =487. Memperbaiki kueri akan mengubah rencana eksekusi kueri, menghapus peringatan sebelumnya, dan mengubah operator pemindaian indeks menjadi pencarian indeks. Pada akhirnya, kinerja meningkat.
Akhir yang bahagia? Ya!
Bawa Pulang
Seperti yang ditunjukkan, kita tidak bisa membiarkan SQL Server melakukan konversi dengan konversi implisit. Saya menyarankan Anda untuk mengikuti prioritas saat memutuskan apa yang akan digunakan saat mengonversi data.
- Pertama, jika Anda hanya perlu mengonversi apa adanya, gunakan CAST (). Ini adalah fungsi yang lebih terstandarisasi saat melakukan porting ke RDBM lain.
- Kedua, jika Anda membutuhkan data yang diformat, gunakan CONVERT ().
- Ketiga, jika keduanya CAST () dan KONVERSI () gagal melakukan tugas, gunakan PARSE ().
- Terakhir, untuk menguji kesalahan saat mengonversi, gunakan TRY_CAST (), COBA_KONVERSI (), atau COBA_PARSE ().
Yah, itu saja untuk saat ini. Saya harap ini membantu Anda dengan petualangan pengkodean Anda berikutnya. Patah kaki!
Untuk mempelajari lebih lanjut tentang topik konversi data SQL dari Microsoft:
- CAST dan CONVERT
- PARSE
- TRY_CAST, TRY_CONVERT, dan TRY_PARSE