VB.NET / Access DB - Column created at runtime is not Updating - database

Thanks everyone for thumbing down my question and not helping me out. This website is amazing.
My program creates columns at runtime with the following code:
Cmd = New OleDb.OleDbCommand("ALTER TABLE [Parent] ADD [" & ColumnDate & "] int", con)
objCmd = New OleDb.OleDbCommand("ALTER TABLE [Parent] ADD [" & ColumnDate & "] int", con)
objCmd.ExecuteNonQuery()
I add data into the newly inserted column with the following code:
da.SelectCommand = New OleDb.OleDbCommand(sql, con)
Dim cb As New OleDb.OleDbCommandBuilder(da)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
ds.Tables("SchoolMaticsDatabase").Rows(inc).Item(ColumnDate) = Hours * Num
da.Update(ds, "SchoolMaticsDatabase")
All of the above works fine; the issue arises when I try to edit the information originally placed in the newly added column. These are the approaches that I have taken. (None of them give an error message; it simply won't update within the database.)
Approach 1:
da.SelectCommand = New OleDb.OleDbCommand(sql, con)
Dim cb As New OleDb.OleDbCommandBuilder(da)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
For Each column As DataColumn In ds.Tables("SchoolMaticsDatabase").Columns
If IsDate(column.ColumnName) = True Then
ds.Tables("SchoolMaticsDatabase").Rows(inc).Item(column.ColumnName) = DataGridView3.Item(column.ColumnName, 0).Value
End If
Next
da.Update(ds, "SchoolMaticsDatabase")
Approach 2:
da.SelectCommand = New OleDb.OleDbCommand(sql, con)
Dim cb As New OleDb.OleDbCommandBuilder(da)
cb.QuotePrefix = "["
cb.QuoteSuffix = "]"
For count = 13 To MaxColumns - 1
ds.Tables("SchoolMaticsDatabase").Rows(inc).Item(count) = DataGridView3.Item(count, 0).Value
Next
da.Update(ds, "SchoolMaticsDatabase")
Approach 3:
For Each column As DataColumn In ds.Tables("SchoolMaticsDatabase").Columns
If IsDate(column.ColumnName) Then
Cmd = New OleDb.OleDbCommand("UPDATE [Parent] SET [" & column.ColumnName & "]=" & DataGridView3.Item(column.ColumnName, 0).Value & " WHERE [ID]=" & inc + 1, con)
objCmd = New OleDb.OleDbCommand("UPDATE [Parent] SET [" & column.ColumnName & "]=" & DataGridView3.Item(column.ColumnName, 0).Value & " WHERE [ID]=" & inc + 1, con)
objCmd.ExecuteNonQuery()
End If
Next
I added a column to the table manually via opening the access database and all the above approaches work for editing data stored in that column. So I believe it is something to do with the fact that the columns are created at run time.

I suspect that your DataSet (ds) is out of sync.
First, confirm that the new column is present within the DataSet: For any one of your three approaches, put a break-point just before the loop starts, and take a look at ds.Tables("SchoolMaticsDatabase").Columns and confirm that the new column is in fact listed there. Alternatively, put a Debug.Print column.ColumnName inside the loop and look for it in the Output window.
Second, assuming that the new column is in the Columns member, I would recommend making a little project on the side to explore your issue further. Make it simple, nothing fancy. Let it create a column (avoid using dates as names at first), give it a value, update its value, see how it goes.
Good luck!

Related

Crystal Report showing only first record in DetailReport Section VB.NET & SQL Server

There are two tables in my database, SalesInvoiceDetails and SalesInvoicesInventoryRowDetails.
I have 6 x records in my table SalesInvoicesInventoryRowDetails from which Crystal Reports is showing only one (first record).
I checked by putting breakpoints. Dataset is filled with all data but its not appearing in Crystal Report except first record (only one line).
Please need kind help to solve the issue.
Thanks.
Dim row As DataRow = GridView1.GetDataRow(GridView1.FocusedRowHandle)
Me.Cursor = Cursors.WaitCursor
Dim objRpt As New XtraReport1
Dim ds As New SalesInvoiceDataSet
Dim adp1 As New SqlClient.SqlDataAdapter("Select * From SalesInvoiceDetails Where InvoiceNo=N'" & row("InvoiceNo") & "'", DAL.OpenSqlConnection)
adp1.Fill(ds, "SalesInvoiceDetails")
Dim adp2 As New SqlClient.SqlDataAdapter("Select * From SalesInvoicesInventoryRowDetails Where InvoiceNo=N'" & row("InvoiceNo") & "' order by Sno", DAL.OpenSqlConnection)
adp2.Fill(ds, "SalesInvoicesInventoryRowDetails")
DAL.CloseConnection()
objRpt.DataSource = ds
Dim s As New SalesInvoicePrintForm
s.DocumentViewer1.DocumentSource = objRpt
s.Show()

Pull value from SQL Server in VB.NET

I am attempting to pull values from an SQL Server table from VB.NET.
On VB Form 1, the number from NoTable, Row 1, is pulled successfully, and Label1 is updated with the value.
Dim command As SqlCommand
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
If datareader.Read() Then
Label1.Text = datareader.GetValue(0)
End If
datareader.Close()
On VB Form 2 I am attempting to pull the value from the second row, using:
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
If datareader.Read() Then
Label1.Text = datareader.GetValue(1)
End If
datareader.Close()
However, this does not work, and the label is not updated with the value from the second row.
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll
Additional information: Index was outside the bounds of the array."
How would I go about fixing this, so that on Form 2, the value from Row 2 is pulled, and so forth?
Thank you.
Firstly, you only get one column back from the reader, but you are indexing the columns with that 0 or 1. So you should always pass 0 to GetValue.
To index the row instead, try this. Assign a form number to each form (first line in my example) and use that to determine which record to assign to the Label. There is probably a more efficient way to do this (not returning all the records before it) but this solution should fit in your environment.
' in form # 1
Dim formNumber = 1
Dim command As SqlCommand
Dim query As String = "SELECT Number FROM NoTable"
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
Dim index = 0
While index < formNumber
If datareader.Read() AndAlso index = formNumber Then
Label1.Text = datareader.GetValue(0)
End If
index += 1
End While
datareader.Close()
See https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.getvalue(v=vs.110).aspx
And another similar question in c# Access a specific row in DataReader
Another way is to just return the row you need in the first place, without iterating over the records on the client side. Assuming there is another column with an index which is in the same order as the row you want to return, called "ID"
' in form # 1
Dim formNumber = 1
Dim command As SqlCommand
Dim query As String =
"SELECT Number FROM " & _
" (SELECT Number, Row_Number() OVER (ORDER BY ID) AS RowNumber " & _
" FROM NoTable) AS Results " & _
" WHERE Results.RowNumber = " & formNumber.ToString()
command = New SqlCommand(query, con)
con.Open()
Dim datareader As SqlDataReader = cmd.ExecuteReader()
Label1.Text = datareader.GetValue(0)
datareader.Close()
See https://msdn.microsoft.com/en-us/library/ms186734.aspx
GetValue(1) does not exist, as this would refer to a second column in the select statement. You are only asking for [Number] which would be datareader.GetValue(0)

Reload a Datagrid View returns Nothing

I have the a Function that loads data into from a Microsoft Access DB into a DGV as shown in code below:
Public Sub LoaddgvCombined()
Try
'//Clear DataGrid
ds.Clear()
dgvSales.DataSource = Nothing
'dgvSales.Refresh()
dgvSales.DataSource = ds
'//Establish Connection to DB
con.ConnectionString = dbProvider & dbSource
tables = ds.Tables
con.Open()
sql = "SELECT * FROM [tblINV_SalesRecord] WHERE CDate(adddate & ' ' &addtime) < CDate('" & selectfrm & "')) ORDER BY temID ASC"
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "tblINV_SalesRecord")
con.Close()
Dim view As New DataView(tables(0))
source1.DataSource = view
dgvSales.DataSource = view
dgvSales.AllowUserToAddRows = False
If dgvSales.RowCount < 1 Then
MessageBox.Show("No Sales Recorded Found From " & selectfrm)
End If
Catch ex As Exception
MessageBox.Show(ex.Message & " - " & ex.Source)
MessageBox.Show("An Error Occured While Loading Sales Record ")
End Try
End Sub
It works fine the first time, but when I call the function the second time it empties the DGV but this time it does not load any Data.
Please can anyone point out what I am doing wrong.
The thing I noticed here is that you are passing to tables BEFORE you are getting the result of your query.
Try passing the values for tables after you fill ds.
Like this:
da = New OleDb.OleDbDataAdapter(sql, con)
da.Fill(ds, "tblINV_SalesRecord")
con.Close()
tables = ds.Tables '<=== transfer it here
It's showing empty because at the point you are passing to tables, your ds variable is not yet filled from your query.

