Xin lỗi cho một bài đăng dài, nhưng tôi cần đăng một số mã để minh họa sự cố."chọn * từ bảng" vs "chọn colA, colB, v.v ... từ bảng" hành vi thú vị trong SQL Server 2005
Lấy cảm hứng từ câu hỏi * What is the reason not to use select ?, tôi quyết định chỉ ra một số quan sát về hành vi chọn * mà tôi đã nhận thấy một số thời gian trước đây.
Vì vậy, hãy là mã nói cho chính nó:
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[starTest]') AND type in (N'U'))
DROP TABLE [dbo].[starTest]
CREATE TABLE [dbo].[starTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[A] [varchar](50) NULL,
[B] [varchar](50) NULL,
[C] [varchar](50) NULL
) ON [PRIMARY]
GO
insert into dbo.starTest(a,b,c)
select 'a1','b1','c1'
union all select 'a2','b2','c2'
union all select 'a3','b3','c3'
go
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vStartest]'))
DROP VIEW [dbo].[vStartest]
go
create view dbo.vStartest as
select * from dbo.starTest
go
go
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vExplicittest]'))
DROP VIEW [dbo].[vExplicittest]
go
create view dbo.[vExplicittest] as
select a,b,c from dbo.starTest
go
select a,b,c from dbo.vStartest
select a,b,c from dbo.vExplicitTest
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[starTest]') AND type in (N'U'))
DROP TABLE [dbo].[starTest]
CREATE TABLE [dbo].[starTest](
[id] [int] IDENTITY(1,1) NOT NULL,
[A] [varchar](50) NULL,
[B] [varchar](50) NULL,
[D] [varchar](50) NULL,
[C] [varchar](50) NULL
) ON [PRIMARY]
GO
insert into dbo.starTest(a,b,d,c)
select 'a1','b1','d1','c1'
union all select 'a2','b2','d2','c2'
union all select 'a3','b3','d3','c3'
select a,b,c from dbo.vExplicittest
select a,b,c from dbo.vStartest
Nếu bạn thực hiện các truy vấn sau đây và nhìn vào kết quả của 2 câu chọn cuối cùng, kết quả mà bạn sẽ thấy sẽ là như sau:
select a,b,c from dbo.vExplicittest
a1 b1 c1
a2 b2 c2
a3 b3 c3
select a,b,c from dbo.vStartest
a1 b1 d1
a2 b2 d2
a3 b3 d3
Như bạn có thể thấy trong kết quả của chọn a, b, c từ dbo.vStartest dữ liệu của cột c đã được thay thế bằng dữ liệu từ cột d.
Tôi tin rằng đó là liên quan đến cách chế độ xem được biên soạn, sự hiểu biết của tôi là các cột được ánh xạ theo chỉ mục cột (1,2,3,4) thay vì tên.
Tôi nghĩ tôi sẽ đăng nó như một cảnh báo cho những người sử dụng lựa chọn * trong SQL của họ và gặp phải hành vi không mong muốn.
Lưu ý: Nếu bạn xây dựng lại chế độ xem sử dụng chọn * mỗi lần sau khi bạn sửa đổi bảng, nó sẽ hoạt động như mong đợi.
Tôi không hiểu, không có cột D ở bất kỳ đâu trong mã ví dụ. – Hogan
@ Bạn cần cuộn xuống ví dụ mã, bảng starTest bị thả và tạo lại lần nữa, lần này với 4 cột: A, B, D, C – kristof
cảm ơn, không biết làm thế nào tôi bỏ lỡ điều đó. – Hogan