Почему я должен включать столбец первичного ключа в этот оператор вставки?

Дана база данных SQL Server Express Compact Edition с таблицей «Клиенты» со следующими столбцами:

ID, FirstName, MiddleName, Nickname, LastName, Suffix, IsMale

где ID — это автоматически увеличивающийся первичный ключ/идентификационное значение, когда я пытаюсь использовать эту команду в таблице:

INSERT INTO Clients (Title, FirstName, MiddleName, Nickname, LastName, Suffix,
IsMale) VALUES ('', 'John', '', '', 'Smith', '', 'True')

все работает. Но когда я пытаюсь использовать эту команду:

INSERT INTO Clients VALUES ('', 'John', '', '', 'Smith', '', 'True')

появляется эта ошибка:

The number of columns in the query and the table must match. [ Number of columns
in query = 7, Number of columns in table = 8 ]

Я уже давно использую операторы вставки с SQL Server, и это никогда не было проблемой; проверка по количеству столбцов всегда игнорировала автоинкрементные первичные ключи/типы удостоверений. Единственная существенная разница в этом случае заключается в том, что сейчас я использую очень дешевую версию SQL Server, тогда как я привык использовать гораздо более профессиональные версии. В случае, если это может иметь значение, я использую это в программе на С#.

Что может быть причиной этого? Спасибо.

РЕДАКТИРОВАТЬ. В этом вопросе основное внимание уделяется тому факту, что я никогда не сталкивался с этой проблемой при использовании несвободных, некомпактных версий SQL Server. SQL-серверы, которые я использовал раньше, ВСЕГДА были достаточно умны, чтобы игнорировать столбец идентификатора/первичного ключа в подсчете столбцов и просто вычислять автоматически увеличивающееся значение без необходимости указывать конкретные имена столбцов.

Хотя еще одно отличие здесь заключается в том, что я всегда использовал SQL Management Studio для работы с определениями таблиц раньше, тогда как в этом случае я использую VS 2012 и SQL Server Compact Edition. Задействованные пользовательские интерфейсы, очевидно, довольно разные, поэтому я думаю, может быть, что-то указано для таблицы или что-то еще, когда вы делаете это в Management Studio, что предотвращает возникновение этой проблемы?


person Panzercrisis    schedule 11.01.2013    source источник
comment
См. (и следуйте!): list.aspx" rel="nofollow noreferrer">Плохие привычки: использование SELECT */пропуск списка столбцов – рекомендуется всегда явно указывать список столбцов – как в SELECT, так и в INSERT заявление   -  person marc_s    schedule 11.01.2013
comment
Это действительно работает. Дело должно быть в чем-то другом. (Например, ваш ID на самом деле не является IDENTITY, а вместо этого обрабатывается триггером.) Сказав это, я согласен с комментарием @marc_s.   -  person Andriy M    schedule 11.01.2013
comment
Сейчас я использую очень младшую версию SQL Server, тогда как я привык использовать гораздо более профессиональные версии - пожалуйста, подробнее   -  person AakashM    schedule 11.01.2013
comment
SQL Server Compact Edition Express, тогда как, хотя я и забыл, как именно он называется, мы, как правило, используем на работе полностью полноценный SQL Server 2012 в комплекте с SQL Server Management Studio. Несмотря на то, что я не помню точно названия, я использую здесь бесплатную версию компактной версии, в то время как я обычно использую дорогие некомпактные версии. Я сейчас не на работе, поэтому не могу найти точное название.   -  person Panzercrisis    schedule 12.01.2013
comment
@Andriy: я вижу, что он работает по этой ссылке, но он не будет работать, когда я добавлю его в свой собственный код. Я изменил имя таблицы на Clients2. Затем он, похоже, не распознал тип данных varchar или что-то в этом роде (чего быть не может, верно?), поэтому я заменил их на nvarchars. Кроме этого, я ничего не менял, но я все еще получаю эту ошибку. Что такого необычного?   -  person Panzercrisis    schedule 13.01.2013
comment
Это может быть что-то специфичное для Compact Edition (если это действительно версия вашего сервера), но я не могу сказать наверняка. Никогда не работал с Compact Edition, а что касается тех версий, с которыми я работал, то не помню, чтобы когда-либо сталкивался с такими проблемами.   -  person Andriy M    schedule 15.01.2013
comment
Андрей, опубликуй свой последний комментарий как ответ, и я приму его.   -  person Panzercrisis    schedule 25.01.2013


Ответы (4)


Если вы не укажете столбцы в операторе вставки, тогда будут учитываться все столбцы. Даже если один из столбцов автоматически увеличивается.

Вставка — MSDN

column_list должен использоваться, когда явные значения вставляются в столбец идентификации, а параметр SET IDENTITY_INSERT должен быть включен для таблицы.

person Habib    schedule 11.01.2013
comment
Да, но по умолчанию столбец автоинкремента обрабатывается так же, как вычисляемые столбцы, если вы не предоставили список столбцов, что означает, что вы должны указать значения только для всех обычных столбцов. Это, в свою очередь, означает, что оператор OP должен работать, если ID действительно является столбцом IDENTITY (в чем я сейчас очень сомневаюсь, иначе они что-то забыли упомянуть). - person Andriy M; 11.01.2013

Оператор INSERT INTO можно записать в двух формах.

В первой форме не указаны имена столбцов, в которые будут вставлены данные, только их значения:

INSERT INTO table_name
VALUES (value1, value2, value3,...)

Это будет работать только в том случае, если количество предоставленных значений соответствует количеству столбцов точно.

Вторая форма указывает как имена столбцов, так и значения, которые необходимо вставить:

INSERT INTO table_name (column1, column2, column3,...)
VALUES (value1, value2, value3,...)

Это форма, которую необходимо использовать, даже если имеется столбец идентификатора типа идентификатора.

Радж


person Raj    schedule 11.01.2013
comment
По какой-то причине я всегда видел, как это работает при использовании дорогих некомпактных версий SQL Server/SQL Management Studio. - person Panzercrisis; 12.01.2013

вы забыли упомянуть, что таблица Clients имеет имя столбца Title. Первый запрос работает, потому что вы явно определили значения для столбцов, которые вы указали в операторе.

Второй не удался, потому что вы используете Implicit тип оператора INSERT. При использовании этого типа INSERT необходимо указать все значения для всех столбцов в таблице. Так как первый столбец в таблице ID и Auto_Incremented, NULL можно использовать для замены значения.

INSERT INTO Clients VALUES (NULL, '', 'John', '', '', 'Smith', '', 'True')
person John Woo    schedule 11.01.2013

я думаю, что '' представляет собой пустую строку, которую нельзя вставить в целочисленное значение

поэтому вы можете указать NULL вместо ' '

person vidyadhar    schedule 11.01.2013