Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Как сохранить новую запись в безе данных Access Добавлено: 06.12.07 16:03  

Автор вопроса:  PVV
Пожалуйста помогите обновить источник данных. Как считывать и пользовать данные из базы данных Access немного понял, но как их туда записать – никак не получается. Сделал вроде все как в MSDN описано, но на строке
 WDA.Update(tbl)
Вылетает исключение " Несоответствие типов данных в выражении условия отбора".
Где это? В выражении "INSERT…" никаких условий отбора нет. Не знаю, куда даже смотреть, подскажите.

MissionDB – экземпляр класса AccessDB
MissionDB.DS - Dataset

Public Class frmMission
... ...
Private Sub XYZ()
... ...

 Dim dr As DataRow
        Dim dt As DataTable = MissionDB.DS.Tables("tblPoruch")
        'Заполнить новую запись значениями контролов формы
        dr = dt.NewRow
        'dr(0) не заполняется, в источнике данных это поле со счетчиком (ключ)
        dr(1) = plData.Value ' As DateTimePicker
        dr(2) = plSrok.Value ' As DateTimePicker
        dr(3) = plMission.Text ' As TextBox
        dr(4) = flGotov.Checked ' As CheckBox
        dr(5) = plPrim.Text ' As TextBox
        dt.Rows.Add(dr)

        Dim insertSQL As String = "INSERT INTO tblPoruch " & _
         "(DataPor, SrockDo, Poruch, Sdelano, Prim) VALUES (?,?,?,?,?)"
        Dim params(dt.Columns.Count) As OleDbParameter
        Dim cl As Integer
        For cl = 1 To dt.Columns.Count - 1
            params(cl - 1) = New OleDbParameter(dt.Columns(cl).ColumnName, dr(dt.Columns(cl)))
        Next
        MissionDB.AddNewDB(dt, insertSQL, params)
    End Sub
 End Class


       
    Public Class AccessDB
        Private Connect As OleDbConnection

... ...

 Public Sub AddNewDB(ByVal tbl As DataTable, ByVal insertSQL As String, _
        ByVal Params() As OleDbParameter)
            Dim WDA As OleDbDataAdapter = New OleDbDataAdapter

            Dim insertCMD As OleDbCommand = New OleDbCommand(insertSQL, Connect)
            WDA.InsertCommand = insertCMD
            ' Add parameters and set values.
            Dim j As Integer
            For j = 0 To Params.GetUpperBound(0) - 2
                insertCMD.Parameters.Add(Params(j))
            Next j
            WDA.Update(tbl)
        End Sub

End Class

Ответить

  Ответы Всего ответов: 15  

Номер ответа: 1
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #1 Добавлено: 06.12.07 17:26
Я вообще то не очеь большо спец... Если ты юзашь Эксес, то тебе вряд ли нужна произодительность... В таком случае я бы сделал намного проще - без этого стандартного приема. Просто попробуй выполнить запросы по-проще

Ответить

Номер ответа: 2
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #2 Добавлено: 06.12.07 17:33
вот примерно процедура, которая делаэт всэ работу запросов

        public DataSet GetSQL(string SQL)
        {
            SQL = SQL.Replace(" ,", " NULL,";);
            SQL = SQL.Replace(" ,0", " ,1";);
            ;DataSet Ds = new DataSet();
            System.Data.SqlClient.SqlConnection dbConnection = new System.Data.SqlClient.SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["epsrDbConnection"];);
            System.Data.SqlClient.SqlDataAdapter dbCommand = new System.Data.SqlClient.SqlDataAdapter(SQL, dbConnection);
            dbCommand.Fill(Ds);
            return Ds;
        }

Ответить

Номер ответа: 3
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #3 Добавлено: 06.12.07 17:34

System.Configuration.ConfigurationSettings.AppSettings["epsrDbConnection"]

это строка подключения

Ответить

Номер ответа: 4
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #4 Добавлено: 06.12.07 17:36
Он по-идее выполняет запроса типа Селект, и при этом возвращает результаты, и запросы типа Инсерт, но при этом, соответственно, никакие значения не возвращаются

Ответить

