Saya terjebak dalam perdebatan di tempat kerja, dan saya butuh nasihat tentang kemungkinan Perangkap yang mungkin saya abaikan.
Bayangkan skenario di mana Pemicu digunakan untuk menyalin Catatan yang Dihapus ke Tabel Audit. Pemicu menggunakan SELECT *. Semua orang menunjuk dan berteriak dan mengatakan betapa buruknya hal ini.
Namun, jika modifikasi dibuat ke Struktur Tabel Utama, dan Tabel Audit diabaikan maka Pemicu akan menghasilkan kesalahan membiarkan orang tahu tabel Audit juga perlu modifikasi.
Kesalahan akan ditangkap saat pengujian pada server DEV kami. Tetapi kita perlu memastikan Production Matches DEV, jadi kami mengizinkan SELECT * dalam Sistem Produksi (hanya Pemicu).
Jadi Pertanyaan saya adalah: Saya didorong untuk menghapus SELECT *, tetapi saya tidak yakin bagaimana lagi untuk memastikan bahwa kami secara otomatis menangkap Kesalahan Pengembangan seperti ini, ada ide atau ini praktik terbaik?
Saya telah mengumpulkan contoh di bawah ini:
--Create Test Table
CREATE TABLE dbo.Test(ID INT IDENTITY(1,1), Person VARCHAR(255))
--Create Test Audit Table
CREATE TABLE dbo.TestAudit(AuditID INT IDENTITY(1,1),ID INT, Person VARCHAR(255))
--Create Trigger on Test
CREATE TRIGGER [dbo].[trTestDelete] ON [dbo].[Test] AFTER DELETE
NOT FOR REPLICATION
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TestAudit([ID], [Person])
SELECT *
FROM deleted
END
--Insert Test Data into Test
INSERT INTO dbo.Test VALUES
('Scooby')
,('Fred')
,('Shaggy')
--Perform a delete
DELETE dbo.Test WHERE Person = 'Scooby'
PEMBARUAN (ulangi pertanyaan):
Saya seorang DBA dan perlu memastikan Pengembang tidak memberikan skrip Penerapan yang dipikirkan dengan buruk dengan berkontribusi pada Dokumentasi Praktik Terbaik kami. SELECT * menyebabkan kesalahan pada DEV ketika Pengembang mengabaikan Tabel Audit (ini adalah jaring pengaman) sehingga kesalahan tersebut diketahui di awal proses pengembangan. Tetapi di suatu tempat dalam Konstitusi SQL - amandemen ke-2 berbunyi "Jangan gunakan SELECT *". Jadi sekarang ada dorongan untuk menyingkirkan Safety Net.
Bagaimana Anda mengganti Jaring Pengaman, atau haruskah saya menganggap ini sebagai praktik terbaik untuk Pemicu?
PEMBARUAN 2: (solusi)
Terima kasih atas semua masukan Anda, saya tidak yakin apakah saya memiliki jawaban yang jelas karena ini tampaknya menjadi subjek yang sangat abu-abu. Namun secara kolektif Anda telah memberikan poin diskusi yang dapat membantu pengembang kami maju dengan menetapkan Praktik Terbaik mereka.
Terima kasih Daevin
atas kontribusi Anda, jawaban Anda memberikan dasar untuk beberapa mekanisme pengujian yang dapat diterapkan oleh Pengembang kami. +1
Terima kasih CM_Dayton
, saran Anda yang berkontribusi pada praktik terbaik dapat bermanfaat bagi siapa saja yang memicu Pemicu Audit. +1
Terima kasih banyak ypercube
, Anda telah banyak memikirkan masalah tentang tabel yang mengalami berbagai bentuk perubahan definisi. +1
Kesimpulannya:
Is Select * ok in a tigger?
Ya, ini wilayah abu-abu, jangan membabi buta mengikuti ideologi "Select * is Bad".
Am I asking for Trouble?
Ya, kami melakukan lebih dari sekadar menambahkan kolom baru ke tabel.
sumber
SELECT *
yang malas, tetapi karena Anda memiliki alasan yang sah untuk menggunakannya, itu lebih abu-abu daripada hitam-putih. Apa yang harus Anda coba lakukan adalah sesuatu seperti ini , tetapi sesuaikan agar tidak hanya memiliki jumlah kolom yang sama, tetapi bahwa nama kolom dan tipe data adalah sama (karena seseorang dapat mengubah tipe data dan masih menyebabkan masalah dalam db yang biasanya tidak ditangkap denganSELECT *
'jaring pengaman' AndaSELECT *
sebagai jaring pengaman tetapi tidak akan menangkap semua kasus. Misalnya, jika Anda menjatuhkan kolom dan menambahkannya lagi. Ini akan mengubah urutan kolom dan (kecuali semua kolom dari jenis yang sama) memasukkan ke dalam tabel audit akan gagal atau mengakibatkan hilangnya data karena konversi tipe implisit.Jawaban:
Biasanya, itu dianggap pemrograman "malas".
Mengingat bahwa Anda secara khusus memasukkan dua nilai ke dalam
TestAudit
tabel Anda di sini, saya akan berhati-hati untuk memastikan bahwa pilihan Anda juga mendapatkan tepat dua nilai. Karena jika, karena alasan tertentu,Test
tabel itu memiliki atau pernah mendapat kolom ketiga, pemicu ini akan gagal.Tidak terkait langsung dengan pertanyaan Anda tetapi jika Anda menyiapkan tabel audit, saya juga akan menambahkan beberapa kolom tambahan ke
TestAudit
meja Anda ke ...Sehingga menghasilkan kueri seperti:
Dengan cara itu Anda mendapatkan kolom persis yang Anda butuhkan dan diaudit tentang apa / kapan / mengapa / siapa acara audit itu.
sumber
Saya mengomentari ini pada pertanyaan Anda, tetapi saya pikir saya akan mencoba untuk benar-benar menyajikan solusi kode.
Saya biasanya setuju dengan
SELECT *
menjadi malas, tetapi karena Anda memiliki alasan yang sah untuk menggunakannya, itu lebih abu-abu daripada hitam-putih.Apa yang harus Anda coba (menurut saya) coba lakukan adalah sesuatu seperti ini , tetapi sesuaikan untuk memastikan nama kolom dan tipe data sama (karena seseorang dapat mengubah tipe data dan masih menyebabkan masalah dalam db yang biasanya tidak ditangkap oleh Anda
SELECT *
keselamatan ' bersih'.Anda bahkan dapat membuat fungsi yang akan memungkinkan Anda dengan cepat memeriksa apakah versi Audit tabel cocok dengan versi non-audit:
The
SELECT ... EXCEPT SELECT ...Audit
akan menunjukkan apa kolom dalam tabel yang tidak ada dalam tabel Audit. Anda bahkan dapat mengubah fungsi untuk mengembalikan nama kolom yang tidak sama, bukan hanya apakah mereka memetakan atau tidak, atau bahkan meningkatkan pengecualian.Anda kemudian dapat menjalankan ini sebelum pindah dari
DEV
kePRODUCTION
server untuk setiap tabel di db, menggunakan kursor di atas:sumber
Pernyataan yang akan mengeluarkan pemicu akan gagal dan pemicu akan gagal. Akan lebih baik untuk mendokumentasikan jejak dan audit jejak sehingga Anda tahu untuk memodifikasi kueri untuk menambahkan kolom daripada menentukan *.
Paling tidak Anda harus memodifikasi pemicu sehingga bisa gagal dengan anggun saat mencatat kesalahan ke sebuah tabel dan mungkin memberi peringatan pada tabel pemicu yang mencatat kesalahan.
Ini juga mengingatkan Anda, Anda dapat menempatkan pemicu atau peringatan ketika seseorang mengubah tabel dan menambahkan lebih banyak kolom atau menghapus kolom, untuk memberi tahu Anda untuk menambahkan pemicu.
Menurut saya, kinerja * tidak mengubah apa-apa, itu hanya meningkatkan kemungkinan kegagalan saat terjadi perubahan dan juga dapat menyebabkan latensi jaringan saat Anda menarik lebih banyak informasi di jaringan saat diperlukan. Ada waktu dan tempat untuk *, tetapi saya merasa seperti dijelaskan di atas Anda memiliki solusi dan alat yang lebih baik untuk dicoba.
sumber
Jika struktur tabel orisinal atau audit Anda berubah sama sekali, Anda menjamin bahwa Anda akan mengalami masalah dengan * pilihan Anda.
Jika salah satu berubah, pemicu akan kesalahan.
Anda bisa melakukannya:
Tapi seperti kata CM_Dayton, itu pemrograman yang malas dan membuka pintu bagi ketidakkonsistenan lainnya. Agar skenario ini berfungsi, Anda harus benar-benar memastikan bahwa Anda memperbarui struktur kedua tabel secara bersamaan.
sumber