Стоит ли цитировать числа в SQL? - PullRequest
21 голосов
/ 17 января 2010

Я помню, что читал о кавычках, когда выполнял SQL-запрос, и что когда вы что-то цитируете, он становится строкой. Я также читал, что цифры не должны быть в кавычках. Теперь я не могу найти эту цитату, и мне нужно освежить свою память, чтобы посмотреть, нужно ли мне цитировать цифры.

Ответы [ 7 ]

14 голосов
/ 17 января 2010

Вы не должны цитировать цифры.

Вы правы, вспомнив, что это делает его строкой.

SELECT 10 AS x

совершенно законно и возвращает (в большинстве движков баз данных) столбец типа данных int (или его вариант).

Я заметил комментарий к вашему вопросу от Адама, и я хотел бы сделать комментарий к нему, но я отредактирую этот ответ, потому что я думаю, что это важный момент.

Заключение в кавычки "цифр" в SQL обычно делается, когда это не число , а вместо код .

Под числом Я имею в виду то, что вы можете посчитать, суммировать, рассчитать, код - это идентификатор.

Таким образом, SSN - это код, это ваш уникальный код (я знаю, N обозначает «число», немного ошибочно, если вы спросите меня), но вы не пытаетесь вычислить среднее значение всех SSN. в базе данных.

Если вы храните идентификаторы продуктов в базе данных в виде строк, но в действительности они состоят только из цифр, то это коды, а не цифры.

Коды должны быть в кавычках, цифры не должны.

6 голосов
/ 17 января 2010

Вот пример, где цитирование может привести к противоречивым результатам (в MySQL):

select 1 < 1.0;      // returns 0

select '1' < '1.0';  // returns 1

Это потому, что второе сравнение выполняется с использованием текущего сопоставления строк, а не численно.

Лучше не заключать в кавычки числа, так как это было бы просто лишним шагом для базы данных, чтобы преобразовать строковый литерал в числовое значение для сравнения и могло бы изменить смысл сравнений.

4 голосов
/ 16 апреля 2018

Этот ответ предназначен для Microsoft SQL Server, в частности MSSQL 2008 R2.

В рукописном SQL я бы никогда не заключал в кавычки числа (если только не вставить значение в столбец varchar, где вставленная строка просто является числом). Но иногда при генерации SQL программным способом можно упростить жизнь, просто цитируя все. (Это в сценариях обслуживания базы данных или в подпрограммах библиотеки, которые работают с любой таблицей, не зная заранее типов столбцов.)

Интересно, будет ли это налагаться на производительность? Если в своем выражении SQL я использовал значение в кавычках, сервер должен проанализировать его как строку, а затем преобразовать в целое число. Но тогда синтаксический анализ SQL в любом случае будет включать преобразование строк в целые числа. И время разбора запроса обычно составляет лишь небольшую часть от общего.

Я запустил несколько тестовых утверждений, похожих на

insert into #t values (123, 123, 123), (123, 123, 123)
insert into #t values ('123', '123', '123'), ('123', '123', '123')

, но с большим числом столбцов в #t, большее количество кортежей значений вставляется за один раз, и каждый оператор повторяется много раз. Я использовал Perl для этого:

$dbh = my_database_connection(); # using DBD::Sybase
$n = 20; # this many value tuples, and also repeated this many times
$v = "'123'";
# $v = 123;    # uncomment this to insert without quoting

@cols = 'aa' .. 'zz';
@ds = map { "[$_] int not null" } @cols;
@vs = map { $v } @cols;
$" = ", ";
$dbh->do("create table #t (@ds)");
foreach (1 .. $n) {
    $sql = 'insert into #t values ';
    $sql .= "(@vs), " foreach 1 .. $n;
    $sql =~ s/, \z//;
    $dbh->do($sql);
}

но вы можете тривиально написать один и тот же тест на любом языке. Я запускал это несколько раз для цитируемого случая и для не цитируемого, и не наблюдал существенной разницы в скорости. (На моей установке один запуск занял около десяти секунд; очевидно, вы можете изменить $n, чтобы сделать его быстрее или медленнее.)

Конечно, сгенерированный SQL больше, если в нем есть избыточные символы кавычек. Это, конечно, не может быть немного быстрее, но, похоже, заметно медленнее.

Учитывая этот результат, я упросту свой код генерации SQL, добавив одинарные кавычки вокруг всех значений, без необходимости знать тип данных столбца, в который нужно вставить. (Код по-прежнему нужно защищать от внедрения SQL, следя за тем, чтобы входное значение само по себе не содержало символ ', или иным образом умело цитировал.)

Я по-прежнему не рекомендую заключать числа в SQL в обычном порядке, но если вы обнаружите, что должны это сделать, это не причинит никакого вреда. Точно так же в сгенерированном коде я помещаю [] вокруг имен столбцов, независимо от того, нужен он или нет, но я считаю, что это ненужная затея в рукописном SQL.

1 голос
/ 17 января 2010

Очевидно, не забудьте проверить, чтобы любое переданное вами значение действительно было числом.

1 голос
/ 17 января 2010

Я не знаю, что вы, возможно, прочитали, но не указывайте цифры.

0 голосов
/ 12 июня 2017

Что ж, рискуя зажечь пламя, могу ли я почтительно не согласиться с тем, что НИКОГДА нельзя использовать одинарные кавычки вокруг числового значения? Мне кажется, что ИНОГДА имеет смысл использовать одинарные кавычки вокруг числового значения. Если col1 является столбцом INT, то (на примере vbscript)

sql = "INSERT " & foo & " INTO col1 WHERE ID = 1"

и

sql = "INSERT '" & foo & "' INTO col1 WHERE ID = 1"

ОБА, когда будет выполнен sql, правильно вставьте любое целочисленное значение foo. Но что, если вы хотите, чтобы 0 вставлялся, когда foo не инициализирован? Использование приведенного в кавычках числового выражения предотвращает ошибку и обрабатывает нулевой регистр. Считаете ли вы это хорошей практикой, это, безусловно, правда.

0 голосов
/ 17 января 2010

эх ... нет, не надо?

Я предполагаю, что вы имеете в виду, цитируя , заключив в ' like 'this'

INSERT INTO table (foo) VALUES (999); совершенно законно, если foo является столбцом типа INT INSERT INTO table (foo) VALUES('foo'); Вставляет строку foo в таблицу. Конечно, вы не можете сделать это в таблицах типа INT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...