Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Ошибка при сохранении данных, значение параметра вне допустимого диапазона. / 8 сообщений из 8, страница 1 из 1
27.05.2015, 12:17
    #38969632
Евгений В
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
Клиент на C#, сервер MSSql
В качестве ID на сервере используется numeric(18,0)

Проблема: при апдейте данных НЕКОТОРЫЕ строки выбрасывают исключение с ошибкой вида "Значение параметра \"...\" вне допустимого диапазона"
вместо ... - идентификатор записи. Конкретный пример:

серверный код:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
CREATE TABLE [dbo].[Synonyms](
	[SynonymId] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
	[SynonymText] [nvarchar](255) NOT NULL,
	[CircleId] [numeric](18, 0) NOT NULL,
	[IsActive] [bit] NOT NULL,
	[Comment] [nvarchar](100) NULL,
	[Source] [nvarchar](100) NULL,
	[IsEthalon] [bit] NOT NULL,
 CONSTRAINT [PK_Synonyms] PRIMARY KEY CLUSTERED 
(
	[SynonymId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

SET IDENTITY_INSERT [dbo].[Synonyms] ON 
INSERT [dbo].[Synonyms] ([SynonymId], [SynonymText], [CircleId], [IsActive], [Comment], [Source], [IsEthalon]) VALUES (CAST(65 AS Numeric(18, 0)), N'Новый синоним', CAST(3 AS Numeric(18, 0)), 1, N'', N'', 0)
SET IDENTITY_INSERT [dbo].[Synonyms] OFF

create PROCEDURE [dbo].[Synonym_Put]
      @Id numeric(18,0) OUTPUT
    , @Text nvarchar(255)
    , @CircleId numeric(18,0)
    , @Comment nvarchar(100)
    , @Source nvarchar(100)
    , @IsEthalon bit
AS
  if (@Id is null)
    -- insert
    BEGIN
      INSERT INTO dbo.Synonyms (SynonymText, CircleId, IsActive, Comment, Source, IsEthalon )
      VALUES (@Text, @CircleId, 1, @Comment, @Source, @IsEthalon)
      
      SELECT @Id = SCOPE_IDENTITY()
    END
    
    -- update
    BEGIN
      UPDATE dbo.Synonyms
      SET
        SynonymText = @Text,
        CircleId = @CircleId,
        IsActive = 1,
        Comment = @Comment,
        Source = @Source,
        IsEthalon = @IsEthalon
      WHERE SynonymId = @Id
    END

GO




Клиентский код, с правильными типами, который вызывает ошибку:
(в описании initAdapter закомментированы две строки, которые упрощают тип данных и позволяют избавиться от ошибки)

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
protected void initAdapter()
        {
            Connection = new SqlConnection(SynonymsVS.Common.Utilities.ConnectionString);
            cmdSynonymsSelect = new SqlCommand("select * from dbo.Synonyms Where IsActive = 1 and CircleId = @CircleId and IsEthalon = @IsEthalon", Connection);
            cmdSynonymsSelect.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CircleId", System.Data.SqlDbType.Decimal, 18));
            cmdSynonymsSelect.Parameters.Add(new System.Data.SqlClient.SqlParameter("@IsEthalon", System.Data.SqlDbType.Bit));

            cmdSynonymsPut = new SqlCommand("dbo.Synonym_Put", Connection);
            cmdSynonymsPut.CommandType = CommandType.StoredProcedure;
            cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Id", System.Data.SqlDbType.Decimal, 18, ParameterDirection.InputOutput, true,0,0, "SynonymId", DataRowVersion.Default,null));
            cmdSynonymsPut.Parameters["@Id"].Direction = ParameterDirection.InputOutput;
            /*cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Id", System.Data.SqlDbType.Int, 0, "SynonymId"));
            cmdSynonymsPut.Parameters["@Id"].Direction = ParameterDirection.InputOutput;*/
            cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Text", System.Data.SqlDbType.VarChar, 255, "SynonymText"));
            cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CircleId", System.Data.SqlDbType.Decimal, 18, "CircleId"));
            cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Comment", System.Data.SqlDbType.VarChar, 100, "Comment"));
            cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Source", System.Data.SqlDbType.VarChar, 100, "Source"));
            cmdSynonymsPut.Parameters.Add(new System.Data.SqlClient.SqlParameter("@IsEthalon", System.Data.SqlDbType.Bit, 1, "IsEthalon"));

            cmdSynonymsDel = new SqlCommand("dbo.Synonym_Del", Connection);
            cmdSynonymsDel.CommandType = CommandType.StoredProcedure;
            cmdSynonymsDel.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Id", System.Data.SqlDbType.Decimal, 18, "SynonymId"));

            daSynonyms = new SqlDataAdapter();
            daSynonyms.SelectCommand = cmdSynonymsSelect;
            daSynonyms.InsertCommand = cmdSynonymsPut;
            daSynonyms.UpdateCommand = cmdSynonymsPut;
            daSynonyms.DeleteCommand = cmdSynonymsDel;
        }

private void updateRow(DataRow rw)
        {
            try
            {
                SqlCommand cmd = cmdSynonymsPut;
                if (Connection.State != ConnectionState.Open)
                {
                    Connection.Open();
                }

                cmd.Parameters["@Id"].Value = rw["SynonymId"];
                cmd.Parameters["@Text"].Value = rw["SynonymText"];
                cmd.Parameters["@CircleId"].Value = rw["CircleId"];
                cmd.Parameters["@Comment"].Value = rw["Comment"];
                cmd.Parameters["@Source"].Value = rw["Source"];
                cmd.Parameters["@IsEthalon"].Value = rw["IsEthalon"];

                cmd.ExecuteNonQuery();

                // out parameter
                rw["SynonymId"] = cmd.Parameters["@Id"].Value;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка при сохранении синонимов: "+ ex.Message, "Ошибка");
            }
            finally
            {
                if (Connection.State == ConnectionState.Open)
                {
                    Connection.Close();
                }
            }
        }

/// <summary>
        /// Applies changes.
        /// </summary>
        public void ApplyChanges()
        {
            try
            {
                foreach (DataRow rw in this.Table.Rows)
                {
                    switch (rw.RowState)
                    {
                        case DataRowState.Added:
                        case DataRowState.Modified:
                            updateRow(rw);
                            break;
                        case DataRowState.Deleted:
                            deleteRow(rw);
                            break;
                    }
                }

                Refresh();

                //daSynonyms.Update(this.Table);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка при сохранении изменений в синонимах, данные:" + ex.Message);
            }
        }




Собственно вопрос - что я делаю неправильно?
Как сохранить numeric(18,0) со стороны клиента и избежать ошибки?
Привел в примере конкретную запись, которая будет приводить к ошибке (ID=65)
...
Рейтинг: 0 / 0
27.05.2015, 12:35
    #38969659
carrotik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
Евгений В,

... а почему именно numeric, а не bigint, например, для поля identity? ...
...
Рейтинг: 0 / 0
27.05.2015, 13:11
    #38969717
Евгений В
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
carrotik,
Это не совсем по сути вопроса. Так исторически сложилось. Можно все переписать, таки да. Однако ошибка почему, хотелось бы узнать.
...
Рейтинг: 0 / 0
01.06.2015, 10:02
    #38972968
Евгений В
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
Проблема все еще актуальна, никто не знает причину и решение?
...
Рейтинг: 0 / 0
01.06.2015, 10:52
    #38973040
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
Евгений В, http://stackoverflow.com/a/33773
Потом смотрите различия...
...
Рейтинг: 0 / 0
01.06.2015, 18:39
    #38973704
Евгений В
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
buser,
Вы можете подробнее пояснить что Вы предлагаете сравнить?
Я прекрасно знаю какие типы в параметрах, это видно в примере.
Еще раз - проблема в том, что когда я использую рекомендованные типы, т.е. какбе совпадающие с обеих сторон, то это не работает.
Поскольку для MS не впервой рекомендовать неработающие решения - я уточняю у сообщества - где же порылась собака? У меня руки кривые, или очередной баг MS с известными путями обхода?
...
Рейтинг: 0 / 0
01.06.2015, 18:45
    #38973712
Евгений В
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
Евгений В,
Да, небольшой нюанс, еще раз повторю. Рекомендованное решение иногда работает, иногда не работает. Зависит от конкретного значения, которое мы пытаемся использовать в связке Numeric-Decimal. Вопрос в том - что нужно сделать, чтобы всегда работало :-)
...
Рейтинг: 0 / 0
01.06.2015, 19:39
    #38973751
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ошибка при сохранении данных, значение параметра вне допустимого диапазона.
Евгений ВВопрос в том - что нужно сделать, чтобы всегда работало :-)

Запихивать Int64, а не decimal в параметры.
Не пробовал, просто не доводилось иметь дела с numeric-identity ))
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Ошибка при сохранении данных, значение параметра вне допустимого диапазона. / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]