Về khóa chính không bắt đầu từ 1 (1 người xem)

  • Thread starter Thread starter Pavami
  • Ngày gửi Ngày gửi
Liên hệ QC

Người dùng đang xem chủ đề này

Tôi tuân thủ nội quy khi đăng bài

Pavami

Thành viên mới
Tham gia
31/10/23
Bài viết
2
Được thích
0
Trong trường hợp này mình muốn đặt khóa chính bắt đầu đếm từ 52 thì làm thế nào vậy mọi người?
1698753886641.png1698762894526.png
 
Lần chỉnh sửa cuối:
Mỗi loại CSDL có cách làm khác nhau. Bạn nghĩ là người khác nhìn hình có thể đoán ra bạn đang dùng loại nào à?
 
Xóa 51 record đầu là được. Bất kể CSDL nào :P :P
 
Lập trường khác rồi đổi lại là được.
 
Bạn chuyển kiểu dữ liệu về dạng số nguyên long/int..., rồi UPDATE [Bảng 1] SET [Mã số]=[Mã số]+51
 
Lập trường khác rồi đổi lại là được.
Trong access không thể đổi 1 trường đã có dữ liệu thành kiểu AutoNumber
Bạn chuyển kiểu dữ liệu về dạng số nguyên long/int..., rồi UPDATE [Bảng 1] SET [Mã số]=[Mã số]+51
Update xong không chuyển về kiểu AutoNumber được.

Kiểu Number thông thường không tự tăng.
 
Trong access không thể đổi 1 trường đã có dữ liệu thành kiểu AutoNumber

Update xong không chuyển về kiểu AutoNumber được.

Kiểu Number thông thường không tự tăng
Vì người mở chủ đề không yêu cầu bắt buộc phải là "Auto number" nên tôi gợi ý thế thôi. Vấn đề này tôi từng giải quyết nên cũng chả lạ gì.
Còn trường hợp đang dùng trường số mà muốn chuyển về "Auto number" thì cũng chỉ cần 1 câu SQL dạng cơ bản mà không cần nhập liệu lại từ đầu, hiển nhiên là không thể dùng lại bảng cũ. Tôi vừa thử xong trên Access đây.
 
Lần chỉnh sửa cuối:
Theo như hình chụp thì bảng đã có dữ liệu chính thức 13 dòng.
Nhập dữ liệu giả thật đơn giản cho nhanh, chỉ để lấy ID đến 51.
Copy 13 dòng
click chọn dòng {New) và paste
Xóa 51 dòng trên

Cách này nhanh và dễ, đồng thời sử dụng được bảng cũ.
 
Vì người mở chủ đề không yêu cầu bắt buộc phải là "Auto number" nên tôi gợi ý thế thôi. Vấn đề này tôi từng giải quyết nên cũng chả lạ gì.
Nếu không phải autonumber từ đầu thì có thể sửa tay, hoặc update bằng SQL mà không cần đổi kiểu long/ integer
 
Nếu anh/chị nào giống tôi luôn suy nghĩ là bọn Tây không ngừng tạo ra những thứ mới mẻ, thỏa mãn những nhu cầu hợp lý thì sẽ search ra một câu SQL cực kỳ hay ho, đủ đáp ứng ngay từ đầu mong muốn của người mở topic.
SQL:
CREATE TABLE TableThatIncrements
(
Id AUTOINCREMENT(1001,1)
)
Tôi đã thử trên Access và một lần nữa phải lác mắt với mấy anh Tây. :wow:
 
Lần chỉnh sửa cuối:
Muốn dùng code
[mã số] = [mã số] + 51
thì phải sắp xếp lớn xuống nhỏ
Nếu không sẽ bị lỗi trùng khóa.

Theo như hình chụp thì bảng đã có dữ liệu chính thức 13 dòng.
Nhập dữ liệu giả thật đơn giản cho nhanh, chỉ để lấy ID đến 51.
Copy 13 dòng
click chọn dòng {New) và paste
Xóa 51 dòng trên

