Pulling data from an access tabel and inserting it in another tabel - database

Im having some trouble with the design of my database. In microsoft Access I have two tables. One named table1 this table contains three fields (Name, Surname and Birthdate). The other table, named table2 contains two fields (Name and Surname). I want the following to happen. If I make a new record in table1 using a form the Name and Surname get passed/inserted to table2 automaticly. What is the best way of doing this? I was messing around with the primary key but that doenst seem to work. And since I'm a beginner I dont know where to go from here.
Thanks in advance for your time and efford!

Just figured out the awnser to my question! I used the following code
Private Sub addNew_Click()
Dim db As Object
Dim rst As Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("select * from Person", dbOpenDynaset)
rst.AddNew
rst!PeopleSoftNr = tbPeopleSoftNr.Value
rst!Name = tbName.Value
rst!Birthday = tbBirthday.Value
rst.Update
Set rst2 = db.OpenRecordset("select * from Dental", dbOpenDynaset)
rst2.AddNew
rst2!PeopleSoftNr = tbPeopleSoftNr.Value
rst2!Dental = tbDental.Value
rst2.Update
End Sub
This allows me to write data to multiple tables.

In my opinion the best way to do, what you described, is creating a form for the personal data and include a subform to assign courses of the persons.
Detail information about the courses should be edited in an own form for the courses.

Related

Access Caption property alternative for SQL Server

I have searched for an answer to this question everywhere. There is one forum asking the same question but the solution given does not work. Alias and Caption is not the same thing. In MS Access you can set alias with SQL using:
([Field1]+[Field2]) as expr1
However, in query design view you can change the caption property of expr1 to something like salary. This will change the field name in datasheet view but does not change the alias, which means fields in reports or forms depending on this query does not have to be modified from expr1 to salary. The salary column will only appear in the datasheet view of the query.
I cannot find a way to do the same in SQL Server. Is there a way to achieve this?
You can add Caption property to linked table(linked view) in Access's TableDef
If there is no caption yet
Dim p As Property
Dim tbl As TableDef
Dim fld As Field
Dim Db As Database
Set Db = CurrentDb
Set tbl = Db.TableDefs("LINKED TABLE NAME")
Set fld = tbl.fields("FIELD NAME")
Set p = fld.CreateProperty("Caption", dbText, "CAPTION FOR FIELD")
fld.Properties.Append p
fld.Properties.Refresh
If there is caption and you want to change it
CurrentDb.TableDefs("LINKED TABLE NAME").fields("FIELD NAME").Properties("Caption").Value = "CAPTION FOR FIELD"
Or by GIU way: open linked table in design mode, go to field definition, print disired caption to Caption property, press save button

Where is Access form data populating data from

I am currently trying to help a friend out with their invoicing Access database. I have rarely ever used Access and I am having problems figuring out the location of where the form (frmEntry) is pulling its data from. I did not create this setup so I am unsure of how it works. I am trying to figure out where the address information is being pulled from for when a customer is selected in a drop down on a form. I checked the query and it is only pulling the CustomerID and CustomerName, no address. The table does have address fields but none of the customers in the table have any listed, yet there address is populated along with their name in the form.
I do see where there is another form (frmCustomer) that has customer and there addresses but I am not sure if the other form is pulling from here, and if so, why can I not find the addresses in any of the tables or datasheet views?
Any direction would be very much appreciated. My end goal is to obtain the customer information (address etc) so that I can insert it into a new database that I am working on
Your data contains linebreaks and a combobox only shows one line per record.
To show the data you can replace the linebreaks in rowsource.
SELECT Replace([CustomerName],vbCrLf, " ") as CName FROM table
' vbCrLf is the VBA constant for linebreaks (Cr - Carrige Return, Lf - LineFeed)
This is poor database normalization (imagine you want to search for a customer name that is equal to a city, e.g. Paris). Each line should be a separate field in table (and Postcode too). If there is a linefeed for every data (e.g. no street -> empty line), you can just split the data into the new fields.
'Put this code in a module
'Split function
Public function splitCustomerName(ByVal strCustomerName as String, ByVal index as long) as String
Dim arrCustomerName As Variant ' or declare a fixed array if you know the number of lines
arrCustomerName = Split(strCustomername,vbCrLf)
splitCustomerName = arrCustomerName(index)
End Function
The query
UPDATE table SET newCustomerName = splitCustomerName([table].[CustomerName],0)
, newCustomerStreet = splitCustomerName([table].[CustomerName],1)
, newCustomerCity = splitCustomerName([table].[CustomerName],2);
Just create the necessary columns for name, street and city, then run the query.
If you delete the CostumerName column and rename the table (e.g. newTable) you can create a query with the oldname of the table, that behaves like your old table.
SELECT *
, newCustomerName & vbCrLf & newCustomerStreet & vbCrLf & newCustomerCity as CustomerName
FROM newTable

