Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Dasar-dasar ekspresi tabel, Bagian 10 – Tampilan, SELECT *, dan perubahan DDL

Sebagai bagian dari seri ekspresi tabel, bulan lalu saya memulai liputan penayangan. Secara khusus, saya memulai cakupan aspek logis dari tampilan, dan membandingkan desainnya dengan tabel turunan dan CTE. Bulan ini saya akan melanjutkan liputan aspek logis dari pandangan, memusatkan perhatian saya pada SELECT * dan perubahan DDL.

Kode yang akan saya gunakan dalam artikel ini dapat dieksekusi di database apa pun, tetapi dalam demo saya, saya akan menggunakan TSQLV5—contoh database yang sama yang saya gunakan di artikel sebelumnya. Anda dapat menemukan skrip yang membuat dan mengisi TSQLV5 di sini, dan diagram ER-nya di sini.

Menggunakan SELECT * dalam kueri dalam tampilan adalah ide yang buruk

Di bagian kesimpulan artikel bulan lalu saya mengajukan pertanyaan sebagai bahan untuk dipikirkan. Saya menjelaskan bahwa sebelumnya dalam seri saya membuat kasus yang mendukung penggunaan SELECT * dalam ekspresi tabel bagian dalam yang digunakan dengan tabel turunan dan CTE. Lihat Bagian 3 dalam seri untuk detailnya jika Anda perlu menyegarkan ingatan Anda. Saya kemudian meminta Anda untuk berpikir apakah rekomendasi yang sama akan tetap valid untuk ekspresi tabel dalam yang digunakan untuk mendefinisikan tampilan. Mungkin judul bagian ini sudah spoiler, tapi saya akan mengatakan benar bahwa dengan pandangan itu sebenarnya ide yang sangat buruk.

Saya akan mulai dengan tampilan yang tidak ditentukan dengan atribut SCHEMABINDING, yang mencegah perubahan DDL yang relevan ke objek dependen, dan kemudian menjelaskan bagaimana hal-hal berubah saat Anda menggunakan atribut ini.

Saya akan langsung ke contoh karena ini akan menjadi cara termudah untuk mempresentasikan argumen saya.

Gunakan kode berikut untuk membuat tabel bernama dbo.T1, dan tampilan bernama dbo.V1 berdasarkan kueri dengan SELECT * terhadap tabel:

GUNAKAN TSQLV5; DROP VIEW JIKA ADA dbo.V1;DROP TABLE JIKA ADA dbo.T1;GO CREATE TABLE dbo.T1( keycol INT NOT NULL IDENTITY CONSTRAINT PK_T1 PRIMARY KEY, intcol INT NOT NULL, charcol VARCHAR(10) NOT NULL); INSERT INTO dbo.T1(intcol, charcol) VALUES (10, 'A'), (20, 'B');GO CREATE OR ALTER VIEW dbo.V1AS SELECT * FROM dbo.T1;GO

Perhatikan bahwa tabel saat ini memiliki kolom keycol, intcol dan charcol.

Gunakan kode berikut untuk menanyakan tampilan:

PILIH * DARI dbo.V1;

Anda mendapatkan output berikut:

keycol intcol charcol----------- ----------- ----------1 10 A2 20 B

Tidak ada yang terlalu istimewa di sini.

Saat Anda membuat tampilan, SQL Server merekam informasi metadata di sejumlah objek katalog. Ini mencatat beberapa informasi umum, yang dapat Anda kueri melalui sys.views, definisi tampilan yang dapat Anda kueri melalui sys.sql_modules, informasi kolom yang dapat Anda kueri melalui sys.columns, dan informasi lebih lanjut tersedia melalui objek lain. Yang juga relevan dengan diskusi kita adalah SQL Server memungkinkan Anda mengontrol izin akses terhadap tampilan. Yang ingin saya peringatkan saat menggunakan SELECT * dalam ekspresi tabel bagian dalam tampilan, adalah apa yang dapat terjadi saat perubahan DDL diterapkan ke objek dependen yang mendasarinya.

