Perilaku ini berbeda ketika membandingkan antara kolom dan konstanta dengan jenis data dalam SQL Server 7.0 dan versi SQL Server

Terjemahan Artikel Terjemahan Artikel
ID Artikel: 271566 - Melihat produk di mana artikel ini berlaku.
Perbesar semua | Perkecil semua

GEJALA

SQL Server 2000 perilaku berbeda dari versi sebelumnya SQL Server ketika permintaan yang melibatkan perbandingan antara kolom dan konstanta dengan data yang berbeda jenis dijalankan. Anda dapat mengharapkan hasil dan kinerja perbedaan karena cara konversi tipe data ditentukan dibandingkan dengan rilis yang lebih awal dari SQL Server.

Dalam SQL Server versi 7.0 dan sebelumnya, setiap kali query menggunakan operator perbandingan antara kolom dan harfiah, tipe data kolom digunakan terlepas dari urutan protokoler aturan. Yaitu, jika kolom dan harfiah memiliki jenis data, kedua adalah selalu menjadi tipe data kolom (selama konversi ini berlaku). Perilaku ini dapat mengakibatkan pengurangan presisi yang tidak dikehendaki, string pemotongan, atau konversi lain.

Dalam SQL Server 2000, ini adalah tidak lagi benar. Konversi dilakukan menurut data jenis didahulukan, sebagai Hal ini dalam perbandingan lain. Dalam kasus di mana harfiah diposisikan lebih tinggi dalam hirarki, perbandingan dibuat antara konstan dan dikonversi kolom (dibandingkan dengan versi sebelumnya) dan oleh karena itu, hasil mungkin berbeda. Akibatnya, ada indeks mungkin tidak berguna, rencana eksekusi berbeda mungkin dipilih, dan kinerja dapat berdampak negatif.

CatatanSQL Server 2005 dan versi terbaru dari program meliputi perbaikan untuk menangani perbandingan tipe data numerik. Selain skenario varchar/nvarchar, semua skenario yang dijelaskan dalam artikel ini tidak berlaku untuk SQL Server 2005 dan versi yang lebih baru. Namun, Microsoft masih merekomendasikan bahwa Anda dengan benar sesuai tipe data ketika Anda melakukan perbandingan data dan bergabung.

TEKNIK PEMECAHAN MASALAH

Meskipun perilaku baru ini menyediakan konsistensi antara perbandingan dalam SQL Server, itu dapat menimbulkan masalah kompatibilitas aplikasi yang mengandalkan semantik tua. Anda dapat memaksa SQL Server 2000 untuk berperilaku dengan cara yang sama seperti versi sebelumnya dari SQL Server dengan melakukan salah satu dari berikut:
  • Secara eksplisit melemparkan konstanta yang perlu diubah menjadi ( sesuai dengan data jenis kolom).

    -atau-

  • Set tingkat kompatibilitas database 70 dengan menggunakan sp_dbcmptlevel.
Tingkat kompatibilitas harus dilihat hanya sebagai konfigurasi pilihan dirancang untuk kelancaran proses migrasi dari versi sebelumnya. Cara yang direkomendasikan untuk mendapatkan konversi konstan dan tidak dari kolom adalah melalui pemain eksplisit, menggunakan fungsi CONVERT atau pemain.

Catatan Pertanyaan yang digunakan untuk menjalankan dengan indeks efisien berusaha Mei sekarang Gunakan indeks scan atau tabel scan. Lebih tinggi CPU waktu, eksekusi kali, atau I/O mungkin bukti bahwa Anda sedang negatif dipengaruhi oleh perilaku baru. Microsoft sangat menganjurkan bahwa Anda menggunakan cetakan eksplisit dalam kasus ini.

Catatan Perilaku ini tidak berlaku untuk operator seperti. Itu berlaku untuk perbandingan operator (kesetaraan, ketidakadilan, lebih besar dari, dan sebagainya) IN dan antara.

INFORMASI LEBIH LANJUT

Perubahan perilaku dalam SQL Server 2000 mengenai Perbandingan kolom dan konstanta memiliki beberapa implikasi yang diharapkan hasil dibandingkan dengan rilis sebelumnya, seperti:
  • Hasil Kueri
  • Permintaan pelaksanaan rencana, indeks pilihan, dan Kinerja
  • Kondisi kesalahan

Hasil query

Pertimbangkan skenario berikut ini:
create table T1 (col1 int NOT NULL)
go
insert T1 values (1)
insert T1 values (2)
insert T1 values (3)
go
Jika Anda menjalankan query berikut pada SQL Server versi 7.0 (atau lebih awal) atau pada SQL Server 2000 dengan database diatur ke 70 tingkat kompatibilitas, Anda menerima hasil sebagai berikut:
select * from T1 where col1=2.3

