Chèn các hàng vào bảng chỉ với một cột IDENTITY


83

Tôi có một Quản trị viên bảng chỉ có một cột, adminId là khóa chính. Bởi vì các quy tắc kinh doanh nó phải theo cách này.

Tôi muốn hiểu một lần và mãi mãi về cách tôi có thể viết các thủ tục được lưu trữ để chèn giá trị vào các bảng như thế này. Tôi đang sử dụng SQL Server và T-SQL và đã thử sử dụng SCOPE_IDENTITY () nhưng điều đó không hoạt động vì bảng có INSERT_IDENTITY thành false hoặc tắt.

Tôi thực sự không muốn chèn một giá trị giả chỉ để có thể chèn một hàng mới. Cảm ơn!


1
Để làm rõ: câu hỏi của bạn là "làm thế nào để chèn các hàng trong bảng SQL Server với một cột IDENTITY duy nhất"?
gbn

Vâng, bạn nói đúng, cảm ơn vì đã làm rõ
Phil

2
Đối với những người hạ cánh ở đây, điều này đã được hỏi trước đây và câu trả lời chính xác là ở đây: stackoverflow.com/questions/850327/…
BJury

Câu trả lời:


140

Nếu bạn có một cột là IDENTITY, chỉ cần làm điều này

INSERT MyTable DEFAULT VALUES;  --allows no column list. The default will be the IDENTITY
SELECT SCOPE_IDENTITY();

Nếu bạn không có danh tính, sau đó bạn có thể đặt nó? Đây là cách tốt nhất .. và sử dụng SQL ở trên.

Nếu không, bạn muốn chèn một hàng mới

INSERT MyTable (admidid)
OUTPUT INSERTED.admidid --returns result to caller
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable

Ghi chú:

  • Dưới tải cao, giải pháp MAX có thể không thành công với các bản sao
  • SCOPE_IDENTITY sau thực tế, không phải trước
  • SCOPE_IDENTITY chỉ hoạt động với cột IDENTITY. Ditto bất kỳ kẻ ngu ngốc nào bằng IDENT_CURRENT
  • Mệnh đề đầu ra thay thế SCOPE_IDENTITY cho giải pháp MAX

1

Bạn cần thêm IDENTITY_INSERT vào câu lệnh đã chọn của mình:

SET IDENTITY_INSERT MyTable ON

INSERT INTO MyTable
(AdminCol)

SELECT AdminColValue

 FROM Tableb

Khi bạn hoàn thành, hãy đảm bảo rằng bạn nhớ

SET IDENTITY_INSERT MyTable OFF

Đây là mô tả tốt về cách nó hoạt động từ BOL: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx


Tôi có phải làm như thế này không: ĐẶT IDENTITY_INSERT Quản trị viên BẬT CHÈN VÀO Quản trị viên (SCOPE_IDENTITY ()) ĐẶT IDENTITY_INSERT Quản trị viên TẮT?
Phil

Đúng. Đó là tất cả những gì bạn cần làm. ĐẶT BẬT, viết mã của bạn, ĐẶT TẮT ở cuối.
DataWriter

Tôi không nghĩ đây là câu trả lời đúng. Nếu đó là cột nhận dạng, bạn không nên thêm giá trị vào đó. Câu trả lời được chấp nhận là câu trả lời đúng.
Mmm

0

@Phil: Ý bạn không phải là bảng của bạn có hai (2) cột, cột PK tự động tăng và một cột AdminName? Nếu nó chỉ có một cột ở đó Tên quản trị viên, Tên quản trị viên là PK và tất nhiên bạn không thể tự động tăng thêm một chuỗi. Các quy tắc kinh doanh có mong đợi bạn đặt tên người dùng Windows đủ điều kiện làm khóa chính không? Điều đó sẽ khả thi và có ý nghĩa, vì khi đó bạn sẽ không cần một chỉ mục duy nhất thay thế trên cột AdminName.

Nhưng nếu bảng của bạn có hai cột, không phải một:

Trong SQLServer, autoincrement là một phần của định nghĩa bảng / cột. Bạn xác định cột là một số nguyên và sau đó cũng biến nó thành một cột nhận dạng, chỉ định gia số, thường là 1, nhưng nó có thể là 2 hoặc 5 hoặc 10 hoặc bất cứ điều gì. Để chèn một hàng, bạn chỉ cần chèn (các) giá trị cột khác và không làm gì với cột PK:

