Как обновить таблицу SQL Server данными из другого источника (DataTable) - PullRequest
1 голос
/ 10 февраля 2012

У меня есть DataTable, сгенерированный из таблицы .xls.

Я хотел бы сохранить это DataTable в существующей таблице в базе данных SQL Server.

Я использую SqlBulkCopy для хранения строк, которые имеют уникальный PK .

Проблема в том, что у меня также есть другие строки, которые имеют такой же PK , что и таблица SQL Server, но содержат ячейкис другим значением по сравнению с таблицей SQL Server.

Короче:

Допустим, в моем DataTable есть строка, подобная этой:

id (PK) |имя |номер

005 |abc |123

006 |lge |122

Для моего сервера SQL у меня есть что-то вроде этого;

id (PK) |имя |номер

004 |cbs |345

005 |лкс |122

Теперь вы видите, что строку 006 можно сразу загрузить в SQL Server с помощью SqlBulkCopy.С другой стороны, строка 005 не может быть вставлена ​​с ее использованием, поскольку таблица сервера SQL содержит строку с идентичным PK.

Теперь я попытался извлечь строку вручную.Извлеките каждую отдельную ячейку в ArrayList, а затем сгенерируйте инструкцию UPDATE Table.Однако этот метод кажется невозможным, так как мне нужно обработать столько строк.

Я ищу лучший способ для достижения этой цели.

Любая помощь приветствуется.

Спасибо в

1 Ответ

2 голосов
/ 10 февраля 2012

Используйте следующий код:

Код стороны C # для чтения данных из DataTable и подготовки данных XML:

DataTable dt = new DataTable();
StringBuilder sb = new StringBuilder();

sb.Append("<R>");
for (int i = 0; i < dt.Rows.Count; i++)
{
    sb.Append("<C><ID>" + dt.Rows[0].ToString() + "</ID>");
    sb.Append("<N>" + dt.Rows[1].ToString() + "</N>");
    sb.Append("<I>" + dt.Rows[2].ToString() + "</I></C>");
}

sb.Append("</R>");

///pass XML string to DB side
///
//sb.ToString(); //here u get all data from data table as xml format

Хранимая процедура на стороне базы данных (вам необходимо обновить имя таблицы):

CREATE PROCEDURE dbo.UpdateData 
    -- Add the parameters for the stored procedure here
    @data       XML
AS
BEGIN
    SET NOCOUNT ON;

    -- keep data into temp table
    create table #tmp_data (id nchar(2),name varchar(20), number int)

    DECLARE @XMLDocPointer INT  
    EXEC sp_xml_preparedocument @XMLDocPointer OUTPUT, @DATA

    INSERT INTO #tmp_data(id,name,number)
    SELECT  ID,N,I
    FROM OPENXML(@XMLDocPointer,'/R/C',2)
    WITH(
            ID  nchar(30),
            N   VARCHAR(20),
            I   int
        )

    EXEC sp_xml_removedocument @XMLDocPointer

    begin tran
        -------------------INSERT not existing ones
        INSERT INTO TABLE (id,name,number)
        SELECT id,name,number
        FROM #tmp_data
        WHERE NOT EXISTS
        (
            SELECT 1
            FROM TABLE
            WHERE ID = #tmp_data.ID
        )

        --- update existing ones
        UPDATE  TABLE
        SET name = #tmp_data.name, number = #tmp_data.number
        FROM #tmp_data
        WHERE #tmp_data.id = TABLE.id

        commit tran

    if(@@error <> 0)
        rollback tran

END
...