Làm cách nào tôi có thể ngăn các số nguyên âm thầm chuyển thành dấu hoa thị trong SQL Server?


8

Giả sử chúng ta có một tài khoản bảng, có một trường acct_type varchar(2)

Insert into account(acct_type) values(888)

Đầu ra:

+-----------+
| acct_type |
+-----------+
| *         |
+-----------+

Tôi hy vọng nó sẽ đưa ra một lỗi khi chèn kích hoạt câu lệnh. Tại sao nó lưu trữ *giá trị trong bảng?


@SMor: hoặc có thể bảng được định nghĩa không chính xác. Nếu ứng dụng muốn lưu trữ số (số nguyên) trong đó, có lẽ cột phải được xác định là integerthay vìvarchar
a_horse_with_no_name

Câu trả lời:


11

Đối với varcharkiểu dữ liệu, một phần bị cắt intsẽ được chọn *thay vì đưa ra một lỗi (trong trường hợp này là ba chữ số không khớp với a varchar(2)).

Điều này không xảy ra với nvarchar

Không có cách nào để thay đổi hành vi này, nó được bảo tồn để tương thích ngược. Nếu đây là một vấn đề thực sự đối với bạn, bạn có thể thêm một ràng buộc kiểm tra rằng giá trị trong cột không phải là *nhưng tôi không thể tưởng tượng bất kỳ tình huống nào trong đó điều này thực sự đáng làm.

Giải pháp là không làm điều đó. Nếu bạn phải chèn INTthì xác nhận nó nằm trong phạm vi -9 to 99trước. Hoặc luôn luôn sử dụng dấu ngoặc kép xung quanh các giá trị dành cho cột chuỗi thay vì dựa vào chuyển đổi ngầm định.


Cảm ơn Martin! .. Làm thế nào tôi có thể đặt một ràng buộc kiểm tra để ngăn giá trị số nguyên trong varchar được gửi ... bạn có thể vui lòng giúp tôi viết cú pháp không?
Ankush

ALTER TABLE account ADD CONSTRAINT CK_NoStar_acct_type CHECK (acct_type <> '*')nhưng bạn gần như chắc chắn không cần phải làm điều này. Có rất nhiều char/varcharcột trong tự nhiên có độ dài bằng 10hoặc ít hơn trong đó đây là một khả năng lý thuyết có thể hoạt động tốt mà không cần điều đó. Tất nhiên, ràng buộc kiểm tra cũng sẽ chặn một phần chèn rõ ràng *vì nó không có cách nào để phân biệt giữa cách thức *được chuyển đến
Martin Smith

1
Cảm ơn rất nhiều Martin !! bây giờ tôi có thể giải thích chính xác cho nhà phát triển của mình bằng cú pháp và hiệu ứng phụ của điều này
Ankush

4
Tôi nghĩ rằng câu hỏi thực sự là: nếu họ muốn lưu trữ các giá trị nguyên, thì tại sao điều này varcharlại bắt đầu?
a_horse_with_no_name

@a_horse_with_no_name Nếu bạn có câu hỏi cho OP, hãy đặt nó vào câu hỏi không phải là câu trả lời. Họ sẽ không được thông báo ở đây. Tôi sẽ nói rằng không có gì trong câu hỏi chỉ ra rằng họ chỉ có ý định lưu trữ số nguyên trong cột này mặc dù "888" không phải là một giá trị hợp lệ cho varchar(2)dù sao đi nữa. Tất cả những gì có thể được suy luận là họ đã thử nó ít nhất một lần và nhận được một kết quả bất ngờ rằng họ thà mắc sai lầm còn hơn là thất bại trong âm thầm.
Martin Smith

-2

varchar chấp nhận loại chuỗi. bạn sẽ có thể chèn giá trị giữa các ký hiệu ''. Có vẻ như Insert into account(acct_type) values('888') Nhưng nó sẽ hiển thị lỗi vì chiều dài tối đa là 2. chiều dài varchar hoặc độ dài giá trị tối đa của bạn phải là 2Insert into account(acct_type) values('88')


Câu trả lời của bạn đi theo một hướng khác so với câu hỏi, Sami cho biết không có lỗi và giá trị được chèn là '*'. Nhận xét mà SMor đã đưa ra có nhiều khả năng theo hướng của vấn đề.
Đánh dấu
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.