C# BulkCopy.WriteToServer Изменение значений - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть таблица данных, созданная на основе листа Excel. Я пытаюсь SqlBulkCopy.WriteToServer. Когда я это делаю, он преобразует мое значение «Percent» в 0, когда схема моих таблиц имеет тип Decimal (38,0) для столбца «Percent». Тем не менее, он вставляется правильно, когда у меня есть тип данных как Float. Я не уверен, что происходит. Я хотел бы использовать десятичную дробь (38, 0), если это возможно, поскольку электронная таблица, которую мне дают, может go содержать более 15 знаков после запятой для этого значения.

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

Вот мой c# код:

private bool ImportToDataBase(DataTable emeTable)
{
    string serverName = PARR_DBDataObject.ServerName;
    string dbName = PARR_DBDataObject.DBName;
    bool dataUploaded = false;

    using ( SqlConnection conn = SQL.ConnectToDB(dbName, serverName, false))
    {
        conn.Open();
        string createTempTable = $@"CREATE TABLE #Holdings(
                                        [Fund][varchar](25) NULL,
                                        [Percent] [varchar](38) NULL,
                                        [Committed] [varchar](25) NULL,
                                        [DryPowder] [varchar](25) NULL,
                                        [CashBalance] [varchar](25) NULL,
                                        [Trades] [varchar](25) NULL,
                                        [Capital] [varchar](25) NULL,
                                        [MgmtFee] [varchar](25) NULL,
                                        [Cash] [varchar](25) NULL,
                                        [ReportDate] [datetime] NULL);";
        SqlCommand cmd = new SqlCommand(createTempTable, conn);
        cmd.ExecuteNonQuery();

        using(SqlBulkCopy blkCopy = new SqlBulkCopy(conn))
        {
            decimal test = Convert.ToDecimal(emeTable.Rows[0][1]);
            foreach(DataColumn col in emeTable.Columns)
            {
                blkCopy.ColumnMappings.Add(col.Ordinal, col.Ordinal);
            }

            blkCopy.DestinationTableName = "#Holdings";
            blkCopy.WriteToServer(emeTable);

            string sqlSelect = "SELECT * FROM #Holdings";
            SqlCommand emeCmd = new SqlCommand(sqlSelect, conn);
            SqlDataAdapter da = new SqlDataAdapter(emeCmd);
            DataTable testTable = new DataTable();
            da.Fill(testTable);
            da.Dispose();
        }
        string spName = DBDataObject.sp_Insert_Into_CashHoldings;
        SqlCommand cmdSP = new SqlCommand(spName, conn);
        cmdSP.ExecuteNonQuery();

        //SQL.NonQueryStoredProcedure(spName, dbName, serverName, false, 600);
        dataUploaded = true;

    }
    return dataUploaded; 
}

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

ALTER PROCEDURE [dbo].[sp_Insert_Into_CashHoldings] 

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    MERGE t_CashHoldings AS TARGET 
        USING #Holdings AS SOURCE
    ON (TARGET.Fund = SOURCE.Fund AND TARGET.ReportDate= SOURCE.ReportDate)
    WHEN MATCHED THEN
        UPDATE SET TARGET.Percent = SOURCE.Percent, 
                   TARGET.Committed = SOURCE.Committed,
                   TARGET.DryPowder = SOURCE.DryPowder,
                   TARGET.Trades = SOURCE.Trades,
                   TARGET.Capital = SOURCE.Capital,
                   TARGET.MgmtFee = SOURCE.MgmtFee,
                   TARGET.Cash = SOURCE.Cash
    WHEN NOT MATCHED THEN
    INSERT (Fund, Percent, Committed, DryPowder, CashBalance, Trades, Capital, MgmtFee, Cash, ReportDate)
    VALUES (SOURCE.Fund, SOURCE.Percent, SOURCE.Committed, SOURCE.DryPowder, SOURCE.CashBalance, SOURCE.Trades, SOURCE.Capital,
            SOURCE.MgmtFee, SOURCE.Cash, SOURCE.ReportDate);

    DROP TABLE #Holdings;

END

1 Ответ

1 голос
/ 04 февраля 2020

Если это неправильный ответ, я могу удалить его, но если вы сделаете десятичную (38,0), которая говорит, что вы хотите #, который имеет 38 знаков слева от десятичного знака и допускает 0 справа. Вы бы хотели что-то вроде 38,10, что означало бы общее число 38, но 28 слева и 10 справа. Если ваши значения хранятся как 0,56, возможно, именно поэтому его обрезают.

При этом я бы рекомендовал сделать что-то вроде 28,10, потому что. NET поддерживает только до 28 точности против sql на сервере 38. Если вы попытаетесь ввести такой большой # к этому. NET позже, он взломает sh.

Надеюсь, это поможет!

...