Cách này nhanh và dễ, đồng thời sử dụng được bảng cũ.
Tự trong Table View thì không được. Nhưng có thể đổi một trường mới qua SQL View
- Đổi trường ID thành Number
- Tạo một trường AutoIncrement mới nuID
- Vào SQL View, dùng command tạo một trường AutoIncrement mới nuID (52,1)
- Copy dữ liệu từ lớp cũ sang lớp mới.
- Xóa lớp cũ
- Rename các tên trường
- Tìm những tables có liên hệ đến key này, và chỉnh chúng
 
Muốn dùng code
[mã số] = [mã số] + 51
thì phải sắp xếp lớn xuống nhỏ
Nếu không sẽ bị lỗi trùng khóa.
Nếu số dòng dữ liệu ít hơn 52 (giống như trên hình) thì câu UPDATE của tôi vẫn chạy đúng nhé. Còn trong trường hợp khác thì dù sắp xếp thì chạy lệnh UPDATE tương tự như thế vẫn có thể lỗi tè le.
 
Muốn dùng code
[mã số] = [mã số] + 51
thì phải sắp xếp lớn xuống nhỏ
Nếu không sẽ bị lỗi trùng khóa.
Dù trùng hay không trùng thì cách này không dùng được, vì update table xong không chuyển thành autonumber được.
- Nếu dưới 51 dòng: Làm như bài 9, vẽ lung tung cho đủ 51
- Nếu trên 51 dòng: Copy 51 dòng đầu paste xuống dưới rồi xóa 51 dòng đầu.
Dùng lại bảng này mà không cần tạo bảng mới, không cần đổi kiểu number, không cần chuyển dữ liệu qua, không cần đổi tên trường, không cần xóa bảng cũ, ...
 
- Nếu trên 51 dòng: Copy 51 dòng đầu paste xuống dưới rồi xóa 51 dòng đầu.
Dùng lại bảng này mà không cần tạo bảng mới, không cần đổi kiểu number, không cần chuyển dữ liệu qua, không cần đổi tên trường, không cần xóa bảng cũ, ...
Cảm giác có gì đó bất thường với ý kiến trên nên tôi đã thực nghiệm và phát hiện ra là... (các anh/chị cứ thử sẽ rõ)
Giả sử dữ liệu nhiều hơn 51 dòng, chẳng hạn đã có sẵn 60 dòng thì áp dụng cách này liệu có đúng không nhỉ? Có vẻ người đưa lý thuyết đồng nhất Access với Excel nên không hề có sự thực nghiệm. Hiển nhiên là vẫn có cách để tận dụng dữ liệu cũ nhưng chắc chắn là không đơn giản như phương án nêu trên
 
Lần chỉnh sửa cuối:
Cảm giác có gì đó bất thường với ý kiến trên nên tôi đã thực nghiệm và phát hiện ra là... (các anh/chị cứ thử sẽ rõ)
Tôi luôn luôn thực nghiệm trước khi viết bài. Kể cả kết luận trường number đã có dữ liệu không chuyển thành autonumber được (bài 7) cũng là đã thực nghiệm kỹ. Tôi tự hào là người luôn thực nghiệm trước khi trả lời bất kỳ việc gì, dù nhỏ như là 1 công thức SUM.

Cách copy paste khi nhiều hơn 51 dòng, hay ít hơn 51 dòng, tôi cũng đã thực nghiệm. Và tôi cũng ngạc nhiên cho 1 vị cũng uyên thâm mà thực nghiệm không ra.

Chẳng hạn tôi thực nghiệm cho mong muốn ID bắt đầu từ 11.

Trường hợp có sẵn 5 dòng: vẽ nhăng cuội cho đủ 10

1698858177065.png 1698858223671.png 1698858314484.png

Trường hợp dữ liệu có sẵn 24 dòng. Copy 10 dòng đầu và paste xuống dưới, sau đó xóa 10 dòng đầu:

1698857761903.png ______1698857844740.png
 
Tôi thường
Tôi luôn luôn thực nghiệm trước khi viết bài. Kể cả kết luận trường number đã có dữ liệu không chuyển thành autonumber được (bài 7) cũng là đã thực nghiệm kỹ. Tôi tự hào là người luôn thực nghiệm trước khi trả lời bất kỳ việc gì, dù nhỏ như là 1 công thức SUM.
Nếu chưa chắc chắn, tôi cũng phải kiểm nghiệm ý tưởng trước khi comment nhưng tôi chả có cảm giác tự hào gì với những kiến thức phổ thông trên mạng.