Gunakan kode berikut untuk membuat pengguna bernama user1 dan berikan izin kepada pengguna untuk memilih kolom keycol dan intcol dari tampilan, tetapi bukan charcol:

HAPUS PENGGUNA JIKA ADA user1; BUAT PENGGUNA pengguna1 TANPA LOGIN; HIBAH PILIH PADA dbo.V1(keycol, intcol) KEPADA user1;

Pada titik ini, mari kita periksa beberapa metadata yang direkam terkait dengan pandangan kita. Gunakan kode berikut untuk mengembalikan entri yang mewakili tampilan dari sys.views:

SELECT SCHEMA_NAME(schema_id) AS nama skema, nama, object_id, type_descFROM sys.viewsWHERE object_id =OBJECT_ID(N'dbo.V1');

Kode ini menghasilkan output berikut:

nama skema nama_objek type_desc----------- ----- ----------- ----------dbo V1 130099504 LIHAT 

Gunakan kode berikut untuk mendapatkan definisi tampilan dari sys.modules:

PILIH definisi FROM sys.sql_modulesWHERE object_id =OBJECT_ID(N'dbo.V1');

Pilihan lain adalah dengan menggunakan fungsi OBJECT_DEFINITION seperti:

SELECT OBJECT_DEFINITION(OBJECT_ID(N'dbo.V1'));

Anda mendapatkan output berikut:

BUAT TAMPILAN dbo.V1AS SELECT * FROM dbo.T1;

Gunakan kode berikut untuk menanyakan definisi kolom tampilan dari sys.columns:

SELECT name AS column_name, column_id, TYPE_NAME(system_type_id) AS data_typeFROM sys.columnsWHERE object_id =OBJECT_ID(N'dbo.V1');

Seperti yang diharapkan, Anda mendapatkan informasi tentang tampilan tiga kolom keycol, intcol dan charcol:

column_name column_id data_type------------ ----------- ----------keycol 1 intintcol 2 intcharcol 3 varchar

Amati ID kolom (posisi ordinal) yang terkait dengan kolom.

Anda bisa mendapatkan informasi serupa dengan menanyakan tampilan skema informasi standar INFORMATION_SCHEMA.COLUMNS, seperti:

PILIH COLUMN_NAME, ORDINAL_POSITION, DATA_TYPEFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_SCHEMA =N'dbo' AND TABLE_NAME =N'V1';

Untuk mendapatkan informasi ketergantungan tampilan (objek yang dirujuk), Anda dapat menanyakan sys.dm_sql_referenced_entities, seperti:

SELECT OBJECT_NAME(referenced_id) AS referenced_object, referenced_minor_id, COL_NAME(referenced_id, referenced_minor_id) AS column_nameFROM sys.dm_sql_referenced_entities(N'dbo.V1', N'OBJECT');

Anda akan menemukan ketergantungan pada tabel T1 dan pada tiga kolomnya:

referenced_object referenced_minor_id column_name------------------ ------------------- ------- ----T1 0 NULLT1 1 keycolT1 2 intcolT1 3 charcol

Seperti yang mungkin bisa Anda tebak, nilai reference_minor_id untuk kolom adalah ID kolom yang Anda lihat sebelumnya.

Jika Anda ingin mendapatkan izin pengguna1 terhadap V1, Anda dapat menanyakan sys.database_permissions, seperti:

SELECT OBJECT_NAME(major_id) AS referenced_object, minor_id, COL_NAME(major_id, minor_id) AS column_name, permission_nameFROM sys.database_permissionsWHERE major_id =OBJECT_ID(N'dbo.V1') AND grantee_principal_ID(N' =USER1'); 

Kode ini menghasilkan output berikut, menegaskan bahwa memang user1 memiliki izin pilih hanya terhadap keycol dan intcol, tetapi tidak terhadap charcol:

referenced_object minor_id column_name permission_name------------------ ----------- ------------ -- --------------V1 1 keycol SELECTV1 2 intcol SELECT