insert into T
(foo)   -- column(s) list
values('bar') -- values list

Proc được lưu trữ của bạn thực hiện việc chèn có thể đặt SCOPE_IDENTITY thành giá trị RETURN hoặc SCOPE_IDENTITY có thể được chuyển lại cho máy khách dưới dạng tham số OUT.

PS SCOPE_IDENTITY () trả về giá trị nhận dạng tự động được tạo gần đây nhất trong phạm vi hiện tại; nó không tạo ra giá trị nhận dạng tiếp theo.

BIÊN TẬP:

Có lẽ, bảng Quản trị viên của bạn chứa một tập hợp các quản trị viên. Nhưng nếu nó không có cột nào khác ngoài cột khóa chính số nguyên, thì không có cách nào để xác định người quản lý; điều duy nhất bạn có thể làm là phân biệt chúng với nhau. Điều đó không giúp bạn tiến xa chút nào. Nhưng nếu bảng Quản trị viên của bạn có một trong các cấu trúc sau:

ID   INTEGER PRIMARY KEY AUTOINCREMENT
windowsusername   varchar(50)  (unique index)

HOẶC LÀ

windowsusername varchar(50) primary key

bạn sẽ có thể tham chiếu bảng Quản trị viên từ các bảng khác và các khóa ngoại sẽ CÓ Ý NGHĨA. Và đó chính xác là điều mà một bảng bao gồm một cột số nguyên thiếu - ý nghĩa.

Có hai cột, bạn có thể có một thủ tục được lưu trữ để thực hiện việc này:

insert into Administrators
(windowsusername)
values('mydomain\someusername');
return SCOPE_IDENTITY();

và chương trình khách hàng của bạn sẽ nhận lại dưới dạng giá trị trả về id tự động tăng cường đã được tự động tạo và gán cho hàng mới được chèn. Cách tiếp cận này là cách làm thông thường, và tôi muốn nói rằng nó được coi là "phương pháp tốt nhất".

Tái bút Bạn đề cập rằng bạn không biết cách "chèn giá trị" nếu bạn "không có gì để chèn". Có một mâu thuẫn ở đó. Nếu bạn không có gì để chèn, tại sao phải chèn? Tại sao bạn lại tạo hồ sơ KHÁCH HÀNG mới nếu bạn hoàn toàn không biết gì về khách hàng? Không phải tên của họ, thành phố của họ, số điện thoại của họ, không có gì?


2
Bảng của tôi có MỘT cột, adminId, là một giá trị int tăng dần
Phil

Đó là thiết kế kỳ lạ nhất mà tôi từng thấy, và tôi đã kinh doanh hơn 20 năm và đã thấy một số điều kỳ lạ trong thời của mình. Vì vậy, câu hỏi của bạn là, Làm thế nào để bạn chèn vào bảng chỉ chứa một cột khóa chính được xác định là cột nhận dạng tự động bổ sung, khi bảng chứa cột PK đó và chỉ cột PK đó, không có cột nào khác ..
Tim

Vậy downvote để làm gì? Một lỗi thực tế ở đâu đó hoặc vì bày tỏ ý kiến ​​về sự thiếu xứng đáng của thiết kế?
Tim

1
Chỉ để làm rõ lý do đằng sau thiết kế DB. Chúng tôi có người dùng trong một bảng. Nếu có mối quan hệ giữa người dùng và quản trị viên; họ được coi là quản trị viên. Không có gì khác để giữ trong bảng quản trị ngoài id duy nhất thực tế. Dữ liệu "thực" nằm trong bảng người dùng và quan hệ có (với dấu thời gian và ai đã cấp, v.v.).
Phil

1
@Phil: Vì vậy, bạn đang sử dụng một bảng và một mối quan hệ khóa ngoại để thể hiện những gì một cột boolean / bit đơn giản có thể làm. Bạn có thể không thêm được cột bit như vậy vào bảng của mình và phải đưa ra một số giải pháp. But an autoincrementing integer whose autoincrementation must be disabled is a poor solution.Tất cả những gì bạn cần là một bảng song song có mối quan hệ 1-1 với bảng người dùng và trong bảng đó, bạn tạo một cột bit. Khi cột đó là true, có nghĩa là người dùng có-admin. Dọn dẹp. Tiêu chuẩn. Thiết kế.
Tim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.