МАССОВАЯ ВСТАВКА в таблицу с внешним ключом

#sql-server-2005

#sql-server-2005

Вопрос:

У меня есть таблица Customer, в которой содержатся сведения о клиенте. Ниже приведены поля

 CustId (PrimaryKey), Name, Date of Birth
  

У меня есть другая таблица, информация об активе. Там находятся следующие поля —

 AssetId (PrimaryKey), AssetValue, CustId (Foreign Key Reference) 
  

Мой CSV-файл как таковой

 Name, Date of Birth, AssetValue 
  

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

Вот что я сделал —

 /*Creation of Table*/
CREATE TABLE Customer
(
    custid int identity(1,1) not null, 
    name nvarchar(50) not null, 
    dateofbirth datetime not null, 
    primary key (custid) 
)
CREATE TABLE Asset
(
    AssetId int identity(1,1) not null, 
    AssetDollars money not null, 
    primary key (AssetId),
    CustId int foreign key references Customer(custid)
)
  

Для массовой вставки я сделал следующее. Я создал представление для клиента с двумя полями Name и Date of Birth и затем вставил записи.

Вот что я сделал —

 CREATE view vw_bulk_insert_customer
AS
    SELECT name, dateofbirth FROM customer

BULK  INSERT vw_bulk_insert_customer
FROM 'C:Customer.csv'
WITH
(
FIELDTERMINATOR = ',',
ROWTERMINATOR = 'n'
)
  

Это сработало отлично.

Теперь, как мне вставить его в таблицу активов с CustID (поскольку он недоступен в файле CSV).

Мне не разрешено изменять файл CSV. Я могу разделить CSV-файл, это разрешено.

Я не знал, как это сделать…Есть мысли?

Ответ №1:

Одним из вариантов является импорт данных как есть во промежуточную таблицу, затем копирование данных из этой таблицы в конечные таблицы. По сути, это последняя часть нормализации базы данных (пропуская дизайн и определение нормализованных таблиц).

 /* interim table */
CREATE TABLE CustomerAssets (
    name NVARCHAR(50) NOT NULL,
    dateOfBirth DATETIME NOT NULL,
    assetDollars MONEY NOT NULL
)

BULK INSERT CustomerAssets
  FROM 'C:Customer.csv'
  WITH (
    FIELDTERMINATOR = ',',
    ROWTERMINATOR = 'n'
  )

INSERT INTO Customer (name, dateOfBirth)
  SELECT name, dateOfBirth FROM CustomerAssets;

INSERT INTO Asset (assetDollars, custId)
  SELECT CA.assetDollars, Customer.custId
    FROM CustomerAssets AS CA
      INNER JOIN Customer
        ON CA.name = Customer.name AND CA.dateOfBirth = Customer.dateOfBirth;
  

Ответ №2:

вы можете использовать disable novalidate поверх внешнего ключа. после того, как вы импортировали все свои данные, вы можете включить novalidate поверх внешнего ключа.То же самое можно сделать и с первичным ключом. Преимущество опции novalidate заключается в том, что ваши предыдущие данные не будут проверяться в соответствии с правилами этого ограничения, но данные после него, следовательно, проверяются. если вы хотите, я мог бы вставить весь синтаксис, чтобы сделать то же самое

Комментарии:

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