Sekali lagi, nilai minor_id adalah ID kolom yang Anda lihat sebelumnya. Pengguna kami, pengguna1, memiliki izin ke kolom yang ID-nya adalah 1 dan 2.

Selanjutnya, jalankan kode berikut untuk meniru identitas pengguna1 dan mencoba dan menanyakan semua kolom V1:

EKSEKUSI SEBAGAI PENGGUNA =N'user1'; PILIH * DARI dbo.V1;

Seperti yang Anda harapkan, Anda mendapatkan kesalahan izin karena kurangnya izin untuk menanyakan charcol:

Msg 230, Level 14, State 1, Line 141
Izin SELECT ditolak pada kolom 'charcol' objek 'V1', database 'TSQLV5', skema 'dbo'.

Coba tanyakan hanya keycol dan intcol:

PILIH keycol, intcol DARI dbo.V1;

Kali ini kueri berhasil dijalankan, menghasilkan output berikut:

keycol intcol----------- -----------1 102 20

Tidak ada kejutan sejauh ini.

Jalankan kode berikut untuk kembali ke pengguna asli Anda:

KEMBALIKAN;

Sekarang mari kita terapkan beberapa perubahan struktural pada tabel yang mendasarinya dbo.T1. Jalankan kode berikut untuk pertama menambahkan dua kolom yang disebut datecol dan binarycol, dan kemudian untuk menjatuhkan kolom intcol:

ALTER TABLE dbo.T1 ADD datecol TANGGAL NOT NULL DEFAULT('99991231'), binarycol VARBINARY(3) NOT NULL DEFAULT(0x112233); ALTER TABLE dbo.T1 DROP COLUMN intcol;

SQL Server tidak menolak perubahan struktural ke kolom yang direferensikan oleh tampilan karena tampilan tidak dibuat dengan atribut SCHEMABINDING. Sekarang, untuk menangkap. Pada titik ini, SQL Server belum menyegarkan informasi metadata tampilan di objek katalog yang berbeda.

Gunakan kode berikut untuk menanyakan tampilan, masih dengan pengguna asli Anda (belum pengguna1):

PILIH * DARI dbo.V1;

Anda mendapatkan output berikut:

keycol intcol charcol----------- ---------- ----------1 A 9999-12-312 B 9999-12-31 

Perhatikan bahwa intcol sebenarnya mengembalikan konten charcol dan charcol mengembalikan konten datecol. Ingat, tidak ada intcol di tabel lagi tetapi ada datecol. Juga, Anda tidak mendapatkan kembali binarycol kolom baru.

Untuk mencoba dan mencari tahu apa yang terjadi, gunakan kode berikut untuk menanyakan metadata kolom tampilan:

SELECT name AS column_name, column_id, TYPE_NAME(system_type_id) AS data_typeFROM sys.columnsWHERE object_id =OBJECT_ID(N'dbo.V1');

Kode ini menghasilkan output berikut:

column_name column_id data_type------------ ----------- ----------keycol 1 intintcol 2 intcharcol 3 varchar

Seperti yang Anda lihat, metadata tampilan masih belum disegarkan. Anda dapat melihat intcol sebagai ID kolom 2 dan charcol sebagai ID kolom 3. Dalam praktiknya, intcol tidak ada lagi, charcol seharusnya kolom 2, dan datecol seharusnya kolom 3.

Mari kita periksa apakah ada perubahan dengan informasi izin:

SELECT OBJECT_NAME(major_id) AS referenced_object, minor_id, COL_NAME(major_id, minor_id) AS column_name, permission_nameFROM sys.database_permissionsWHERE major_id =OBJECT_ID(N'dbo.V1') AND grantee_principal_ID(N' =USER1'); 

Anda mendapatkan output berikut:

referenced_object minor_id column_name permission_name------------------ ----------- ------------ -- --------------V1 1 keycol SELECTV1 2 intcol SELECT

