Чи чутливий до регістру синтаксис SQL?


199

Чутливий до регістру SQL. Я використовував MySQL та SQL Server, які, як видається, не залежать від регістру. Це завжди так? Чи визначає стандарт чутливість до регістру?


Відповіді:


181

У SQL Ключові слова нечутливі до регістру ( SELECT, FROM, WHEREі т.д.), але часто пишуться великими літерами. Однак у деяких таблицях налаштувань імена стовпців залежать від регістру. У MySQL є можливість конфігурації, щоб увімкнути / вимкнути її. Зазвичай назви таблиць і стовпців, що залежать від регістру, є типовими для Linux MySQL, а невідчутними до регістру раніше використовувались за замовчуванням у Windows, але зараз інсталятор запитав про це під час налаштування. Для MSSQL це функція налаштування порівняння бази даних.

Ось сторінка MySQL про чутливість до імені

Ось стаття в MSDN про зіставлення для MSSQL


7
Деякі системи (наприклад, PostgreSQL) залежать від регістру в іменах таблиць і стовпців, але намагаються приховати це через нижнє регістр або верхнє регістр усіх імен, перш ніж їх шукати. У цих системах вам доведеться укласти ім'я таблиці в "подвійні лапки", щоб переконатися, що шукається точне ім'я, яке ви ввели.
Майкл Ратанапінта

2
", але часто пишуться з
великої літери

3
Наприклад, якщо сервер MS Sql встановлений за допомогою порівняння з урахуванням регістру, то імена таблиць, стовпців, змінних стають чутливими до регістру, навіть якщо база даних не відповідає чутливості регістру.
Вадим Стецяк

3
@BlackTigerX - У посібниках Oracle є всі приклади SQL з ключовими словами (SELECT, FROM, WHERE тощо), написаними великими літерами, а також назви таблиць та стовпців у нижньому регістрі.
Дж. Полфер

Хммм, це все-таки правда про mysql? Я подумав, що у мене встановлено за замовчуванням встановлення mysql, і це стосується імен регістру для імен стовпців.
Kzqai

22

Це не суто мова SQL, але в SQL Server, якщо порівняння вашої бази даних залежить від регістру, то всі назви таблиць залежать від регістру.


16

У сервері Sql це варіант . Вмикаючи його на відстій.

Я не впевнений у MySql.


У MySql нечутливість регістру - це варіант, який можна включати та вимикати. Просто ця нечутливість не працює, як можна було б вважати, що це робиться в Linux, якщо файлова система відрізняється від регістру (за замовчуванням). Вам потрібно зробити файлову систему, нечутливу до регістру, в Linux, щоб невідчутливість регістру mysql працювала так само, як у Windows (= належним чином). Особливо ввімкнення / вимкнення після роботи в режимі один одного може спричинити погані наслідки.
Стефан Штайгер

14

Ідентифікатори та зарезервовані слова не повинні враховувати великі регістри, хоча багато хто дотримується конвенції про використання великих літер для зарезервованих слів та регістру Паскаля для ідентифікаторів.

Див. SQL-92 Sec. 5.2


13

У специфікації SQL92 зазначено, що ідентифікатори можуть бути котировані або цитуватися. Якщо обидві сторони не цитуються, то вони завжди нечутливі до регістру, наприклад table_name == TAble_nAmE.

Однак цитовані ідентифікатори залежать від регістру, наприклад "table_name" != "TAble_naME". Також, виходячи з специфікації, якщо ви хочете порівнювати незареєстровані ідентифікатори з цитованими, то ідентифіковані і котируються ідентифікатори можна вважати однаковими, якщо символи без котировки є великими, наприклад TABLE_NAME == "TABLE_NAME", але TABLE_NAME != "table_name"або TABLE_NAME != "TAble_NaMe".

