SQL Server Insert Into - Cara mengidentifikasi kolom yang menyebabkan kesalahan pemotongan

11

Saya memiliki prosedur tersimpan yang memasukkan 650 bidang ke dalam tabel. Sisipan gagal dengan kesalahan pemotongan.

Sederhana saja

INSERT INTO
SELECT (a bunch of fields) 
FROM (a bunch of tables)

Di bawah ini adalah pesan kesalahan:

Msg 8152, Level 16, Negara 14, Prosedur DSP_Procedure, Line 1075 String atau data biner akan terpotong.

Apakah ada cara cepat untuk mengidentifikasi bidang apa yang menyebabkan kesalahan pemotongan?

Fakta bahwa pernyataan pilih yang akan dimasukkan ke dalam tabel memiliki 650 bidang membuatnya sulit untuk menentukan bidang mana yang menyebabkan kesalahan pemotongan.

Saya pikir saya mungkin dapat mengomentari blok bidang pada suatu waktu sehingga hanya memiliki SP memasukkan 100 bidang pada suatu waktu dan kemudian menjalankan SP 6 atau 7 waktu yang berbeda sampai saya setidaknya dapat mempersempit ke sekelompok 100 bidang yang akan berisi bidang yang menyebabkan kesalahan pemotongan.

Atau saya berpikir bahwa mungkin saya bisa hanya SELECT INTOtabel baru dan kemudian membandingkan panjang data dalam tabel vs panjang data tabel target yang saya coba masukkan ke dalam SP saya untuk melihat bidang mana yang berisi panjang bidang lebih panjang dari yang diharapkan. ..

Saya menggunakan SQL Server 2014.

Adakah alternatif yang lebih mudah?

Juan Velez
sumber
1
Saya akan pergi ke INFORMATION_SCHEMA.COLUMNS dan membandingkan tipe data dengan yang Anda coba masukkan. Sayangnya SQL server tidak memiliki tipe data dinamis untuk deklarasi variabel seperti ORACLE.
MguerraTorres
2
Saya akan menggunakan opsi kedua Anda, masukkan ke dalam tabel (atau #temp) baru dan kemudian membandingkan panjang kolom. Atau Anda dapat membungkus LEN () di sekitar semua kolom pada kolom pilih dan kemudian minta bagian luar melakukan MAX () untuk masing-masing ... yang akan memberi Anda panjang teks terbesar untuk bidang tersebut. Tentu saja, itu mengasumsikan itu bidang char yang memberi Anda masalah. Tidak menggunakan smalldatetime atau tinyint?
Jonathan Fite
1
Saya akan pergi dengan pendekatan "Pilih Ke" dan membandingkan panjang kolom, ya. Mungkin dengan "WHERE 1 = 0" sehingga tabel tidak memiliki baris. Canggung jika SELECT Anda tidak menyertakan nama unik untuk kolom yang dipilih. Saya memformat daftar kolom panjang sebagai satu baris skrip per kolom, lalu nama kolom "AS" pada baris berikutnya jika diperlukan, dan baris kosong setelah empat kolom untuk membuatnya lebih mudah untuk tetap berada dalam daftar. Itu juga mendukung memilih banyak baris dan melakukan Ctrl + K Ctrl + C untuk mengubahnya ke komentar, sehingga Anda bisa menyerang operasi Sisipan seperti itu, tetapi kolom yang ditinggalkan harus nullable.
Robert Carnegie

Jawaban:

9

Sayangnya, Anda telah menjumpai "fitur" yang cukup lama . Sudah ada tiket Connect yang dibuka sejak 2008, dan selama hampir sepuluh tahun ini belum cukup signifikan untuk menjamin perbaikan.

Solusi standarnya , seperti yang Anda bayangkan, select into...diikuti dengan membandingkan tabel metadata. Kemungkinan lain adalah pencarian biner pada kolom yang menyinggung, tetapi itu juga pekerjaan manual. Ada beberapa peretasan untuk perbandingan metadata, tetapi solusi sederhana dan elegan tidak ada. Mungkin beberapa alat pihak ketiga bisa membantu, tapi saya tidak menyadarinya.

vonPryz
sumber
1

Menggunakan (QUERYTRACEON 460) tidak berfungsi untuk saya saat meletakkannya di akhir permintaan saya.

Saya menyalakannya di tingkat DB dan berhasil:

DBCC TRACEON(460, -1);
GO

Tapi, pastikan untuk mematikannya setelah Anda menemukan dan memperbaiki masalah, jangan biarkan!

DBCC TRACEOFF(460, -1);
GO
Taylor Brown
sumber