Info izin menunjukkan bahwa pengguna1 memiliki izin untuk kolom 1 dan 2 dalam tampilan. Namun, meskipun metadata menganggap bahwa kolom 2 disebut intcol, sebenarnya dipetakan ke charcol di T1 dalam praktiknya. Itu berbahaya karena user1 tidak seharusnya memiliki akses ke charcol. Bagaimana jika dalam kehidupan nyata kolom ini menyimpan informasi sensitif seperti sandi.

Mari kita meniru user1 lagi, dan menanyakan semua kolom tampilan:

JALANKAN SEBAGAI PENGGUNA ='pengguna1'; PILIH * DARI dbo.V1;

Anda mendapatkan kesalahan izin yang mengatakan Anda tidak memiliki akses ke charcol:

Msg 230, Level 14, State 1, Line 211
Izin SELECT ditolak pada kolom 'charcol' dari objek 'V1', database 'TSQLV5', skema 'dbo'.

Namun, lihat apa yang terjadi ketika Anda secara eksplisit meminta keycol dan intcol:

PILIH keycol, intcol DARI dbo.V1;

Anda mendapatkan output berikut:

keycol intcol----------- ----------1 A2 B

Kueri ini berhasil, hanya saja ia mengembalikan konten charcol di bawah intcol. Pengguna kami, pengguna1, tidak seharusnya memiliki akses ke informasi ini. Ups!

Pada titik ini, kembali ke pengguna asli dengan menjalankan kode berikut:

KEMBALIKAN;

Segarkan modul SQL

Anda dapat melihat dengan jelas bahwa menggunakan SELECT * dalam ekspresi tabel bagian dalam tampilan adalah ide yang buruk. Tapi bukan hanya itu. Secara umum, merupakan ide bagus untuk menyegarkan metadata tampilan setelah setiap perubahan DDL ke objek dan kolom yang direferensikan. Anda dapat melakukannya menggunakan sp_refreshview atau sp_refreshmodule yang lebih umum, seperti:

EXEC sys.sp_refreshsqlmodule N'dbo.V1';

Kueri tampilan lagi, sekarang metadatanya telah disegarkan:

PILIH * DARI dbo.V1;

Kali ini Anda mendapatkan hasil yang diharapkan:

keycol charcol datecol binarycol----------- ---------- ---------- ---------1 A 9999 -12-31 0x1122332 B 9999-12-31 0x112233

Kolom charcol diberi nama dengan benar dan menunjukkan data yang benar; Anda tidak melihat intcol, dan Anda melihat kolom baru datecol dan binarycol.

Kueri metadata kolom tampilan:

SELECT name AS column_name, column_id, TYPE_NAME(system_type_id) AS data_typeFROM sys.columnsWHERE object_id =OBJECT_ID(N'dbo.V1');

Output sekarang menunjukkan informasi metadata kolom yang benar:

column_name column_id data_type------------ ----------- ----------keycol 1 intcharcol 2 varchardatecol 3 datebinarycol 4 varbinary 

Minta izin pengguna1 terhadap tampilan:

SELECT OBJECT_NAME(major_id) AS referenced_object, minor_id, COL_NAME(major_id, minor_id) AS column_name, permission_nameFROM sys.database_permissionsWHERE major_id =OBJECT_ID(N'dbo.V1') AND grantee_principal_ID(N' =USER1'); 

Anda mendapatkan output berikut:

referenced_object minor_id column_name permission_name------------------ ----------- ------------ -- -------------- V1 1 keycol PILIH

Informasi izin sekarang benar. Pengguna kami, pengguna1, hanya memiliki izin untuk memilih keycol, dan informasi izin untuk intcol telah dihapus.

Untuk memastikan semuanya baik-baik saja, mari kita uji ini dengan meniru identitas pengguna1 dan menanyakan tampilan:

JALANKAN SEBAGAI PENGGUNA ='pengguna1'; PILIH * DARI dbo.V1;

Anda mendapatkan dua kesalahan izin karena kurangnya izin terhadap datecol dan binarycol:

Msg 230, Level 14, State 1, Line 281
Izin SELECT ditolak pada kolom 'datecol' objek 'V1', database 'TSQLV5', skema 'dbo'.