SQL SERVER: Loading data all at ONCE or Checking ONE by ONE?

Which one could be a better practice? In my situation, I need to check if a specific data exists in a table. I am iterating through an Excel file and verifying if a code there exists in my table using VB.NET. I have two options to do this (or if there is a better way to do this, I am open for suggestions).
First is to check it one by one, this code is executed per loop:
SQL = "SELECT TOP 1 * FROM Table1 WHERE Code = '" & codeFromExcel & "'"
rs = dbConn.Execute(SQL)
If Not rs.EOF Then
isFound = True
Else
isFound = False
End If
The other one is I load all the codes in a List(Of T)
Dim myList As New List(Of String)()
rs = Nothing
rs = dbConn.Execute("Select Code from Table1")
If Not rs.EOF Then
Do While Not rs.EOF
myList.Add(rs.Fields("Code").Value.ToString)
rs.MoveNext()
Loop
End If
Then check every record if it is in the List(Of T) while iterating in the Excel.
If myList.Contains(codeFromExcel) Then
isFound = True
Else
isFound = False
End If
I've been working with this kind of stuff most of the time and I want to know which one is the most efficient way to use. At the moment I only have a few records in my database. I want my code to be ready and efficient when the time comes that I need to deal with numerous records. Thanks in advance!
Additional info: The data doesn't need to be "fresh" as that table is meant for one-time entry only.
Personally I prefer to open as less connections to data base as possible.
So:
If the table is not very large (some hundred rows) I would go with the "cache" option.
Generally:
I would gather all excel codes in a list. ( excelCodes )
Then I would query something like Select Distinct Code from Table1 Where Code In ( excelCodesList ) and store it in a second list ( foundCodes ).
Then I would compare these lists.
I test it on a table with 6.143.993 rows.
To select just one column (description) to "cache" took 1'29".
On the other hand query like:
select distinct description from ItemDetail where description in ( 'abc','cddd','xxx' )
took 0'58".
UPDATE
An index on Code column might help with performance.

getting data from rows after executing query