col1        
----------- 
2

(1 row(s) affected)
Jika Anda menjalankan kueri yang sama pada SQL Server 2000 menggunakan default tingkat kompatibilitas (80), Anda menerima hasil sebagai berikut:
col1        
----------- 

(0 row(s) affected)
Dalam kasus pertama, 2.3 ditaubatkan untuk int nilai (menghasilkan 2 akibatnya) dan query dijalankan sebagai ".. .dimana col1 = 2," kembali satu baris karena konstanta selalu menjadi data jenis kolom.

Dalam kedua kasus, konstan 2.3 adalah diidentifikasi sebagai angka perkiraan yang lebih tinggi dalam hirarki tipe data dari kolom yang dinyatakan sebagai int. Oleh karena itu, query dievaluasi sebagai "convert(decimal(2,1), col1) = 2.3 "dan tidak ada baris kembali. Jika Anda ingin SQL Server 2000 berperilaku sebagai Versi sebelumnya lakukan, kemudian menulis ulang kueri sebagai:
select * from T1 where col1=convert(int,2.3)
Situasi yang sama berlaku untuk jenis data lainnya juga. Sebagai contoh, perbandingan antara kolom char tipe data dan konstan Unicode mungkin akan menghasilkan hasil yang berbeda SQL Server 7.0 dan SQL Server 2000.

Rencana eksekusi query, indeks pilihan, dan kinerja

