none
Ошибка при вставки данных используя .NET класс SqlBulkCopy RRS feed

  • Общие обсуждения

  • Доброго времени суток уважаемые!!! Есть сервер на Windows Server 2003 SP2 x32 на нем стоит SQL Server 2005. В этой СУБД имеется 1 БД. В этой БД активно используется только 1 таблица, в нее каждые 3 минуты (00, 03, 06 минут) с различных экземпляров моей программы (код ниже) поступают в таблицу [dbo].[OBJ_PARAMETER_VALUE] с использованием класса .NET SqlBulkCopy. Вопрос 1. Дело в том что иногда возникают исключения: +[spoiler ]16.02.2011 11:51:00.286 Сервер: sr-sql. Сообщение: Невозможно вставить повторяющуюся ключевую строку в объект "dbo.OBJ_PARAMETER_VALUE" с уникальным индексом "PK_ID_TIMESTAMP". Выполнение данной инструкции было прервано.. Код ошибки: -2146232060. Процедура: . Номер строки: 1 Однако ситуаций вызывающих это исключений быть не может, на каждом экземпляре диапазон OBJ_PARAMETER_ID свой, то есть по этому индексу вообще не должно быть таких исключений... Подскажите пожалуйста что не так? Вопрос 2. Насколько корректна и правильна процедура GetAirValues? Спасибо. SELECT @@version Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) Feb 9 2007 22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2) Создание таблицы USE [ASKU] GO /****** Object: Table [dbo].[OBJ_PARAMETER_VALUE] Script Date: 02/11/2011 12:05:35 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[OBJ_PARAMETER_VALUE]( [OBJ_PARAMETER_VALUE_ID] [numeric](38, 0) IDENTITY(1,1) NOT NULL, [OBJ_PARAMETER_ID] [numeric](38, 0) NOT NULL, [LIST_PARSTATUS_ID] [numeric](38, 0) NULL, [VALUE] [numeric](38, 10) NOT NULL, [TIMESTAMP] [datetime] NOT NULL, CONSTRAINT [PK_OBJ_PARAMETER_VALUE] PRIMARY KEY CLUSTERED ( [OBJ_PARAMETER_VALUE_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO Indexes USE [ASKU] GO /****** Object: Index [PK_ID_TIMESTAMP] Script Date: 02/11/2011 12:06:50 ******/ CREATE UNIQUE NONCLUSTERED INDEX [PK_ID_TIMESTAMP] ON [dbo].[OBJ_PARAMETER_VALUE] ( [OBJ_PARAMETER_ID] ASC, [TIMESTAMP] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO USE [ASKU] GO /****** Object: Index [PK_ID_VALUE] Script Date: 02/11/2011 12:11:17 ******/ CREATE NONCLUSTERED INDEX [PK_ID_VALUE] ON [dbo].[OBJ_PARAMETER_VALUE] ( [OBJ_PARAMETER_ID] ASC, [VALUE] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO USE [ASKU] GO /****** Object: Index [PK_OBJ_PARAMETER_VALUE] Script Date: 02/11/2011 12:11:42 ******/ ALTER TABLE [dbo].[OBJ_PARAMETER_VALUE] ADD CONSTRAINT [PK_OBJ_PARAMETER_VALUE] PRIMARY KEY CLUSTERED ( [OBJ_PARAMETER_VALUE_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO [/spoiler] +[spoiler Keys]USE [ASKU] GO /****** Object: Index [PK_OBJ_PARAMETER_VALUE] Script Date: 02/11/2011 12:12:28 ******/ ALTER TABLE [dbo].[OBJ_PARAMETER_VALUE] ADD CONSTRAINT [PK_OBJ_PARAMETER_VALUE] PRIMARY KEY CLUSTERED ( [OBJ_PARAMETER_VALUE_ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO Stored Procedure GetAirValues USE [ASKU] GO /****** Object: StoredProcedure [dbo].[GetAirValues] Script Date: 02/11/2011 12:13:05 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[GetAirValues] (@Date DATETIME, @GroupId INT) AS BEGIN DECLARE @NAMES NVARCHAR(max); DECLARE @T_NAMES NVARCHAR(max); DECLARE @SQL NVARCHAR(max); DECLARE @CNT INT; DECLARE @STP INT; IF DATEPART(YEAR,GETDATE()) = DATEPART(YEAR,@Date) BEGIN IF DATEPART(MONTH,GETDATE()) = DATEPART(MONTH,@Date) BEGIN IF DATEPART(DAY,GETDATE()) = DATEPART(DAY,@Date) BEGIN SET @CNT = DATEPART(HOUR,GETDATE()) END ELSE BEGIN SET @CNT = 23 END END ELSE BEGIN SET @CNT = 23 END END ELSE BEGIN SET @CNT = 23 END SET @STP = @CNT WHILE @CNT >= 0 BEGIN IF @CNT = @STP BEGIN SET @NAMES = '[' + CONVERT(NVARCHAR,@CNT) + ']' SET @T_NAMES = '[' + CONVERT(NVARCHAR,@CNT) + '] AS [' + CONVERT(NVARCHAR,@CNT) + ' ч.]' END IF @CNT < @STP BEGIN SET @NAMES = '[' + CONVERT(NVARCHAR,@CNT) + '],' + @NAMES SET @T_NAMES = '[' + CONVERT(NVARCHAR,@CNT) + '] AS [' + CONVERT(NVARCHAR,@CNT) + ' ч.],' + @T_NAMES END SET @CNT = @CNT - 1 END SELECT @SQL = ' WITH SELRES ([OBJ_PARAMETER_ID], [NAME], [VALUE], [TIMESTAMP]) AS ( SELECT par.[OBJ_PARAMETER_ID], par.[NAME] + '''+', '+ '''+lu.[NAME], val.[VALUE], val.[TIMESTAMP] FROM [dbo].[OBJ_PARAMETER] par INNER JOIN [dbo].[LINK_PARGROUP] gr ON gr.[OBJ_PARAMETER_ID]=par.[OBJ_PARAMETER_ID] INNER JOIN [dbo].[LIST_UNIT] lu ON par.[LIST_UNIT_ID] = lu.[LIST_UNIT_ID] INNER JOIN [dbo].[OBJ_GROUP] ogr ON ogr.[OBJ_GROUP_ID]=gr.[OBJ_GROUP_ID] INNER JOIN [dbo].[OBJ_PARAMETER_VALUE] val ON val.OBJ_PARAMETER_ID = par.OBJ_PARAMETER_ID WHERE gr.[OBJ_GROUP_ID] = CONVERT(INT,@GroupId) AND val.[TIMESTAMP] >= @Date AND val.[TIMESTAMP] < DATEADD(DAY,1,@Date) ) SELECT [NAME] AS [Параметр] ,'+@T_NAMES+' FROM (SELECT [NAME], [VALUE], x = cast(datepart(hour,[TIMESTAMP]) as varchar) from SELRES) T PIVOT ( AVG ( VALUE ) FOR [x] IN ('+@NAMES+') ) PVT ' --PRINT @SQL EXEC sp_executesql @SQL, N'@Date datetime, @GroupId int', @Date, @GroupId END GO Код на C# с использованием SqlBulkCopy private void ProcessData(DateTime currentTime) { try { Stopwatch DatPr = new Stopwatch(); DatPr.Start(); IList<ValueData> valdata; IList<RecieveData> Params; SqlConnection Connection = null; lock (((ICollection)this.ValuesList).SyncRoot) { valdata = new List<ValueData>(this.ValuesList); this.ValuesList.Clear(); } lock (((ICollection)this.RecieveDataList).SyncRoot) { Params = new List<RecieveData>(this.RecieveDataList); } var query = from v in valdata group v by v.OBJ_PARAMETER_ID into g join p in Params on g.Key equals p.OBJ_PAR_ID into gj from j in gj where g.Where(x => (j.MIN_VALUE == null || j.MIN_VALUE <= x.VALUE) && (j.MAX_VALUE == null || j.MAX_VALUE >= x.VALUE)).Count() > 0 select new { OBJ_PARAMETER_ID = j.OBJ_PAR_ID, VALUE = g.Where(x => (j.MIN_VALUE == null || j.MIN_VALUE <= x.VALUE) && (j.MAX_VALUE == null || j.MAX_VALUE >= x.VALUE)) .Average(x => x.VALUE) }; DatPr.Stop(); #region Simple LINQ query /*var query = (from v in valdata group v by v.OBJ_PARAMETER_ID into g select new { OBJ_PARAMETER_ID = g.Key, VALUE = g.Average(x => x.VALUE) }).ToList();*/ #endregion if (SQLConnectionString != null && SQLConnectionString != string.Empty) { Connection = new SqlConnection(SQLConnectionString); SqlTransaction Transaction = null; try { Connection.Open(); Transaction = Connection.BeginTransaction(); DataTable table = new DataTable(); DataColumn par_column = new DataColumn(); par_column.ColumnName = "OBJ_PARAMETER_ID"; par_column.Caption = "OBJ_PARAMETER_ID"; par_column.DataType = System.Type.GetType("System.Int32"); par_column.AutoIncrement = false; par_column.ReadOnly = false; table.Columns.Add(par_column); DataColumn val_column = new DataColumn(); val_column.ColumnName = "VALUE"; val_column.Caption = "VALUE"; val_column.DataType = System.Type.GetType("System.Double"); val_column.AutoIncrement = false; val_column.ReadOnly = false; table.Columns.Add(val_column); DataColumn time_column = new DataColumn(); time_column.ColumnName = "TIMESTAMP"; time_column.Caption = "TIMESTAMP"; time_column.DataType = System.Type.GetType("System.DateTime"); time_column.AutoIncrement = false; time_column.ReadOnly = false; table.Columns.Add(time_column); DataColumn parst_column = new DataColumn(); parst_column.ColumnName = "LIST_PARSTATUS_ID"; parst_column.Caption = "LIST_PARSTATUS_ID"; parst_column.DataType = System.Type.GetType("System.Int32"); parst_column.AutoIncrement = false; parst_column.ReadOnly = false; table.Columns.Add(parst_column); DataRow row; foreach (var data in query) { row = table.NewRow(); row["OBJ_PARAMETER_ID"] = Convert.ToInt32(data.OBJ_PARAMETER_ID); row["VALUE"] = data.VALUE; row["TIMESTAMP"] = currentTime; row["LIST_PARSTATUS_ID"] = 1; table.Rows.Add(row); } try { bool Cis0=false, Dis0 = false; foreach (var CalcPar in CalcValuesList) { MathParser parser = new MathParser(); foreach (var data in query) { if (string.Equals(data.OBJ_PARAMETER_ID, CalcPar.X, StringComparison.OrdinalIgnoreCase)) { parser.X = data.VALUE; this.LogText(LogStyle.InformationStyle, "X ID=" + data.OBJ_PARAMETER_ID + " " + data.VALUE.ToString()); } if (string.Equals(data.OBJ_PARAMETER_ID, CalcPar.Y, StringComparison.OrdinalIgnoreCase)) { parser.Y = data.VALUE; this.LogText(LogStyle.InformationStyle, "Y ID=" + data.OBJ_PARAMETER_ID + " " + data.VALUE.ToString()); } if (string.Equals(data.OBJ_PARAMETER_ID, CalcPar.T, StringComparison.OrdinalIgnoreCase)) { parser.T = data.VALUE; this.LogText(LogStyle.InformationStyle, "T ID=" + data.OBJ_PARAMETER_ID + " " + data.VALUE.ToString()); } if (string.Equals(data.OBJ_PARAMETER_ID, CalcPar.Z, StringComparison.OrdinalIgnoreCase)) { parser.Z = data.VALUE; this.LogText(LogStyle.InformationStyle, "Z ID=" + data.OBJ_PARAMETER_ID + " " + data.VALUE.ToString()); } if (string.Equals(data.OBJ_PARAMETER_ID, CalcPar.C, StringComparison.OrdinalIgnoreCase)) { parser.C = data.VALUE; if (data.VALUE <= 1) { Cis0 = true; } this.LogText(LogStyle.InformationStyle, "C ID=" + data.OBJ_PARAMETER_ID + " " + data.VALUE.ToString()); } if (string.Equals(data.OBJ_PARAMETER_ID, CalcPar.D, StringComparison.OrdinalIgnoreCase)) { parser.D = data.VALUE; if (data.VALUE <= 1) { Dis0 = true; } this.LogText(LogStyle.InformationStyle, "D ID=" + data.OBJ_PARAMETER_ID + " " + data.VALUE.ToString()); } } parser.Expression = CalcPar.Expression; this.LogText(LogStyle.InformationStyle, "X=" + parser.X + " Y=" + parser.Y + " T=" + parser.T + " Z=" + parser.Z + " C=" + parser.C + " D=" + parser.D); parser.OptimizationOn = false; parser.Parse(); row = table.NewRow(); row["OBJ_PARAMETER_ID"] = Convert.ToInt32(CalcPar.ID); if (Dis0 || Cis0) { row["VALUE"] = 0; } else { row["VALUE"] = parser.ValueAsDouble; } row["TIMESTAMP"] = currentTime; row["LIST_PARSTATUS_ID"] = 1; table.Rows.Add(row); parser = null; Dis0 = false; Cis0 = false; this.LogText(LogStyle.InformationStyle, row["VALUE"].ToString()); } } catch (ParserException e) { this.LogText(LogStyle.ErrorStyle, "Ошибка парсера формулы. " + e.Message); } catch (Exception e) { this.LogText(LogStyle.ErrorStyle, "Ошибка вычисляемых параметров. " + e.Message); } System.Data.SqlClient.SqlBulkCopy bcopy = new SqlBulkCopy(Connection, SqlBulkCopyOptions.FireTriggers, Transaction); bcopy.ColumnMappings.Add("OBJ_PARAMETER_ID", IDColumn); bcopy.ColumnMappings.Add("VALUE", ValColumn); bcopy.BatchSize = 1; bcopy.ColumnMappings.Add("TIMESTAMP", DateColumn); bcopy.ColumnMappings.Add("LIST_PARSTATUS_ID", "LIST_PARSTATUS_ID"); bcopy.DestinationTableName = ValuesTable; Stopwatch DatWr = new Stopwatch(); DatWr.Start(); this.RowsCopied = 0; bcopy.NotifyAfter = 1; bcopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bcopy_SqlRowsCopied); bcopy.WriteToServer(table); DatWr.Stop(); Transaction.Commit(); bcopy.Close(); Connection.Close(); Connection.Dispose(); this.LogText(LogStyle.InformationStyle, valdata.Count().ToString()+" Обработано за " + TimeToString(DatPr.Elapsed.TotalMilliseconds) + " записано " + this.RowsCopied.ToString() + " из " + table.Rows.Count.ToString() + " параметров за " + TimeToString(DatWr.Elapsed.TotalMilliseconds)); table.TableName = "Data"; table.Dispose(); } catch (SqlException SqlEx) { this.LogText(LogStyle.ErrorStyle, "Сервер: " +SqlEx.Server + ". Сообщение: " + SqlEx.Message + ". Код ошибки: " + SqlEx.ErrorCode + ". Процедура: " + SqlEx.Procedure + ". Номер строки: " + SqlEx.LineNumber); if (query.Count() > 0 && this.RowsCopied == 0) { lock (((ICollection)ValuesStoreList).SyncRoot) { foreach (var data in query) { ValueData val = new ValueData(); val.OBJ_PARAMETER_ID = data.OBJ_PARAMETER_ID; val.VALUE = data.VALUE; val.TIMESTAMP = currentTime; ValuesStoreList.Add(val); } this.WriteToXMLStorage(); } } Transaction.Commit(); } } else { this.LogText(LogStyle.ErrorStyle, "Соединение с БД MS SQL Server не настроено!"); } } catch (Exception ex) { this.LogText(LogStyle.ErrorStyle, "Сообщение: " + ex.Message + "Трассировка: " + ex.StackTrace); } MemoryManagement.FlushMemory(); }
    16 февраля 2011 г. 10:17

Все ответы

  • Здравствуйте, не могли бы вы оформить вопрос более читабельно, а не одним предложением. Для вставки кода есть кнопка - . Хорошо оформленный вопрос - 50% успеха получить быстрый и нужный ответ.


    Для связи [mail]
    17 февраля 2011 г. 6:45
  • Вопрос 1. Дело в том что иногда возникают исключения: +[spoiler ]16.02.2011 11:51:00.286 Сервер: sr-sql. Сообщение: Невозможно вставить повторяющуюся ключевую строку в объект "dbo.OBJ_PARAMETER_VALUE" с уникальным индексом "PK_ID_TIMESTAMP". Выполнение данной инструкции было прервано.. Код ошибки: -2146232060. Процедура: . Номер строки: 1 Однако ситуаций вызывающих это исключений быть не может, на каждом экземпляре диапазон OBJ_PARAMETER_ID свой, то есть по этому индексу вообще не должно быть таких исключений... Подскажите пожалуйста что не так?

    А насколько часто возникают такие ошибки? Если есть возможность и используется полная версия Microsoft SQL Server, запустите, пожалуйста, SQL Server Profiler и отследите, какие данные приводят к генерации этого исключения.

    По второму вопросу — извините, не смог разобраться в коде.

    18 февраля 2011 г. 15:04
  • Уважаемый пользователь!

    В вашей теме отсутствует активность в течение последних 5 дней. При отсутствии каких-либо действий в течение 2 последующих дней, тема будет переведена в разряд обсуждений. Вы можете возобновить дискуссию, просто оставив сообщение в данной теме


    Для связи [mail]
    25 февраля 2011 г. 7:50