Là trường hợp SQL nhạy cảm. Tôi đã sử dụng MySQL và SQL Server mà cả hai đều có vẻ nhạy cảm. Luôn luôn là trường hợp này sao? Liệu tiêu chuẩn xác định trường hợp nhạy cảm?
Là trường hợp SQL nhạy cảm. Tôi đã sử dụng MySQL và SQL Server mà cả hai đều có vẻ nhạy cảm. Luôn luôn là trường hợp này sao? Liệu tiêu chuẩn xác định trường hợp nhạy cảm?
Câu trả lời:
Từ khóa SQL là case-insensitive ( SELECT
, FROM
, WHERE
, vv), nhưng thường được viết hoa toàn bộ. Tuy nhiên, trong một số thiết lập tên bảng và cột có phân biệt chữ hoa chữ thường. MySQL có một tùy chọn cấu hình để kích hoạt / vô hiệu hóa nó. Thông thường các tên bảng và cột phân biệt chữ hoa chữ thường là mặc định trên Linux MySQL và không phân biệt chữ hoa chữ thường được sử dụng làm mặc định trên Windows, nhưng bây giờ trình cài đặt đã hỏi về điều này trong khi thiết lập. Đối với MSSQL, đây là một chức năng của cài đặt đối chiếu của cơ sở dữ liệu.
Trong Sql Server, nó là một tùy chọn . Bật nó lên hút.
Tôi không chắc chắn về MySql.
Mã định danh và từ dành riêng không nên phân biệt chữ hoa chữ thường, mặc dù nhiều từ tuân theo quy ước sử dụng chữ viết hoa cho từ dành riêng và trường hợp Pascal cho mã định danh.
Xem SQL-92 giây. 5,2
Đặc tả SQL92 nói rằng các định danh có thể được trích dẫn hoặc không trích dẫn. Nếu cả hai bên đều không được trích dẫn thì chúng luôn không phân biệt chữ hoa chữ thường, vd table_name == TAble_nAmE
.
Tuy nhiên, định danh được trích dẫn là trường hợp nhạy cảm, ví dụ "table_name" != "TAble_naME"
. Cũng dựa trên thông số kỹ thuật nếu bạn muốn so sánh các định danh không được yêu cầu với các định danh được trích dẫn, thì các định danh không trích dẫn và trích dẫn có thể được coi là giống nhau, nếu các ký tự không được trích dẫn được đặt trên, ví dụ TABLE_NAME == "TABLE_NAME"
, TABLE_NAME != "table_name"
hoặc TABLE_NAME != "TAble_NaMe"
.
Đây là phần có liên quan của thông số kỹ thuật (phần 5.2.13):
13)A <regular identifier> and a <delimited identifier> are equiva-
lent if the <identifier body> of the <regular identifier> (with
every letter that is a lower-case letter replaced by the equiva-
lent upper-case letter or letters) and the <delimited identifier
body> of the <delimited identifier> (with all occurrences of
<quote> replaced by <quote symbol> and all occurrences of <dou-
blequote symbol> replaced by <double quote>), considered as
the repetition of a <character string literal> that specifies a
<character set specification> of SQL_TEXT and an implementation-
defined collation that is sensitive to case, compare equally
according to the comparison rules in Subclause 8.2, "<comparison
predicate>".
Lưu ý, giống như với các phần khác của tiêu chuẩn SQL, không phải tất cả các cơ sở dữ liệu đều tuân theo phần này đầy đủ. Ví dụ, PostgreSQL lưu trữ tất cả các mã định danh không được trích dẫn thay vì hạ cấp, vì vậy table_name == "table_name"
(điều này hoàn toàn ngược lại với tiêu chuẩn). Ngoài ra, một số cơ sở dữ liệu không phân biệt chữ hoa chữ thường hoặc phân biệt chữ hoa chữ thường phụ thuộc vào một số cài đặt trong DB hoặc phụ thuộc vào một số thuộc tính của hệ thống, thường là liệu hệ thống tệp có phân biệt chữ hoa chữ thường hay không.
Lưu ý rằng một số công cụ cơ sở dữ liệu có thể gửi các số nhận dạng được trích dẫn mọi lúc, do đó, trong trường hợp bạn trộn các truy vấn được tạo bởi một số công cụ (như truy vấn CREATE TABLE được tạo bởi Liquibase hoặc công cụ di chuyển DB khác), với các truy vấn được tạo bằng tay (như chọn JDBC đơn giản trong ứng dụng của bạn), bạn phải đảm bảo rằng các trường hợp nhất quán, đặc biệt là trên các cơ sở dữ liệu nơi các định danh được trích dẫn và không trích dẫn là khác nhau (DB2, PostgreQuery, v.v.)
Hiểu biết của tôi là tiêu chuẩn SQL yêu cầu không phân biệt chữ hoa chữ thường. Mặc dù vậy, tôi không tin bất kỳ cơ sở dữ liệu nào tuân theo tiêu chuẩn hoàn toàn.
MySQL có một cài đặt cấu hình như là một phần của "chế độ nghiêm ngặt" của nó (một túi chứa một số cài đặt làm cho MySQL tuân thủ tiêu chuẩn hơn) cho các tên bảng nhạy cảm hoặc không phân biệt chữ hoa chữ thường. Bất kể cài đặt này, tên cột vẫn không phân biệt chữ hoa chữ thường, mặc dù tôi nghĩ nó ảnh hưởng đến cách hiển thị tên cột. Tôi tin rằng cài đặt này là toàn bộ phiên bản, trên tất cả các cơ sở dữ liệu trong phiên bản RDBMS, mặc dù hôm nay tôi đang nghiên cứu để xác nhận điều này (và hy vọng câu trả lời là không).
Tôi thích cách Oracle xử lý việc này tốt hơn nhiều. Trong SQL thẳng, các định danh như tên bảng và cột không phân biệt chữ hoa chữ thường. Tuy nhiên, nếu vì một lý do nào đó mà bạn thực sự mong muốn có được vỏ rõ ràng, bạn có thể đặt mã định danh trong dấu ngoặc kép (khá khác nhau trong Oracle SQL từ dấu ngoặc đơn được sử dụng để gửi dữ liệu chuỗi). Vì thế:
SELECT fieldName
FROM tableName;
sẽ truy vấn tên trường từ tablename , nhưng
SELECT "fieldName"
FROM "tableName";
sẽ truy vấn fieldName từ tableName .
Tôi khá chắc chắn rằng bạn thậm chí có thể sử dụng cơ chế này để chèn khoảng trắng hoặc các ký tự không chuẩn khác vào một mã định danh.
Trong tình huống này nếu vì một lý do nào đó, bạn thấy tên bảng và cột được đặt rõ ràng mong muốn nó có sẵn cho bạn, nhưng nó vẫn là thứ tôi rất thận trọng chống lại.
Quy ước của tôi khi tôi sử dụng Oracle hàng ngày là trong mã tôi sẽ đặt tất cả các từ khóa Oracle SQL bằng chữ hoa và tất cả các mã định danh bằng chữ thường. Trong tài liệu tôi sẽ đặt tất cả các tên bảng và cột bằng chữ hoa. Thật thuận tiện và dễ đọc để có thể làm điều này (mặc dù đôi khi rất khó để nhập quá nhiều chữ viết hoa - tôi chắc chắn rằng tôi có thể tìm thấy một tính năng soạn thảo để trợ giúp, ở đây).
Theo tôi, MySQL đặc biệt tệ vì khác biệt về điều này trên các nền tảng khác nhau. Chúng ta cần có khả năng kết xuất cơ sở dữ liệu trên Windows và tải chúng vào UNIX và làm như vậy là một thảm họa nếu trình cài đặt trên Windows quên đặt RDBMS vào chế độ phân biệt chữ hoa chữ thường. (Công bằng mà nói, một phần lý do đây là một thảm họa là các lập trình viên của chúng tôi đã đưa ra quyết định tồi, từ lâu, dựa vào tính nhạy cảm trường hợp của MySQL trên UNIX.) Giống như Windows, và thật tuyệt khi chuyển sang cung cấp cho mọi người một hộp kiểm để nói "Bạn có muốn bật chế độ nghiêm ngặt và làm cho MySQL tuân thủ tiêu chuẩn hơn không?" Nhưng nó rất thuận tiện để MySQL khác biệt rất nhiều so với tiêu chuẩn, và sau đó làm cho vấn đề tồi tệ hơn bằng cách quay lại và khác với tiêu chuẩn thực tế của chính nó trên các nền tảng khác nhau. Tôi chắc chắn rằng trên các bản phân phối Linux khác nhau, điều này có thể được kết hợp thêm, vì các trình đóng gói cho các bản phân phối khác nhau đôi khi có thể kết hợp các cài đặt cấu hình MySQL ưa thích của chúng.
Đây là một câu hỏi SO khác được thảo luận nếu phân biệt chữ hoa chữ thường là mong muốn trong RDBMS.
Không. MySQL không phân biệt chữ hoa chữ thường và cũng không phải là tiêu chuẩn SQL. Đó chỉ là thực tế phổ biến để viết các lệnh viết hoa.
Bây giờ, nếu bạn đang nói về tên bảng / cột, thì có, nhưng không phải là chính các lệnh.
Vì thế
SELECT * FROM foo;
giống như
select * from foo;
nhưng không giống như
select * from FOO;
Tôi thấy bài viết trên blog này rất hữu ích (tôi không phải là tác giả). Tóm tắt (xin vui lòng đọc, mặc dù):
... số nhận dạng được phân tách là phân biệt chữ hoa chữ thường ("tên_bảng"! = "tên_bảng"), trong khi số nhận dạng không được trích dẫn thì không và được chuyển thành chữ hoa (tên_bảng => TABLE_NAME).
Ông đã tìm thấy DB2, Oracle và Interbase / Firebird tuân thủ 100%:
PostgreSQL ... viết thường mọi định danh không được trích dẫn, thay vì viết hoa trên nó. MySQL ... phụ thuộc hệ thống tập tin. SQLite và SQL Server ... trường hợp tên bảng và trường được giữ nguyên khi tạo, nhưng chúng hoàn toàn bị bỏ qua sau đó.
Các từ khóa SQL không phân biệt chữ hoa chữ thường.
Tên của bảng, cột, v.v., có độ nhạy trường hợp phụ thuộc vào cơ sở dữ liệu - có lẽ bạn nên cho rằng chúng phân biệt chữ hoa chữ thường trừ khi bạn biết cách khác (Trong nhiều cơ sở dữ liệu chúng không có; tên không).
So sánh dữ liệu bằng cách sử dụng =,>, <etc, có nhận thức trường hợp phụ thuộc vào cài đặt đối chiếu được sử dụng trên cơ sở dữ liệu cá nhân, bảng hoặc thậm chí cột trong câu hỏi. Tuy nhiên, điều đó là bình thường, để giữ cho đối chiếu khá nhất quán trong cơ sở dữ liệu. Chúng tôi có một vài cột cần lưu trữ các giá trị phân biệt chữ hoa chữ thường; họ có một đối chiếu cụ thể được thiết lập.
Có những điều tốt nhất của cả hai thế giới
Ngày nay, bạn có thể viết tất cả các câu lệnh sql bằng chữ thường và nếu bạn cần định dạng nó thì chỉ cần cài đặt một plugin sẽ làm điều đó cho bạn. Điều này chỉ áp dụng nếu trình soạn thảo mã của bạn có sẵn các plugin đó. VSCode có nhiều phần mở rộng có thể làm điều này.