Chẳng hạn tôi thực nghiệm cho mong muốn ID bắt đầu từ 11.
Trường hợp dữ liệu có sẵn 24 dòng. Copy 10 dòng đầu và paste xuống dưới, sau đó xóa 10 dòng đầu:

View attachment 296285 ______View attachment 296286
Theo yêu cầu giả định (ID bắt đầu từ 11), đáng ra kết quả sau thủ thuật phải là 11-b01, 12-b02...34-b24 chứ sao lại là 11-b11, 12-b12...34-b10 như trong hình minh họa kết quả của ptm0412 được nhỉ?
 
Lần chỉnh sửa cuối:
Trong trường hợp này mình muốn đặt khóa chính bắt đầu đếm từ 52 thì làm thế nào vậy mọi người?
View attachment 296268View attachment 296270
Mục đích chuyển mã số của bạn là gì?
Khóa chính theo dạng "Auto number" dùng nhận dạng khác nhau của từng dòng và thứ tự nhập liệu, không nên dùng nó làm "Mã số" thực sự để nhận diện từng người
 
Mục đích chuyển mã số của bạn là gì?
Khóa chính theo dạng "Auto number" dùng nhận dạng khác nhau của từng dòng và thứ tự nhập liệu, không nên dùng nó làm "Mã số" thực sự để nhận diện từng người
Khóa chính mà có ý nghĩa gì đó thì là phản chuẩn (normalisation).
Trên nguyên tắc CSDL liên hệ, khóa chính không được mang ý nghĩa gì hết (kể cả thứ tự nhập liệu). Nó chỉ dùng để nhận diện dòng (bởi vậy nó thường được mặc định cái tên ID). Và những gì liên hệ đến dòng X sẽ có cái trường liên hệ mang trị X.

Ở bài #12, câu cuối tôi có nói là "tìm những chỗ liên hệ đến trường này và chỉnh chúng".
Tôi không hỏi mục đích thớt bởi vì tôi nghĩ có thể thớt bị lỗi trợt trường liên hệ. Ví dụ bảng 1 chứa ID, bảng 2 có trường bang1_ID, đáng lẽ mang số 5 thì nó mang số 56. Bây giờ nếu chỉnh cái trường ấy thì cũng dễ. Nhưng nếu có nhiều bảng bị vậy thì người ta cho rằng chỉnh cái bảng chính dễ hơn.

Thực tế, lúc bị trợt trường (có thể vì một code VBA nào đó viết bậy, hay cái Event nạp trường kẹt, hổng chạy,...) thì bản thân tôi thà sửa chục cái bảng liên hệ còn hơn sửa khóa bảng chính. Vừa rắc rối vừa để họa sau này.
 
Có một việc mà tôi đợi để nói với tác giả bài 1, nhưng thôi nói luôn:
- Trường autonumber chả có ý nghĩa gì về mặt dữ liệu (không chứa thông tin), nó cũng không hiện diện trên form nhập liệu, báo cáo. Người dùng cuối có khi còn không biết đến sự tồn tại của nó. Vậy thì dù nó là bao nhiêu cũng chẳng cần biết làm gì.
- Đối với các bảng danh mục thì khóa chính nên là mã của danh mục chứ không phải con số tăng kia (mã vật tư, mã nhân viên, mã phòng ban, ...), để khi nhập liệu nó hiển thị có hình tượng cho người dùng. Và những mã này (duy nhất ở từng bảng danh mục) mới dùng để tạo quan hệ với những bảng dữ liệu khác.