How to return database fields from checkbox selection?

the code below returns the fields of a given table ("Employee"), but I need to return the fields of ALL the tables in the given database, is this possible? My assumption is a For loop which loops round the tables in the database and prints the corresponding fields but my efforts seem to be in vain
Public Sub getDbFields()
Dim i As Integer
Dim dbcon As New System.Data.OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source = " & dblocation & _
"\" & dbname)
Try
dbcon.Open()
dbDt = dbcon.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Columns, New Object() _
{Nothing, Nothing, "Employee", Nothing})
For i = 0 To dbDt.Rows.Count - 1
'compile lbtables with a list of available tables from the database
newLine()
frmMain.lstTables.Items.Add(dbDt.Rows(i)!COLUMN_NAME.ToString())
Next
Catch ex As Exception
MessageBox.Show(ex.Message.ToString(), "Data Load Error", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
End Try
End Sub
This routine will be fired from the selection of a checkbox
This will return all columns on a database
Using con = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + dblocation + "\" + dbname)
con.Open()
Dim schema as DataTable = con.GetSchema("COLUMNS")
Dim dr as DataRow
For Each dr in schema.Rows
Dim tablename as string = dr("TABLE_NAME").ToString()
if Not tablename.StartsWith("MSys") then
Console.WriteLine(dr("TABLE_NAME").ToString() + " " + dr("COLUMN_NAME").ToString())
End if
Next
End Using
Please note that the bang (!) syntax is not allowed in vb.net.
Also your code could work if you change
dbDt = dbcon.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Columns, New Object() _
{Nothing, Nothing, Nothing, Nothing})
and this line
frmMain.lstTables.Items.Add(dbDt.Rows(i)("COLUMN_NAME").ToString())