Номер ответа: 5
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #5 Добавлено: 06.12.07 17:52
Другой проблемой может быть то, что ты неправильно передаешь значения. Вот например, в некоторые значения должны быть в кавычках ;-)

Ответить

Номер ответа: 6
Автор ответа:
 PVV



Вопросов: 8
Ответов: 21
 Профиль | | #6 Добавлено: 06.12.07 18:46
Спасибо, но по моему это C#, а у меня VB.NET. Вряд ли мне будет полезен пример на другом языке, о котором я вообще ничего не слышал, кроме названия.

Ответить

Номер ответа: 7
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #7 Добавлено: 06.12.07 18:48
Ок, здесь нет проблем. Просто я использую дотНетовские классы, так это легко переписать на ВБ.НЕТ

Ответить

Номер ответа: 8
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #8 Добавлено: 06.12.07 18:57

    Public Function GetSQL(ByVal SQL As String) As DataSet
        SQL = SQL.Replace(" ,", " NULL,";)
        SQL = SQL.Replace(" ,0", " ,1";)
        Dim Ds As New DataSet
        Dim dbConnection As New System.Data.SqlClient.SqlConnection("myConnectionString";)
        Dim dbCommand As New System.Data.SqlClient.SqlDataAdapter(SQL, dbConnection)
        dbCommand.Fill(Ds)
        Return Ds
    End Function

Ответить

Номер ответа: 9
Автор ответа:
 Сашок



ICQ: 387093431 

Вопросов: 1
Ответов: 70
 Профиль | | #9 Добавлено: 06.12.07 18:59
лучше юза этот код, т.к. я допустил ошибку :-(

    Public Function GetSQL(ByVal SQL As String) As DataSet
        Dim Ds As New DataSet
        Dim dbConnection As New System.Data.SqlClient.SqlConnection("myConnectionString";)
        Dim dbCommand As New System.Data.SqlClient.SqlDataAdapter(SQL.Replace(" ,", " NULL,";), dbConnection)
        dbCommand.Fill(Ds)
        Return Ds
    End Function

Ответить

Номер ответа: 10
Автор ответа:
 PVV



Вопросов: 8
Ответов: 21
 Профиль | | #10 Добавлено: 10.12.07 14:38
Сашок, спасибо за помощь. Правда не удалось мне поюзать твой код. Не смог найти в справке Replace, потом в твоем коде sql, а у меня oledb. Для такого чайника как я это оказалось достаточно большим затруднением. Но в итоге я все-таки сделал, что хотел с - помощью класса OleDbCommandBuilder.

Ответить

Номер ответа: 11
Автор ответа:
 PVV



Вопросов: 8
Ответов: 21
 Профиль | | #11 Добавлено: 10.12.07 14:44
Сашок, спасибо за помощь. Правда не удалось мне поюзать твой код. Не смог найти в справке Replace, потом в твоем коде sql, а у меня oledb. Для такого чайника как я это оказалось достаточно большим затруднением. Но в итоге я все-таки сделал, что хотел с - помощью класса OleDbCommandBuilder.

Ответить

Номер ответа: 12
Автор ответа:
 Fatty



Вопросов: 0
Ответов: 55
 Профиль | | #12 Добавлено: 12.12.07 00:23
Хотелось бы посмотреть решение :)


Ответить

Номер ответа: 13
Автор ответа:
 PVV



Вопросов: 8
Ответов: 21
 Профиль | | #13 Добавлено: 12.12.07 09:11
Решение у меня получилось такое. Правда есть некоторые проблемы. Создание новой записи и редактирование (удаление) существующей выполняется разными процедурами (функциями), хотя эти процедуры мало чем отличаются. В Public Function AddNewDBAuto введен вспомогательный объект Dim addDS As DataSet = New DataSet для того, чтобы возвратить значение ключа (счетчика) вновь созданной записи с помощью процедуры OnRowUpdated. При работе сразу с основным DataSet'ом почему-то значение нового ключа не выцепляется, а оно нужно для соответствующих изменений в подчиненной таблице (про подчиненную таблицу из кода все вырезано, чтобы не загромождать). Вторая проблема серьезнее и пока не могу понять в чем дело. Процедура WriteDBAuto нормально редактирует записи в обеих таблицах и создает новые в подчиненной таблице (там не нужно возвращать значение ключа), но с удалением записей какие-то непонятки.
В процедуре Private Sub knDel удаление записи из объекта dataset происходит, но из самой базы данных запись не удаляется и после вызова MissionDB.ReadDB все возвращается на круги своя, как будто и не удаляли ничего. И никаких ошибок, все как бы нормально. Сижу, пытаюсь вкурить, в чем дело.