Msg 230, Level 14, State 1, Line 281
Izin SELECT ditolak pada kolom 'binarycol' dari objek 'V1', database 'TSQLV5', skema 'dbo'.

Coba kueri keycol dan intcol:

PILIH keycol, intcol DARI dbo.V1;

Kali ini kesalahan dengan benar mengatakan bahwa tidak ada kolom bernama intcol:

Pesan 207, Level 16, Negara Bagian 1, Baris 279

Nama kolom 'intcol' tidak valid.

Hanya kueri intcol:

PILIH keycol FROM dbo.V1;

Kueri ini berhasil dijalankan, menghasilkan output berikut:

keycol-----------12

Pada titik ini kembali ke pengguna asli Anda dengan menjalankan kode berikut:

KEMBALIKAN;

Apakah cukup dengan menghindari SELECT * dan menggunakan nama kolom yang eksplisit?

Jika Anda mengikuti praktik yang mengatakan tidak SELECT * dalam ekspresi tabel bagian dalam tampilan, apakah ini cukup untuk membuat Anda keluar dari masalah? Baiklah, mari kita lihat…

Gunakan kode berikut untuk membuat ulang tabel dan tampilan, hanya kali ini daftarkan kolom secara eksplisit dalam kueri dalam tampilan:

DROP VIEW JIKA ADA dbo.V1;DROP TABLE JIKA ADA dbo.T1;GO CREATE TABLE dbo.T1( keycol INT NOT NULL IDENTITY CONSTRAINT PK_T1 PRIMARY KEY, intcol INT NOT NULL, charcol VARCHAR(10) NOT NULL); INSERT INTO dbo.T1(intcol, charcol) VALUES (10, 'A'), (20, 'B');GO CREATE OR ALTER VIEW dbo.V1AS SELECT keycol, intcol, charcol FROM dbo.T1;GO

Kueri tampilan:

PILIH * DARI dbo.V1;

Anda mendapatkan output berikut:

keycol intcol charcol----------- ----------- ----------1 10 A2 20 B

Sekali lagi, berikan izin pengguna1 untuk memilih keycol dan intcol:

BERI PILIH PADA dbo.V1(keycol, intcol) KEPADA user1;

Selanjutnya, terapkan perubahan struktural yang sama seperti yang Anda lakukan sebelumnya:

ALTER TABLE dbo.T1 ADD datecol TANGGAL NOT NULL DEFAULT('99991231'), binarycol VARBINARY(3) NOT NULL DEFAULT(0x112233); ALTER TABLE dbo.T1 DROP COLUMN intcol;

Perhatikan bahwa SQL Server menerima perubahan ini, meskipun tampilan memiliki referensi eksplisit ke intcol. Sekali lagi, itu karena tampilan dibuat tanpa opsi SCHEMABINDING.

Kueri tampilan:

PILIH * DARI dbo.V1;

Pada titik ini SQL Server menghasilkan kesalahan berikut:

Pesan 207, Level 16, Status 1, Prosedur V1, Baris 5 [Batch Start Line 344]
Nama kolom 'intcol' tidak valid.

Msg 4413, Level 16, State 1, Line 345
Tidak dapat menggunakan tampilan atau fungsi 'dbo.V1' karena kesalahan pengikatan.

SQL Server mencoba menyelesaikan referensi intcol dalam tampilan, dan tentu saja tidak berhasil.

Tetapi bagaimana jika rencana awal Anda adalah menjatuhkan intcol dan kemudian menambahkannya kembali? Gunakan kode berikut untuk menambahkannya kembali, lalu kueri tampilan:

ALTER TABLE dbo.T1 ADD intcol INT NOT NULL DEFAULT(0); PILIH * DARI dbo.V1;

Kode ini menghasilkan output berikut:

keycol intcol charcol----------- ----------- ----------1 0 A2 0 B

Hasilnya tampaknya benar.

Bagaimana dengan menanyakan tampilan sebagai user1? Mari kita coba:

JALANKAN SEBAGAI PENGGUNA ='user1';SELECT * FROM dbo.V1;