I am very new to DB application development, though I have a fair amount of experience in VB.NET and C++ (self-taught, somewhat intermediate). I have a query in a table adapter with two parameters (user input) that always returns only one row from a table, based on those two parameters. Let's say row X with A, B and C columns. Filters are set on A and B in my query, but it selects all fields.
Now, I want to show the value of C in one of my main Form objects (let's say a Label in this example), but I cannot seem to be able to extract it. I know it probably is very easy, but I am a bit lost in DB code jungle..
[EDIT]
My apologies, the code bit (example).
Query:
SELECT Column1, Column2, Column3
FROM Table1
WHERE (Column1 = #Parameter1) AND (Column2 = #Parameter2)
In my VB project:
Dim temp
temp=Me.Table1TableAdapter.queryName(Me.MyProjectDBDataSet.Table1,userinput1, userinput2)
Up to this point everything works perfectly, but this is also where I get stuck. How do I, let's say, assign the value of Column3 (after running the query the result will always be only one row from Table1) to Label.Text for instance?
I hope this makes it a bit clearer..
Dim db As Database = DatabaseFactory.CreateDatabase
Dim cmd As DbCommand = db.GetSqlStringCommand(query) 'Query is a string containing your SQL command'
Dim sqlDataReader As IDataReader = db.ExecuteReader(cmd)
Dim myObj As New MyObject
If sqlDataReader IsNot Nothing Then
'Loop through the rows of the DataReader'
Do While sqlDataReader.Read()
'Do something here with the value in Column3'
myObj.myIntegerProperty= CInt(IIf(IsDBNull(.Item("Column3")), 0, .Item("Column3")))
Loop
End If

Entity Framework - how to get database column datatype from metadata

Is there a way to get the database column DataType length information given a table's EntityType?
Example SQL (SQL Server) that you can run to see precisely what information I am looking for:
select
sys.tables.name as 'Table Name',
sys.columns.name as 'Column Name',
sys.systypes.name as 'DataType',
sys.columns.max_length as 'Max Length',
sys.columns.precision as 'Precision'
from
sys.columns, sys.systypes, sys.tables
where
sys.columns.system_type_id = sys.systypes.xtype
and sys.systypes.name <> 'sysname'
and sys.tables.type = 'U'
and sys.tables.name <> 'sysdiagrams'
and sys.columns.object_id=sys.tables.object_id
order by
sys.tables.name, sys.columns.column_id;
The last 3 columns contain the data that I would like to have access to because I'm generating some documentation. One example reason for the documentation is: Entity Framework will throw an Exception by default if a string is set on a property that can't support it's length. A developer without access to the database metadata has a challenge with the discoverability of length requirements in this case.
Thanks,
Aaron
Unfortunately no.
Even if that information is correctly captured in the SSDL (i.e. the Storage Schema Definition language) there is no public API in EF to go from C-Space (conceptual model) property to S-Space (storage model) column.
If your model is simple you can perhaps infer that information, using the EF metadata workspace and some simple heuristics, but once things get even a little complicated, those heuristics will break down.
Your only option at that point is to write code to interpret MSL (mapping or CS-Space) files, and use that in conjunction with the MetadataWorkspace to go from C-Space to S-Space.
EDIT: as pointed out by KristoferA you often have the attribute on the C-Space property, so you can go to directly to that. Unfortunately that is not always the case, and often it gets out of sync with the database.
I'm pretty sure that Julie Lerman's book covers how to get maxlength, at least a tool to validate against it, by making changes in the POCO creation. Chapter 13, starts around page 356. Example 13-12 covers it, it starts with
string MaxLengthValidation(EdmProperty prop)...
it's copyrighted material so I won't cut/paste it, but I hope you can buy a copy of her book and get the info.
Yes, this is possible: (EF6.1)
<Extension>
Public Function GetColumns(Of TEntity)(Db As IObjectContextAdapter) As List(Of DataColumn)
Dim oMetadata As MetadataWorkspace
Dim oObjects As ObjectItemCollection
Dim oContext As ObjectContext
Dim oColumn As DataColumn
Dim oQuery As Func(Of EdmProperty, Boolean)
Dim oType As EntityType
GetColumns = New List(Of DataColumn)
oContext = Db.ObjectContext
oMetadata = oContext.MetadataWorkspace
oObjects = oMetadata.GetItemCollection(DataSpace.OSpace)
oType = oMetadata.GetItems(Of EntityType)(DataSpace.OSpace).
Single(Function(EntityType As EntityType) oObjects.GetClrType(EntityType) Is GetType(TEntity))
oQuery = Function(EdmProperty As EdmProperty) EdmProperty.DeclaringType.Name = oType.Name
oType.Properties.ToList.ForEach(Sub(Column As EdmProperty)
oColumn = New DataColumn With
{
.AutoIncrement = Column.IsStoreGeneratedIdentity,
.AllowDBNull = Column.Nullable,
.ColumnName = Column.Name,
.DataType = Column.PrimitiveType.ClrEquivalentType,
.Caption = Column.Name
}
If oColumn.DataType Is GetType(String) Then
oColumn.MaxLength = Column.MaxLength.GetValueOrDefault
Else
oColumn.MaxLength = -1
End If
GetColumns.Add(oColumn)
End Sub)
End Function

Resources