Không trông chờ được vào việc kiểm soát số tăng, vì nó hoàn toàn tự động. Như sau:
- Nếu xóa 1 record mang số ID nào đó, thì số đó mất vĩnh viễn, những số ở dưới không đôn lên. Thì không còn tính liên tục để nhìn cho đẹp mắt.
- Nếu 1 chứng từ có 3 record, ID là 40, 41, 42. Sau đó (sau khi nhập liệu thêm cả đống) phát hiện thiếu và chỉnh sửa thêm 1 record thì đừng trông chờ rằng record mới sẽ mang số 43 mà sẽ là số khác lớn hơn. Kết quả là 1 chứng từ 4 record mang số 40, 41, 42, 101.
- Nếu xóa một vài record cuối chẳng hạn xóa 2 record mang ID 99 và 100, thì khi nhập liệu thêm, ID tiếp theo sẽ vẫn là 101 chứ đừng mong rằng Access lấy số cuối (98) tăng 1. Nó đã ghi nhớ rằng 2 con đó đã xài và không cho xài nữa.

Vậy thì theo cách ở bài 16 copy ở trên paste xuống dưới ID vẫn bắt đầu bằng 11 nhưng dòng dữ liệu nhập vào đầu tiên hồi năm ngoái sẽ mang số 25 (như phát hiện của bài 17). Tôi không quan tâm vì yêu cầu chỉ nói về ID bắt đầu từ 52 chứ không nói gì về nguyên dòng dữ liệu đầu tiên phải mang số 52.

Và theo tôi thì nó mang số 52 hay 152 hay 1000 chả ảnh hưởng gì đến việc nhập liệu, ra báo cáo, ....

Tất nhiên tôi đưa ra giải pháp thì tác giả có quyền chọn cách nào họ thấy là phù hợp, hoặc đơn giản là chỉ thích, chứ tôi cũng không mong cầu gì họ làm theo những gì tôi viết ở trên.
 
Access Tôi không biết nhiều lắm và chỉ xem nó như là File Data.accdb lưu trữ dữ liệu và tạo các mối quan hệ của các bảng dữ liệu ( Ở mức cơ bản, đơn giản nhất thôi ... còn phức tạp là tôi Tịt)

Tôi có vài ý nêu ra như sau với mục đích tìm hiểu thêm thôi

1/ tại sao phải bắt đầu từ con số 52 =??!!!

2/ khi trường ID là AutoNumber có nghĩa nó sẻ tự động tăng dần lên vậy khi ta nhập sai gì đó mà xóa các dòng ở khúc giữa thì sao ???!!! giá trị tăng dần không còn chính xác nữa

3/ tại sao không cho trường ID là Number thì nó cũng thế thôi mà thuận tiện khi xử lý nhiều kiểu dữ liệu khác nhau tốt hơn

4/ khi kiến thức khá lên ta có thể Úp cái File Data.accdb lên Web Server của chính mình thì khi truy xuất dữ liệu từ xa như mục số 3 nó ít lỗi và dễ xử lý hơn mục số 2 ( Còn phân tích tại sao thì tôi chịu ... vì tôi thử mọi cái nó thế )


5/ VD: khi ta chèn dữ liệu theo mục số 3 thì nó sẻ tôt hơn mục số 2 mà không bị lỗi ... còn tại sao thong thả dò là ra thôi

sử dụng phương thức Append

Mã:
Rs.Fields.Append "AffectedRows", vbLong
Rs.Open: Rs.AddNew Array(0, 1), Array(Cnn.Execute("Select @@Identity")(0), AffectedRows)

... rảnh bà tám tiếp
 
Lần chỉnh sửa cuối:
Vậy thì theo cách ở bài 16 copy ở trên paste xuống dưới ID vẫn bắt đầu bằng 11 nhưng dòng dữ liệu nhập vào đầu tiên hồi năm ngoái sẽ mang số 25 (như phát hiện của bài 17). Tôi không quan tâm vì yêu cầu chỉ nói về ID bắt đầu từ 52 chứ không nói gì về nguyên dòng dữ liệu đầu tiên phải mang số 52.

Và theo tôi thì nó mang số 52 hay 152 hay 1000 chả ảnh hưởng gì đến việc nhập liệu, ra báo cáo, ....
Để tôi đối chiếu "niềm tự hào" của ptm0412 với kết quả mà theo thôi là hợp lý hơn với hình minh họa bên dưới. Sự hợp lý ở đây chính là thứ tự trước sau của các dòng dữ liệu vẫn tương tự như ban đầu, giúp cho người quản lý dữ liệu dễ dàng nắm bắt và cũng để đảm bảo những ràng buộc khi không thể tùy tiện phá vỡ thứ tự các dòng dữ liệu. Giải quyết theo hướng hợp lý này cũng không quá khó với nhiều anh chị ở đây.