insert and display image in vb.net from sql server database

i need to upload and display images to and from database. i have written this code for uploading and it uploads fine. except 1 problem. It crashes when i dont select an image. can someone help me fix it for null value? also how do you display an image in IE?
code for inserting image -
Dim imageInfo As FileInfo = Nothing
Dim data() As Byte = Nothing
imageInfo = New FileInfo(Me.UploadLogo.Value.Trim())
Dim imagestream As FileStream = New FileStream(imageInfo.ToString, FileMode.Open)
if name_id > 0
ReDim data(imagestream.Length - 1)
imagestream.Read(data, 0, imagestream.Length)
imagestream.Close()
Sqlstr = "UPDATE logos WITH(ROWLOCK) " & _
"SET Logo=#Logo,Modified_Date=GETDATE() " & _
"WHERE ID = " + name_id.ToString + ""
Else
Sqlstr = "INSERT logos (Logo,Created_Date) " & _
"VALUES ("#Logo,GETDATE())"
End If
SqlCmd = New SqlCommand(Sqlstr, SqlCnn)
Dim pictureParameter As SqlParameter = Nothing
pictureParameter = New SqlParameter("#Logo", SqlDbType.Image)
pictureParameter.Value = data
SqlCmd.Parameters.Add(pictureParameter)
SqlCmd.ExecuteScalar()
this works fine only if an image is selected, crashes for NULL values.
Also please help me with image display. thanks
To solve your "file not selected problem", you should have an If statement along the lines of:
If Not File.Exists(Me.UploadLogo.Value.Trim())
' Exit out or handle no file selected
End If

Resources