Imports System.Data.OleDb

Public Class frmMission
... ...
    Private Sub knSave (ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles knSave.Click
... ...

         ;Dim nom, i, j As Integer
        ;Dim dr As DataRow
        ;Dim dt As DataTable = MissionDB.DS.Tables("tblPoruch";)
        If _Mode = modDB.Mode.mEdit Then
            dr = dt.Rows(l_ActivRec) 'взять текущую запись, если режим редактирования
        Else
            dr = dt.NewRow 'иначе (новая, из режима просмотра сюда попасть нельзя)
            ' создать новую запись
        End If
        'Заполнить запись значениями контролов формы
        'dr(0) не заполняется, в источнике данных это поле со счетчиком (ключ)
        dr(1) = plData.Value ' As DateTimePicker
        dr(2) = plSrok.Value ' As DateTimePicker
        dr(3) = plMission.Text ' As TextBox
        dr(4) = flGotov.Checked ' As CheckBox
        dr(5) = plPrim.Text ' As TextBox
        ;Dim selSQL As String = "SELECT * FROM tblPoruch"
        If _Mode = modDB.Mode.mEdit Then
            nom = dr(dt.Columns(0))
            MissionDB.WriteDBAuto(selSQL, dt)
        Else
            dt.Rows.Add(dr)
            nom = MissionDB.AddNewDBAuto(selSQL, dr, dt)
        End If

        MissionDB.ReadDB("SELECT * FROM tblPoruch", "tblPoruch";)

...

    End Sub


    Private Sub knDel (ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles knDel.Click

...

                ;Dim dtP As DataTable = MissionDB.DS.Tables("tblPoruch";)
                ;Dim dr As DataRow
                dr = dtP.Rows(l_ActivRec) 'активная запись в tblPoruch
                selSQL = "SELECT * FROM tblPoruch"
                dr.Delete() 'удалить активную запись в tblPoruch
                dtP.AcceptChanges()
                MissionDB.WriteDBAuto(selSQL, dtP)
                MissionDB.ReadDB("SELECT * FROM tblPoruch", "tblPoruch";)
...
    End Sub

End Class


        
Module modDB
    Public MissionDB As AccessDB

    Public Enum Mode As Integer
        'режимы формы frmMission - просмотр, редактирование и новая запись
        mView = 1
        mEdit = 2
        mNew = 3
    End Enum

    Public Class AccessDB
        Private myDS As DataSet
        Private sPatch As String = ""
        Private Connect As OleDbConnection

... ...

        Public Function AddNewDBAuto(ByVal selSQL As String, ByVal dtRow As DataRow, _
        ByVal dtbl As DataTable) As Integer
            ;Dim tblName As String = dtbl.TableName
            ;Dim WNDA As OleDbDataAdapter = New OleDbDataAdapter(selSQL, Connect)
            ;Dim CB As OleDbCommandBuilder = New OleDbCommandBuilder(WNDA)
            CB.QuotePrefix = "["
            CB.QuoteSuffix = "]"
            ;Dim addDS As DataSet = New DataSet
            If Connect.State = ConnectionState.Closed Then Connect.Open()
            WNDA.Fill(addDS, tblName)
            ;Dim dt As DataTable = addDS.Tables(tblName)
            ;Dim dr As DataRow
            dr = dt.NewRow
            ;Dim c As Integer
            For c = 1 To dt.Columns.Count - 1
                dr(dt.Columns(c)) = dtRow(dtbl.Columns(c))
            Next
            dt.Rows.Add(dr)
            AddHandler WNDA.RowUpdated, New _
            OleDbRowUpdatedEventHandler(AddressOf OnRowUpdated)
            WNDA.Update(addDS, tblName)
            Connect.Close()
            Return dr(dt.Columns(0))
        End Function


        Public Sub WriteDBAuto(ByVal selSQL As String, ByVal dtbl As DataTable)
            ;Dim tblName As String = dtbl.TableName
            ;Dim WNDA As OleDbDataAdapter = New OleDbDataAdapter(selSQL, Connect)
            ;Dim CB As OleDbCommandBuilder = New OleDbCommandBuilder(WNDA)
            CB.QuotePrefix = "["
            CB.QuoteSuffix = "]"
            If Connect.State = ConnectionState.Closed Then Connect.Open()
            WNDA.Update(DS, tblName)
            Connect.Close()
        End Sub


        Private Sub OnRowUpdated(ByVal sender As Object, _
        ByVal args As OleDbRowUpdatedEventArgs)
            ' Include a variable and a command to retrieve the identity value
            ' from the Access database.
            ;Dim newID As Integer = 0
            ;Dim idCMD As OleDbCommand = New _
            OleDbCommand("SELECT @@IDENTITY", Connect)

            If args.StatementType = StatementType.Insert Then
                ' Retrieve the identity value and store it in the CategoryID column.
                newID = CInt(idCMD.ExecuteScalar())
                args.Row(0) = newID
            End If
        End Sub

        Public Function ReadDB(ByVal cmdString As String, _
ByVal tblName As String) As Integer
            ;Dim da As System.Data.OleDb.OleDbDataAdapter
            ;Dim cmd As New OleDb.OleDbCommand(cmdString)
            cmd.Connection = Connect
            da = New System.Data.OleDb.OleDbDataAdapter

            da.SelectCommand = cmd
            If Not Connect.State = ConnectionState.Open Then _
                Connect.Open()
            Try
                ;DS.Tables(tblName).Clear()
                Return da.Fill(DS, tblName)
                Connect.Close()
            Catch ex As ArgumentNullException
                Return 0
            End Try
        End Function

    End Class

Ответить

Номер ответа: 14
Автор ответа:
 Fatty



Вопросов: 0
Ответов: 55
 Профиль | | #14 Добавлено: 12.12.07 13:08
У меня удаляется так:

    Private Sub btnDelRow_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelRow.Click
        SelectedRowDelete()
    End Sub
    Private Sub SelectedRowDelete()
        Dim conn As OleDbConnection = New OleDbConnection("Provider=Microsoft.JET.OLEDB.4.0;data source=C:\Northwind.mdb";)
        conn.Open()
        Dim custDataSet As DataSet = New DataSet()
        Dim custDataAdapter As OleDbDataAdapter = New OleDbDataAdapter(New OleDbCommand("SELECT * FROM Customers", conn))
        Dim custCmdBuilder As OleDbCommandBuilder = New _
        OleDbCommandBuilder(custDataAdapter)
        custDataAdapter.Fill(custDataSet, "Customers";)
        Dim custTable As DataTable = custDataSet.Tables(0)
        Dim dlgResp As DialogResult = MessageBox.Show("Удалить эту запись ? ", "Подтверждение", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
        If dlgResp = Windows.Forms.DialogResult.Yes Then

            Dim i As Integer = DataGridView1.CurrentCell.RowIndex
            custTable.Rows(i).Delete()
            custDataAdapter.Update(custTable)
            custTable.AcceptChanges()

        End If
    End Sub


Я использую DataGridView на форме

Ответить

Номер ответа: 15
Автор ответа:
 PVV



Вопросов: 8
Ответов: 21
 Профиль | | #15 Добавлено: 12.12.07 14:42
У меня тоже все заработало. Я убрал AcceptChanges, а в процедуру WriteDBAuto добавил предварительно Fill вспомогательного Dataseta. В справке написано, что при автоматическом формировании команд необходима предварительная обработка commandselect. В итоге получилось практически так же, как и у тебя. Кстати, в справке опять же прочитал, что по умолчанию выполнение метода Update завершается вызовом AcceptChanges автоматически.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам