Вставьте значения в несколько таблиц SQL - PullRequest
1 голос
/ 16 марта 2009

Каков хороший метод для вставки табличных данных, отвечающих на многие таблицы в C # и SQL-сервере?

Например, скажем, у меня есть следующие таблицы:

Products: PK=PID, Product_Name
Build: PK:BID, Build_Number, FK:PID
Files: PK:FID, File_Name, FK:PID
FileDetails: PK:FDID, FK:FID, FK:BID, File_Size, File_Version

Таким образом, все первичные ключи являются автоматически увеличивающимися числами

Итак, у меня есть XML-файл, там у меня есть ряды информации, такие как:

Product_Name ,Build_Number,File_Name,File_Size,File_Version
FooCreator1.0,112233      ,foo.exe  ,123456   ,3.5
FooCreator1.0,112233      ,bar.exe  ,234567   ,1.5

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

Должен ли я сначала добавить все продукты, затем добавить все сборки, затем добавить все файлы, затем объединить все таблицы и затем добавить все данные файла?

РЕДАКТИРОВАТЬ: у меня будет около 20 000 строк, и я буду хранить около 40 значений на строку в окончательной уникальной таблице.

Ответы [ 5 ]

2 голосов
/ 16 марта 2009

Это то, что я бы сделал, хотя я не уверен, что это лучший способ:

declare @PID bigint
declare @BID bigint
declare @FID bigint

insert into Products (Product_Name)
values ('FooCreator1.0')

select @PID = scope_identity()

insert into Build (Build_Number, PID)
values (112233, @PID)

select @BID = scope_identity()

insert into Files (File_Name, PID)
values ('foo.exe', @PID)

select @FID = scope_identity()

insert into FileDetails (FID, BID, File_Size, File_Version)
values (@FID, @BID, 123456, '3.5')

Что-то подобное? Вероятно, вы хотите выполнить все это в транзакции, если что-то пойдет не так.

1 голос
/ 16 марта 2009

По сути, да (последнее0. Но как вы делаете это может зависеть от количества задействованных строк. Если у вас есть несколько сотен (может быть, тысяча или около того), то вы можете использовать что-то вроде LINQ-to-SQL довольно радостно: создайте нужные вам объекты и используйте InsertOnSubmit для добавления необходимых элементов в контекст данных. Наконец, вызовите SubmitChanges (работа выполнена; другие инструменты ORM будут работать аналогично).

Если у вас десятки тысяч строк (или что-то еще), вы можете просто взять весь XML в базу данных (возможно, хранимую процедуру с параметром xml). Используйте Sql / xml в базе данных и выполните 4 INSERT операторов из параметра xml.

Для сотен тысяч / миллионов строк вы хотите использовать SqlBulkCopy, чтобы поместить данные в промежуточную таблицу (как показано в примере), а затем использовать хранимую процедуру для выполнения 4 INSERT с. , Работа с XML как csv - это задача для специального считывателя данных .

0 голосов
/ 16 марта 2009

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

  • Производительность, позволяющая компилировать БД и кешировать операторы.
  • Безопасность, вызов SP с входными данными в качестве параметров ограничит использование вредоносных значений.
  • Держа структуру DB отдельно от клиента, вам не нужно будет перекомпилировать, если / когда вы захотите изменить схему.
  • Возможность добавления внутренней регистрации / обработки ошибок без вмешательства клиента.

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

Вы должны заключить инструкцию в транзакцию , чтобы убедиться, что все или ничего не сделано, и даже использовать TRY-CATCH . Но, как я уже писал, все зависит от использования операции.

/ JB

0 голосов
/ 16 марта 2009

C # /. NET может иметь лучший способ, но обычный способ сделать это, как вы предлагаете (примерно). Для каждой строки в файле XML сначала необходимо создать ПРОДУКТ (или получить его PID, если он уже существует).

Затем добавьте BUILD, если он не существует (получите BID, если он существует).

Затем добавьте ФАЙЛ, если он не существует (получите FID, если он существует).

Затем добавьте или обновите отношение «многие ко многим» в FILEDETAILS.

Каждая из операций вставки / выбора (product, build, file) будет выглядеть следующим образом:

insert into PRODUCTS (PRODUCT_NAME) VALUES ('FooCreator1.0')
// ignore errors from preceding statement
select PID from PRODUCTS where PRODUCT_NAME = 'FooCreator1.0'

, поскольку, если кто-то превзошел вас в создании этого продукта, вам просто нужен PID для последующих вставок.

0 голосов
/ 16 марта 2009

Да. Откройте транзакцию и добавьте строки в следующем порядке. Сначала нужно добавить Продукт и получить его идентификатор, чтобы иметь возможность добавить сборку и использовать этот идентификатор в качестве внешнего ключа. Вы также можете написать это как хранимую процедуру. SQL Server не имеет параметров процедуры типа списка, но если вы хотите передать сложную структуру, подобную этой, за один шаг, и у вас уже есть ее в формате XML, вы можете передать этот документ как SQL Server 2005 (вы не делали не говоря уже о том, какую версию вы используете) поддерживает параметры XML . Имея это, вы можете использовать XPath в своей хранимой процедуре для запроса содержимого и создания данных.

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