Sebagaimana dinyatakan sebelumnya, dalam beberapa kasus kolom dapat dikonversi ke data lain jenis untuk melakukan perbandingan tergantung pada data jenis menjadi dibandingkan. Ini berarti bahwa permintaan dengan predikat seperti "<column> = <literal>"diperlakukan".. .convert<(other_data_type>, <column)>= <literal>"dan pelaksanaan rencana untuk sebuah variasi mungkin berubah secara signifikan.</literal> </column)> </(other_data_type> </literal> </column>

Pertimbangkan skenario berikut ini:
create table T3 (col1 char(10) NOT NULL)
go
insert T3 values ('a')
insert T3 values ('b')
insert T3 values ('c')
go
create clustered index CIT3 on T3(col1)
Query berikut pada SQL Server versi 7.0 atau SQL Server 2000 dengan kompatibilitas 70 database tingkat dijalankan dengan menggunakan indeks mencari nilai tertentu:
select * from T3 where col1=N'a'

  |--Clustered Index Seek(OBJECT:([Northwind].[dbo].[T3].[CIT3]), SEEK:([T3].[col1]=Convert([@1])) ORDERED FORWARD)
Di bawah tingkat kompatibilitas 80, SQL Server 2000 menggunakan indeks memindai, yang mengakibatkan lebih tinggi I/O, penggunaan CPU, dan jangka waktu.
|--Clustered Index Scan(OBJECT:([Northwind].[dbo].[T3].[CIT3]), WHERE:(Convert([T3].[col1])=[@1]))
Pertimbangkan skenario lain:
create table T1 
(col1 int NOT NULL) 
go 
insert T1 values (1) 
insert T1 values (2) 
insert T1 values (3) 
go 
create clustered index clustind on T1(col1)  
Query berikut pada SQL Server 7.0 atau SQL Server 2000 dengan tingkat kompatibilitas 70 database memberi kita permintaan rencana di bawah ini.
Select * from T1 where col1 = 1
 
|--Clustered Index Seek(OBJECT:([master].[dbo].[T1].[clustind]), SEEK:([T1].[col1]=[@1]) ORDERED) 
Di bawah tingkat kompatibilitas 80, SQL Server 2000 mengkonversi 1 harfiah jenis data yang sama seperti Col1 kolom. Oleh karena itu, waktunya akan diubah ke int.

Jenis dasar diasumsikan 1 harfiah adalah tinyint. The tinyint jenis data adalah yang terendah dalam urutan protokoler tipe data dalam keluarga bilangan bulat.

Ini memungkinkan Anda dapat mengkonversi literal untuk tipe data kolom tanpa hilangnya presisi.
Select * from T1 where col1 = 1
 
|--Clustered Index Seek(OBJECT:([pubs].[dbo].[T1].[clustind]), SEEK:([T1].[col1]=Convert([@1])) ORDERED FORWARD)

Jika konversi terjadi antara tipe data numerik, kesetaraan Perbandingan dijalankan sebagai mencari berbagai diikuti oleh perbandingan (dari kembali berbagai) dengan konstan. Ini memiliki konsekuensi negatif dari Disallowing penggunaan kolom tambahan pada indeks komposit, seperti dalam skenario berikut:
create table T4 (col1 int NOT NULL, col2 int NOT NULL)

insert T4 values (1,1)
insert T4 values (1,2)
insert T4 values (1,3)

create clustered index CIT4 on T4(col1, col2)
Menjalankan query berikut dengan perilaku sebelumnya menghasilkan mencari indeks pada dua kolom:
select * from T4 where col1=1.1 and col2=2

|--Clustered Index Seek(OBJECT:([Northwind].[dbo].[T4].[CIT4]),
SEEK:([T4].[col1]=Convert([@1]) AND [T4].[col2]=Convert([@2])) ORDERED FORWARD)
Di bawah SQL Server 2000 dengan tingkat 80 kompatibilitas, rencana termasuk kisaran indeks yang mencari di kolom pertama hanya, diikuti oleh join bersarang loop dengan terus-menerus menemukan baris pencocokan. (Perhatikan bahwa rencana lengkap tidak ditampilkan.)
|--Clustered Index Seek(OBJECT:([Northwind].[dbo].[T4].[CIT4]),
SEEK:([T4].[col1] > [Expr1004] AND [T4].[col1] < [Expr1005]),
WHERE:([T4].[col2]=Convert([@2]) AND Convert([T4].[col1])=Convert([@1]))
ORDERED FORWARD)

Kondisi kesalahan

Perilaku perbandingan baru juga mungkin mengizinkan permintaan yang digunakan untuk gagal pada versi sebelumnya. Pertimbangkan skenario berikut ini:
create table T5 (col1 tinyint NOT NULL)
go
insert T5 values (1)
insert T5 values (2)
go
Jika Anda menjalankan query berikut, kesalahan dibesarkan di bawah sebelumnya perilaku karena SQL Server upaya untuk mengubah terus-menerus 300 ke tinyint nilai:
select * from T5 where col1= 300
Result:
Server: Msg 220, Level 16, State 2, Line 1
Arithmetic overflow error for data type tinyint, value = 300.
Di bawah SQL Server 2000 (diatur ke tingkat kompatibilitas 80), permintaan berjalan karena tinyint kolom dikonversi ke yang lebih besar bilangan bulat tipe data:
col1 
---- 

(0 row(s) affected)

Sumber daya tambahan

Untuk mengubah tingkat kompatibilitas database, gunakan sp_dbcmptlevel prosedur yang tersimpan. Untuk informasi lebih lanjut, lihat "sp_dbcmptlevel" dan "Database kompatibilitas tingkat pilihan" topik di SQL Server Buku secara Online.

Untuk informasi lebih lanjut tentang data jenis didahulukan hirarki, lihat topik "Data jenis didahulukan" dalam SQL Server buku Online.

Untuk informasi lebih lanjut tentang menggunakan literal pada SQL Server, lihat "Konstanta" topik dalam SQL Server buku Online.

Properti

ID Artikel: 271566 - Kajian Terakhir: 05 Oktober 2011 - Revisi: 3.0
Berlaku bagi:
  • Microsoft SQL Server 7.0 Standard Edition
  • Microsoft SQL Server 2000 Standard Edition
  • Microsoft SQL Server 2005 Standard Edition
  • Microsoft SQL Server 2005 Developer Edition
  • Microsoft SQL Server 2005 Enterprise Edition
  • Microsoft SQL Server 2005 Express Edition
  • Microsoft SQL Server 2005 Workgroup Edition
Kata kunci: 
kbprb kbmt KB271566 KbMtid
Penerjemahan Mesin
PENTING: Artikel ini diterjemahkan menggunakan perangkat lunak mesin penerjemah Microsoft dan bukan oleh seorang penerjemah. Microsoft menawarkan artikel yang diterjemahkan oleh seorang penerjemah maupun artikel yang diterjemahkan menggunakan mesin sehingga Anda akan memiliki akses ke seluruh artikel baru yang diterbitkan di Pangkalan Pengetahuan (Knowledge Base) dalam bahasa yang Anda gunakan. Namun, artikel yang diterjemahkan menggunakan mesin tidak selalu sempurna. Artikel tersebut mungkin memiliki kesalahan kosa kata, sintaksis, atau tata bahasa, hampir sama seperti orang asing yang berbicara dalam bahasa Anda. Microsoft tidak bertanggung jawab terhadap akurasi, kesalahan atau kerusakan yang disebabkan karena kesalahan penerjemahan konten atau penggunaannya oleh para pelanggan. Microsoft juga sering memperbarui perangkat lunak mesin penerjemah.
Klik disini untuk melihat versi Inggris dari artikel ini:271566

Berikan Masukan

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com