Saat menanyakan semua kolom, Anda mendapatkan kesalahan yang diharapkan karena kurangnya izin terhadap charcol:

Msg 230, Level 14, State 1, Line 367
Izin SELECT ditolak pada kolom 'charcol' objek 'V1', database 'TSQLV5', skema 'dbo'.

Query keycol dan intcol secara eksplisit:

PILIH keycol, intcol DARI dbo.V1;

Anda mendapatkan output berikut:

keycol intcol----------- -----------1 02 0

Sepertinya semuanya beres berkat fakta bahwa Anda tidak menggunakan SELECT * dalam kueri dalam tampilan, meskipun Anda tidak me-refresh metadata tampilan. Namun, itu bisa menjadi praktik yang baik untuk menyegarkan metadata tampilan setelah DDL berubah menjadi objek dan kolom yang direferensikan agar berada di sisi yang aman.

Pada titik ini, kembali ke pengguna asli Anda dengan menjalankan kode berikut:

KEMBALIKAN;

SCHEMABINDING

Menggunakan atribut tampilan SCHEMABINDING Anda dapat menghemat banyak masalah yang disebutkan di atas. Salah satu kunci untuk menghindari masalah yang Anda lihat sebelumnya adalah tidak menggunakan SELECT * dalam kueri dalam tampilan. Namun ada juga masalah perubahan struktural terhadap objek dependen, seperti menghapus kolom yang direferensikan, yang masih dapat mengakibatkan kesalahan saat mengkueri tampilan. Menggunakan atribut tampilan SCHEMABINDING, Anda tidak akan diizinkan untuk menggunakan SELECT * dalam kueri dalam. Selain itu, SQL Server akan menolak upaya untuk menerapkan perubahan DDL yang relevan ke objek dan kolom yang bergantung. Yang relevan, maksud saya perubahan seperti menjatuhkan tabel atau kolom yang direferensikan. Menambahkan kolom ke tabel yang direferensikan jelas bukan masalah, jadi SCHEMABINDING tidak mencegah perubahan seperti itu.

Untuk mendemonstrasikan ini, gunakan kode berikut untuk membuat ulang tabel dan tampilan, dengan SCHEMABINDING dalam definisi tampilan:

DROP VIEW JIKA ADA dbo.V1;DROP TABLE JIKA ADA dbo.T1;GO CREATE TABLE dbo.T1( keycol INT NOT NULL IDENTITY CONSTRAINT PK_T1 PRIMARY KEY, intcol INT NOT NULL, charcol VARCHAR(10) NOT NULL); INSERT INTO dbo.T1(intcol, charcol) VALUES (10, 'A'), (20, 'B');GO CREATE OR ALTER VIEW dbo.V1 WITH SCHEMABINDINGAS SELECT * FROM dbo.T1;GO

Anda mendapatkan kesalahan:

Msg 1054, Level 15, Status 6, Prosedur V1, Baris 5 [Batch Start Line 387]
Sintaks '*' tidak diperbolehkan dalam objek yang terikat skema.

Saat menggunakan SCHEMABINDING, Anda tidak diperbolehkan menggunakan SELECT * dalam ekspresi tabel bagian dalam tampilan.

Coba buat tampilan lagi, hanya kali ini dengan daftar kolom eksplisit:

BUAT ATAU ubah tampilan dbo.V1 DENGAN SCHEMABINDINGAS SELECT keycol, intcol, charcol FROM dbo.T1;GO

Kali ini tampilan berhasil dibuat.

Berikan izin pengguna1 pada keycol dan intcol:

BERI PILIH PADA dbo.V1(keycol, intcol) KEPADA user1;

Selanjutnya, coba terapkan perubahan struktural pada tabel. Pertama, tambahkan beberapa kolom:

ALTER TABLE dbo.T1 ADD datecol DATE NOT NULL DEFAULT('99991231'), binarycol VARBINARY(3) NOT NULL DEFAULT(0x112233);

Menambahkan kolom tidak menjadi masalah karena tidak dapat menjadi bagian dari tampilan terikat skema yang ada, sehingga kode ini berhasil diselesaikan.

