none
Внести изменения в dbf RRS feed

  • Вопрос

  • Здравствуйте.
    Нужно внести изменения в таблицу.

     

    OleDbConnection conn = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=.\\tb.dbf;");
     conn.Open();
     OleDbCommand cmd = conn.CreateCommand();
     cmd.CommandText = "SELECT * FROM .\\tb.dbf";
     OleDbDataAdapter adp = new OleDbDataAdapter(cmd);
     OleDbCommandBuilder cb = new OleDbCommandBuilder();
     cb.DataAdapter = adp;
     DataSet ds = new DataSet("test");
     adp.Fill(ds);
     ds.Tables[0].Rows[1][1] = "test";
     adp.Update(ds);
    

     

    При запуске выдает ошибку: "Динамическое создание SQL не поддерживается для SelectCommand, не возвращающего никакой информации о базовой таблице.";



    13 августа 2011 г. 13:36

Ответы

  • > Вносить изменения данным методом просто в dbf таблицы нельзя?

    этот способ требует наличие primary key в таблице. его можно определить только для .dbc; для .dbf получим exception: "Feature is not supported for non-.DBC tables."
    к тому же все данные из dbf загружаются в dataset .... эффективней выполнять прямое обновление. для этого надо создать команду с текстом, например, "UPDATE table_name SET field_name='field_value' WHERE id=1" и вызвать ExecuteNonQuery.

    • Помечено в качестве ответа mrzlodey 15 августа 2011 г. 16:05
    14 августа 2011 г. 20:21

Все ответы

  • на какой строке возникает ошибка? датасет заполняется? если нет, то:
    cmd.CommandText = "select count(*) from tb";
    var res = cmd.ExecuteScalar();  // что возвращает?

    13 августа 2011 г. 16:09
  • Датасет заполняется. Ошибка возникает на  adp.Update(ds);

    Проблема как я понимаю была в бд. Чтобы код работал, как я понял, у таблицы должен быть primary индекс. Чтобы его создать нужно поместить dbf таблицу в файл базы данных dbc foxpro. Создал в foxpro новую бд data1.dbc добавил туда существующую таблицу, создал primary индекс. Заработало.

     

    OleDbConnection conn = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=.\\data1.dbc;");
    conn.Open();
    OleDbCommand cmd = conn.CreateCommand();
    cmd.CommandText = "SELECT * FROM tb.dbf";
    OleDbDataAdapter adp = new OleDbDataAdapter(cmd);
    OleDbCommandBuilder cb = new OleDbCommandBuilder();
    cb.DataAdapter = adp;
    DataSet ds = new DataSet("test");
    adp.Fill(ds);
    ds.Tables[0].Rows[1][1] = "test";
    adp.Update(ds);
    
    

    Вносить изменения данным методом просто в dbf таблицы нельзя?

     




    14 августа 2011 г. 13:06
  • Check ALTER TABLE command  ADD PRIMARY KEY ...

    It doesn't tell, that we need DBC to create primary key, so I assume you can create primary key for free tables as well.

     

    ADD PRIMARY KEY eExpression3[FOR lExpression4] TAG TagName2

    Adds a primary index to the table. The eExpression3 specifies the primary index key expression.

    You can use lExpression4 to specify a filter expression where only records that satisfy the condition are available for display and access. Primary index keys are created in the index file just for those records that match the filter expression. You should avoid using the FOR clause to create a primary index; the uniqueness of a primary key is enforced only for those records that match the condition specified in the FOR clause. Instead, use the INDEX command with a FOR clause to create a filtered index.

    Rushmore Query Optimization optimizes an ALTER TABLE ... FOR lExpression4 command if the lExpression4 expression can be optimized. For the best performance, use an optimizable expression in the FOR clause. For more information, see SET OPTIMIZE Command and Using Rushmore Query Optimization to Speed Data Access.

    The TagName2 parameter specifies the name of the primary index tag. Index tag names can contain up to 10 characters. If you omit TAG TagName2, and eExpression3 is a single field, the primary index tag has the same name as the field specified in eExpression3.

    I've tested and found that you can not add a Primary Key for free tables. I think Help file could have stated this explicitly.


    For every expert, there is an equal and opposite expert. - Becker's Law


    My blog


    14 августа 2011 г. 18:04
  • > Вносить изменения данным методом просто в dbf таблицы нельзя?

    этот способ требует наличие primary key в таблице. его можно определить только для .dbc; для .dbf получим exception: "Feature is not supported for non-.DBC tables."
    к тому же все данные из dbf загружаются в dataset .... эффективней выполнять прямое обновление. для этого надо создать команду с текстом, например, "UPDATE table_name SET field_name='field_value' WHERE id=1" и вызвать ExecuteNonQuery.

    • Помечено в качестве ответа mrzlodey 15 августа 2011 г. 16:05
    14 августа 2011 г. 20:21
  • эффективней выполнять прямое обновление. для этого надо создать команду с текстом, например, "UPDATE table_name SET field_name='field_value' WHERE id=1" и вызвать ExecuteNonQuery.


    А если мне все равно необходимо вывести данные в datagridview, как будет более эффективней выполнить sql запрос update или изменять значения в dataset?

    Я исхожу из того, что после выполнения sql запроса мне прийдется снова выполнить запрос select после чего загрузить данные из таблицы в  dataset, чего не прийдется делать если пойти путем изменения dataset. Я правильно рассуждаю? Проблема в том, хотя таблица маленьгая <1 мб datagridview не заполняется мгновенно, все происходит быстро, но видно как заполняются строки.







    15 августа 2011 г. 16:05
  • > datagridview не заполняется мгновенно, все происходит быстро, но видно как заполняются строки

    у datagridview есть виртуальный режим. свойство VirtualMode=true
    также надо подключить обработчик к событию CellValueNeeded, через который гриду надо отдавать значения ячеек.
    грид запрашивает значения только видимых ячеек. т.е. загружать данные из базы можно частями.
    пример: http://www.gotdotnet.ru/forums/3/117572/554678/#post554678

    > если мне все равно необходимо вывести данные в datagridview, как будет более эффективней выполнить sql запрос update или изменять значения в dataset?

    данные вводятся через форму. после нажатия "сохранить" они должны отобразиться в datagridview и сохраниться в базе данных?

     

     

    15 августа 2011 г. 19:00
  • данные вводятся через форму. после нажатия "сохранить" они должны отобразиться в datagridview и сохраниться в базе данных?


    Да, необходимо и изменение базы и необходимо отображение изменений в  datagridview. 

    Подробней. Данные вносятся в дочернюю форму, на которой имется кнопка "сохранить" (adp.Update(ds);), после нажатия кнопки дочерняя форма закрывается, а в основной форме обновляется datagridview.


    16 августа 2011 г. 10:21
  • > Данные вносятся в дочернюю форму

    передавать/обновлять данные можно с помощью bindingcontext, общего для двух форм
    пример: http://www.gotdotnet.ru/forums/1/98031/466095/#post466095

    если код из первого сообщения не работает, то можно перехватывать изменение значений полей в DataTable (см. ColumnChanged и TableNewRow) и отправлять изменения в базу данных.
    или в момент закрытия дочерней формы брать данные методом DataSet.GetChanges и на их основе обновлять базу данных.

    16 августа 2011 г. 15:18