Nhân đây tôi cũng giới thiệu một giải pháp của các anh Tây có thể giúp nhảy cóc bộ đếm của Autonumber đối với bảng đã tồn tại. Cách này chỉ áp dụng nếu không có relationship. Lưu ý là cách này đòi hỏi số dòng dữ liệu đã được nhập vào (kể cả đã xóa) phải ít hơn...
SQL:
ALTER TABLE TableThatIncrements
   ALTER COLUMN Id AUTOINCREMENT(52,1)
 

File đính kèm

  • 1698857844740.png
    1698857844740.png
    44.6 KB · Đọc: 9
Lần chỉnh sửa cuối:
Để tôi đối chiếu "niềm tự hào" của ptm0412
Nếu đọc kỹ sẽ thấy tôi tự hào vì cái gì. Không phải tự hào về kiến thức nhá.

1698898098667.png
Tôi thực nghiệm theo ý của tôi, và ý của tôi dựa trên yêu cầu mà tôi cố tình viết chữ đậm:

1698898198551.png

Và tại sao tôi bỏ qua việc copy xong bị chạy số khác thì đã giải thích ở bài 20.

Tôi sẽ không nói gì thêm, và đừng gọi tên tôi nữa.
 
Lần chỉnh sửa cuối:
Như ông chú nói "Tội tự hào là người luôn thực nghiệm ...". Ông chú thấy tự hào với việc mình làm nhưng thành quả của nó thì ông chú lại không có cảm xúc tương xứng là sao nhỉ? Nếu Messi phát biểu "Tôi tự hào vì thi đấu cùng đội tuyển tại Worldcup 2002 nhưng không tự hào vì chiếc cúp vô định (thành quả)" thì chú có thấy lời nói anh này có gì bất nhất không?
Đọc lại dòng chữ đậm và nguyên bài 20. (nhắc lần 2, để không đọc hoặc đọc không hiểu, hoặc cố tình vặn vẹo). Tôi hết!
 
Đọc lại dòng chữ đậm và nguyên bài 20. (nhắc lần 2, để không đọc hoặc đọc không hiểu, hoặc cố tình vặn vẹo). Tôi hết!
Theo tôi thì Access được ra lúc máy tính còn yếu. Mà máy yếu thì chạy CSDL LH thật chuẩn sẽ sặc gạch. Do đó phiên bản cũ của Access thường né chuẩn một chút bằng cách đặc chế một số luật mà CSDL LH ngày nay không thấy. Nhiều luật thấy rõ ràng rằng do ràng buộc với loại file ISAM, VSAM (random access), Sequential.
Các loại CSDL mới hơn (SQL Server, mySQL, Oracle,...) dễ chỉnh sửa metadata là vì chúng dùng loại files mới hơn (điển hình là Index bằng B-Tree)

Do Access phải hỗ trợ các phiên bản cũ cho nên nó có nhiều chỗ uất nghẹn.
 
- Trường autonumber chả có ý nghĩa gì về mặt dữ liệu (không chứa thông tin), nó cũng không hiện diện trên form nhập liệu, báo cáo. Người dùng cuối có khi còn không biết đến sự tồn tại của nó. Vậy thì dù nó là bao nhiêu cũng chẳng cần biết làm gì.
Một trường dữ liệu được chọn làm key mà chả có ý nghĩa về mặt dữ liệu? Với người biết cách dùng, nó không khác gì "vân tay" của dữ liệu và cho nhiều thông tin hơn là chỉ là một cái mã.
- Nếu xóa 1 record mang số ID nào đó, thì số đó mất vĩnh viễn, những số ở dưới không đôn lên. Thì không còn tính liên tục để nhìn cho đẹp mắt.
Trước khi tham gia cái chủ đề này, tôi cũng tưởng là như thế nhưng sau nhiều thử nghiệm thì tôi phát hiện ra là không phải. Với Autonumber chả có gì mất vĩnh viễn cả, một giá trị bị xóa đi dùng lại hoàn toàn bình thường, ít nhất là với Access 365. Và nếu dùng lại một giá trị Autonumber từng bị xóa thì sẽ xẩy ra một điều rất thú vị. Tôi đã thử nghiệm một lần nữa trước khi đưa ra ý kiến này và cũng đã thử vài ba lần trước đó vì không thể tin vào sự thật.