Ось відповідна частина специфікації (розділ 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>".

Зауважте, що, як і в інших частинах стандарту SQL, не всі бази даних повністю дотримуються цього розділу. Наприклад, PostgreSQL зберігає всі котирувані ідентифікатори з нижчим регістром, а не з великим регістром, так table_name == "table_name"(що прямо протилежне стандарту). Також деякі бази даних весь час нечутливі до регістру, або чутливість до регістру залежить від деяких параметрів у БД або залежать від деяких властивостей системи, зазвичай, залежно від того, чи стосується файлова система чи великі регістри.

Зауважте, що деякі інструменти бази даних можуть надсилати ідентифікатори, які цитуються постійно, тому у випадках, коли ви змішуєте запити, згенеровані певним інструментом (наприклад, запит CREATE TABLE, сформований Liquibase або іншим інструментом міграції БД), з ручними запитами (як звичайний вибір JDBC у вашій програмі) ви повинні переконатися, що випадки є послідовними, особливо в базах даних, де ідентифіковані цитовані та котируються ідентифікатори різні (DB2, PostgreSQL тощо)


10

Я розумію, що стандарт SQL вимагає нечутливості до регістру. Я не вірю, хоча жодна база даних повністю відповідає стандарту.

MySQL має налаштування конфігурації як частину свого "суворого режиму" (мішок захоплення кількох налаштувань, що робить MySQL більш сумісним із стандартами) для чутливих до регістру чи нечутливих імен таблиць. Незалежно від цього параметра, назви стовпців все ще не залежать від регістру, хоча, я думаю, це впливає на те, як відображаються назви стовпців. Я вважаю, що це налаштування є загальним для всіх баз даних в екземплярі RDBMS, хоча я сьогодні досліджую, щоб підтвердити це (і сподіваюся, що відповідь - ні).

Мені подобається, як Oracle справляється з цим набагато краще. У прямому SQL такі ідентифікатори, як назви таблиць та стовпців, не залежать від регістру. Однак, якщо ви з якоїсь причини дійсно бажаєте отримати явний кожух, ви можете долучити ідентифікатор до подвійних лапок (які в Oracle SQL досить відрізняються від одноцитат, що використовуються для вкладення рядкових даних). Так:

SELECT fieldName
FROM tableName;

буде запитувати ім'я поля з імені таблиці , але

SELECT "fieldName"
FROM "tableName";

буде запитувати fieldName від tableName .

Я впевнений, що ви навіть можете використовувати цей механізм для вставки пробілів або інших нестандартних символів в ідентифікатор.

У цій ситуації, якщо ви з якоїсь причини виявили бажані назви таблиць та стовпців бажаними, вони були доступні вам, але це все одно було би я дуже застерігаю.

Моя умова, коли я щодня користувався Oracle, полягала в тому, що в коді я ставлю всі ключові слова Oracle SQL у великі регістри, а всі ідентифікатори - у малі регістри. У документації я б розмістив усі назви таблиць і стовпців у великих літерах. Це було дуже зручно і легко читати (хоча іноді болісно вводити стільки великих літер у коді - я впевнений, що тут я міг знайти функцію редактора, яка допомогла б).

На мій погляд, MySQL особливо погано відрізняється з цього приводу на різних платформах. Нам потрібно мати можливість скидати бази даних у Windows та завантажувати їх у UNIX, і це стане катастрофою, якщо інсталятор у Windows забув перевести RDBMS у режим, що залежить від регістру. (Справедливо кажучи, частина причини цього - це катастрофа - це те, що наші кодери давно прийняли неправильне рішення покладатися на чутливість регістру MySQL в UNIX.) Люди, які написали інсталятор Windows MySQL Windows, зробили це дуже зручним і Windows-подібний, і було чудово рухатись до надання людям прапорця, щоб сказати: "Чи хочете ви ввімкнути суворий режим і зробити MySQL більш сумісним із стандартами?" Але MySQL дуже зручно настільки сильно відрізнятися від стандарту, а потім погіршити питання, обернувшись та відмінившись від власного фактичного стандарту на різних платформах. Я впевнений, що при різних дистрибутивах Linux це може бути ще більше ускладнене, оскільки пакувачі для різних дистрибутивів, ймовірно, часом включали власні переважні налаштування конфігурації MySQL.

Ось ще одне питання SO, яке вступає в обговорення, якщо в RDBMS бажана чутливість до регістру.


5

Ні. MySQL не відрізняється від регістру, і це не є стандартом SQL. Це просто звичайна практика писати команди великим регістром.

Тепер, якщо ви говорите про назви таблиць / стовпців, то так, вони є, але не самі команди.

Так

SELECT * FROM foo;

те саме, що

select * from foo;

але не те саме, що

select * from FOO;

2
У більшості RDBMS назви таблиць також не відрізняються від регістру. Принаймні, не за замовчуванням. MySQL - найвизначніший виняток із цього правила.

4

Я вважаю цю публікацію в блозі дуже корисною (я не автор). Узагальнення (хоча, будь ласка, прочитайте):

... розмежовані ідентифікатори залежать від регістру ("table_name"! = "table_Name"), тоді як ідентифіковані ідентифікатори не цитуються та перетворюються у верхній регістр (table_name => TABLE_NAME).

Він виявив, що DB2, Oracle та Interbase / Firebird на 100% сумісні:

PostgreSQL ... реєструє всі котирувані ідентифікатори замість верхнього корпусу. Залежить файлова система MySQL ... SQLite і SQL Server ... випадок імен таблиць і полів зберігається при створенні, але згодом вони повністю ігноруються.


2

Я не думаю, що SQL Server є чутливим до регістру, принаймні, не за замовчуванням.

Коли я запитую вручну через Management Studio, я весь час псую справу, і він радісно приймає це:

select cOL1, col2 FrOM taBLeName WheRE ...

2

Ключові слова SQL самі по собі не чутливі до регістру.

Імена таблиць, стовпців тощо мають чутливість до регістру, яка залежить від бази даних - ви, мабуть, припускаєте, що вони залежать від регістру, якщо ви не знаєте інше (у багатьох базах даних це не так; в іменах таблиць MySQL є SOMETIMES з урахуванням регістру, але в більшості інших імена немає).

Якщо порівнювати дані, використовуючи =,>, <тощо, відомо про те, що залежить від параметрів порівняння, які використовуються у відповідній окремій базі даних, таблиці чи навіть стовпцях. Однак нормально зберігати порівняння досить послідовно в базі даних. У нас є кілька стовпців, в яких потрібно зберігати чутливі до регістру значення; у них встановлено порівняння.


0

Майте найкращі з обох світів

Ці дні ви можете просто записати всі ваші заяви sql в малі регіони, і якщо вам коли-небудь потрібно буде його форматувати, просто встановіть плагін, який зробить це за вас. Це застосовується лише в тому випадку, якщо у вашому редакторі коду доступні ці плагіни. VSCode має багато розширень, які можуть це зробити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.