Coba hapus kolom intcol:

ALTER TABLE dbo.T1 DROP COLUMN intcol;

Anda mendapatkan kesalahan berikut:

Msg 5074, Level 16, State 1, Line 418
Objek 'V1' bergantung pada kolom 'intcol'.

Msg 4922, Level 16, State 9, Line 418
ALTER TABLE DROP COLUMN intcol gagal karena satu atau beberapa objek mengakses kolom ini.

Menjatuhkan atau mengubah kolom yang direferensikan tidak diizinkan saat objek terikat skema ada.

Jika Anda masih perlu menghapus intcol, Anda harus menghapus tampilan referensi terikat skema terlebih dahulu, menerapkan perubahan, lalu membuat ulang tampilan dan menetapkan kembali izin, seperti:

DROP VIEW JIKA ADA dbo.V1;GO ALTER TABLE dbo.T1 DROP COLUMN intcol;GO CREATE ATAU ALTER VIEW dbo.V1 DENGAN SCHEMABINDINGAS SELECT keycol, charcol, datecol, binarycol FROM dbo.T1;GO GRANT SELECT ON V1(keycol, datecol, binarycol) KE user1;GO

Tentu saja pada titik ini tidak perlu me-refresh definisi tampilan, karena Anda telah membuatnya lagi.

Sekarang setelah Anda selesai menguji, jalankan kode berikut untuk pembersihan:

DROP VIEW JIKA ADA dbo.V1;DROP TABLE JIKA ADA dbo.T1;DROP USER JIKA ADA user1;

Ringkasan

Menggunakan SELECT * dalam ekspresi tabel bagian dalam tampilan adalah ide yang sangat buruk. Setelah perubahan struktural diterapkan ke objek yang direferensikan, Anda bisa mendapatkan nama kolom yang salah, dan bahkan mengizinkan pengguna mengakses data yang seharusnya tidak mereka akses. Merupakan praktik penting untuk secara eksplisit mencantumkan nama kolom yang direferensikan.

Menggunakan SCHEMABINDING dalam definisi tampilan Anda dipaksa untuk secara eksplisit mencantumkan nama kolom, dan perubahan struktural yang relevan untuk objek dependen ditolak oleh SQL Server. Oleh karena itu, sepertinya membuat tampilan dengan SCHEMBINDING selalu merupakan ide yang bagus. Namun, ada peringatan dengan opsi ini. Seperti yang Anda lihat, menerapkan perubahan struktural ke objek yang direferensikan saat SCHEMBINDING digunakan menjadi proses yang lebih panjang dan rumit. Ini terutama bisa menjadi masalah dalam sistem yang harus memiliki ketersediaan yang sangat tinggi. Bayangkan Anda perlu mengubah kolom yang didefinisikan sebagai VARCHAR(50) menjadi VARCHAR(60). Itu bukan perubahan yang diizinkan jika ada tampilan yang ditentukan dengan SCHEMABINDING yang mereferensikan kolom ini. Implikasi dari menjatuhkan sekelompok tampilan referensi, yang dapat direferensikan oleh tampilan lain, dan seterusnya, dapat menjadi masalah bagi sistem. Singkatnya, tidak selalu sepele bagi perusahaan untuk hanya mengadopsi kebijakan yang mengatakan bahwa SCHEMABINDING harus digunakan di semua objek yang mendukungnya. Namun, mengadopsi kebijakan untuk tidak menggunakan SELECT * dalam kueri dalam tampilan harus lebih mudah.

Ada banyak lagi yang bisa dijelajahi terkait pemandangan. Dilanjutkan bulan depan…


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bekerja dengan Data Java di Alteryx

  2. ScaleGrid DBaaS Dipilih untuk Cloud Excellence Awards 2018

  3. Kunci SQL, Unik dan Utama

  4. Mengganti Kursor SQL dengan Alternatif untuk Menghindari Masalah Kinerja

  5. Tingkatkan Performa UDF dengan NULL ON NULL INPUT