Hy vọng là sau khi tiết lộ cái thông tin bất ngờ này, nhiều anh chị có hứng thú với database cũng sẽ táy máy để tự khám phá điều tôi vừa chia sẻ. Và nếu đúng như tôi đã nói thì đừng ngại phản hồi nhé.
 
Không ai bắt buộc CSDL LD phải chuẩn tới mực nào cả.
Chuẩn ở đây là dịch từ "normalisation" (không phải tôi tự dịch, và tôi thích viết tiếng Anh thay vì tiếng Mẽo). Nó chỉ dùng để dễ nắm đầu dữ liệu thôi. Cũng như bảng tính Excel nếu thiết kế đàng hoàng thì dễ làm việc.
Ví dụ để lập master file cho kiểu đóng gói gồm gói, thùng, pa-let, cần xé,... người ta có thể dùng 2 ký tự đầu để làm khóa id: go, th, pl, cx,... Người đọc quen sẽ tự đoán được kiểu từ key. Lúc liệt query ra, không cần phải từ transaction lấy khóa ngoại (cái key trên) kết nối (join) master file để biết kiểu. Ai cũng vui vẻ.
Rất tiếc, đến một ngày đẹp trời nào đó, kiểu đóng gói sanh thêm cái "thúng". Vậy thì key nó là gì đây? Đặt là ts? Người đọc lại phải tập hiểu s liên quan đến dấu sắc. Tuy rằng họ sẽ thắc mắc tại sao thùng lại khong dùng cái gì liên quan đến dấu huyền!

Kiểu tra cứu mã để tìm ra liên hệ là kiểu thượng cổ mà chỉ có mấy người giáo viên không chạm thực tế mới còn giữ.
"hai ký tự đầu là loại hàng, ký tự giữa là số nhà kho, ký tự cuối cùng cho biết..." ---> rác rưởi!

Chú thích:
Trên thực tế, người ta hy sinh một bậc chuẩn để tăng tốc là chuyện thường tình. Nhưng khi làm chuyện đó người ta biết là mình có "hy sinh", chứ không hề nói là "làm vậy mới đúng".
 
Trên thực tế, người ta hy sinh một bậc chuẩn để tăng tốc là chuyện thường tình. Nhưng khi làm chuyện đó người ta biết là mình có "hy sinh", chứ không hề nói là "làm vậy mới đúng".
Đúng vậy bác. Tôi cũng thường dùng cả 2 kiểu tạo khoá chính. Chỉ dùng cách tạo mã bằng việc kết hợp thông tin cho một số bảng dữ liệu có tính đặc trưng, còn lại các bảng dạng lưu record chi tiết (như chi tiết hoá đơn, chứng từ nhập xuất ...), số record lớn thì cứ dùng Autonumber làm khoá chính. Khỏi tốn code tạo mã, index, tìm kiếm khoá dạng số cũng nhanh...
Từ đó đến giờ thiết kế CSDL xong đưa vào hoạt động cũng chẳng có lý do gì phải code tái sử dụng lại các mã dùng Autonumber đã xoá. Dữ liệu nào nhập sau thì cứ nằm sau, chẳng có lý gì để chen vô sâp xếp trước vì tái sử dụng Autonumber (ANum) cũ. Còn có một trường hợp thực tế khác là khi nhập liệu dòng mới, mã với ANum tự động tạo -> sau đó lại xoá record đó do sai một số thông tin, tạo lại -> ANum sẽ tự động gán số mới mặc dù số liền kề trước đó chưa được dùng (do mới bị xoá). Muốn lấy lại số liền kề trước đó thì chỉ việc chạy Compact and Repairt Databae là Anum sẽ trả lại số mới nhất liền kề. Tôi thường dùng cách này khi bàn giao ứng dụng cho khách, xoá toàn bộ dữ liệu nháp, reset Autonumber về lại 1.
 
Lần chỉnh sửa cuối:

Bài viết mới nhất

Back
Top Bottom