#c# #database
#c# #База данных
Вопрос:
Раз в месяц я получаю XML-файл со счетами клиентов за последний месяц. Мне нужно сохранить эту информацию в базе данных. У меня есть таблица с именем transactions
. Мой первичный ключ — это customers_nr
. В настоящее время, когда я вставляю данные, я получаю сообщение об ошибке
нарушение первичного ключа……
Я использую табличный адаптер для вставки. В принципе, мне нужно только продолжать заполнять базу данных информацией. Итак, есть ли какая-либо команда для обработки этого? Или как я должен сделать
Пример информации
customer_nr: 12345
Billing_name: Microsoft
Billing_city: Seattle
Billing_amount 300
Billing_name: Mcdonalds
Billing_city: Seattle
Billing_amount 25
customer_nr: 4321
Billing_name: Ikea
Billing_city: New York
Billing_amount 1200
Комментарии:
1. Итак, что должно произойти, если вы получите новую запись для клиента с идентификатором клиента, который уже существует ?!?!?!?!
Ответ №1:
Ошибка означает, что у вас дублируется значение вашего первичного ключа как минимум в двух записях.
помните, что первичный ключ обеспечивает уникальность данных внутри него.
таким образом, вы не можете вставить две записи в таблицу с одинаковым значением для первичного ключа. вы можете изменить свой первичный ключ на новое поле (например, поле автоматического номера), таким образом, вы удалили ограничение уникальности из вашего старого поля первичного ключа, а затем вы можете вставить в него дубликаты!
Комментарии:
1. Да, я знаю это. Как этого избежать?
2. вы не можете, единственный способ — переместить ваше ограничение первичного ключа в другое поле.
3. @dumbel = измените свой первичный ключ. customers_nr (который, как я предполагаю, является идентификатором для клиента) сам по себе не может быть первичным ключом вашей таблицы транзакций, поскольку у вас будет несколько транзакций для любого данного клиента. Есть ли у вас идентификатор транзакции, такой как TransactionID или transaction_num? Возможно, вы захотите использовать это вместо customers_nr для вашего первичного ключа. В принципе, вам нужно найти столбец или комбинацию столбцов в вашей таблице транзакций, которые уникальны по строке. Эти столбцы должны быть вашим первичным ключом.
4. как сказал Джереми Уилл, просто создайте новый столбец «TransactionID» и установите для автоматического номера значение true. затем измените свой первичный ключ на новый столбец. Столбец транзакции должен иметь свой собственный первичный ключ, а не ключ клиента
Ответ №2:
дата и время выставления счета мне больше подходит для первичного ключа в этом отношении, alt. customer_nr billing_datetime.
Если у вас нет даты и времени для выставления счета или вы просто знаете месяц, вы могли бы использовать customer_nr, year, month в качестве составного первичного ключа.
Ответ №3:
Тогда использование номера клиента, очевидно, не является уникальным значением, что означает, что его нельзя использовать в качестве первичного ключа.
Создайте IDENTITY
столбец или используйте GUID
с newsequentialid()
(преф. как поле по умолчанию) для получения уникального ключа в таблице.
Пример:
У вас есть структура базы данных следующим образом:
- TransactionID (Это новое поле,
uniqueidentifer
соnewsequentialid()
значением по умолчанию) - Customer_Nr
- Имя_заказчика
- Billing_city
- Billing_amount
- Имя_заказчика
- Billing_city
- Billing_amount
Затем вы должны поступить следующим образом:
INSERT INTO transactions (Customer_Nr, Billing_name, Billing_city, Billing_amount)
VALUES ('12345', 'Microsoft', 'Seattle', 300);
Как вы видите, вам не нужно будет изменять какой-либо код со значениями из-за автоматически сгенерированного (уникального) значения первичного ключа.
Примечание относительно newsequentialid()
заключается в том, что если вашим данным требуется безопасность / приватность, не используйте newsequentialid()
, поскольку угадать последовательности тривиально.
Комментарии:
1. Если вы создаете новый идентификатор — пожалуйста, во что бы то ни стало используйте
newsequentialid()
по умолчанию! Фрагментация вашего индекса будет намного меньше, чем при использовании функции randomnewid()
2. Да! Если вы создадите первичный ключ (ключ кластеризации) на
uniqueidentifier
, фрагментация индекса будет ужасной — если вы не используетеnewsequentialid()
значение по умолчанию — тогда это терпимо3. @marc — Также стоит отметить, что newsequentialid() — это большой nono, если речь идет о безопасности / конфиденциальности. Если вы знаете, как newsequentialid () реагирует на сбой сервера БД?