I am converting an old 2010 Access data base to Access 2016, the database being originally built in Access 2000. My customer table used an autonumber field to generate a CustomerId number.
I used this field to connect to my repairs table which currently has 13,000 records. I have not been able to find away to maintain this field in new database, so I thought if I can export the table to an Excel file than add numbers in sequence of missing ID numbers along with data to fill name and address fields for temp import to new database, after import I can delete these fields.
I don't know if there are other ways to maintain this id. I imported customer table with Old ID field name, but access won't allow me to use this field to create relationships to new repairs table.
The ID numbers go from 1 to 8,437 yet there are only 7,884 records in the spreadsheet.
The best way to resequence the IDs is to take advantage of "Cascade Update Related Fields".
What you will have to do is
Delete all the relationships to your table
Change the ID field to Number - Long Integer
Add the relationships back, inforcing cascading updates
Shift all the indices to a number larger than the current max ID
Renumber than starting at 1
Delete all the relationships
Delete the ID field
Save the table
Add the ID field back as auto-increment - primary key
Add the relationships back
ReImcrementCustomerIDs:Sub
Option Compare Database
Option Explicit
Public Sub ReImcrementCustomerIDs(ByVal FirstIndex As Long)
Dim rs As DAO.Recordset
Dim db As Database
Dim SQL As String
Dim ID As Long
Set db = CurrentDb
SQL = "SELECT CustomerID FROM Customers ORDER BY CustomerID;"
Set rs = db.OpenRecordset(SQL, dbOpenDynaset)
Do While Not rs.EOF
rs.Edit
rs("CustomerID") = FirstIndex
FirstIndex = FirstIndex + 1
rs.Update
rs.MoveNext
Loop
End Sub
Usage
ReImcrementCustomerIDs 50000
ReImcrementCustomerIDs 1
Related
I have a design for a multi-user database:
1. Form A is used to update Table A and Table B (simultaneously On Click)
2. Form B is used to review Table B, approve records, then delete them from Table B
The problem is if Form B is opened on a record (with Primary Key CASENUMBER) and the record for that CASENUMBER is edited in Form A.
How do I put a lock on a specific record so that if it is being viewed in a form it cannot be viewed/edited in another?
To expand on your syntax question:
First you would need to modify your SQL statement to include the IN_USE_A and IN_USE_B. Once a record is pulled but before it is put into the form, you would set a recordset based on that record and then make the field for each table true.
Dim strSQL As String
Dim myR As Recordset
strSQL = "SELECT * FROM TABLE_A WHERE criteria_here"
Set myR = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset)
'myR is now that record and can be manipulated/data pulled from
myR.Edit
myR![IN_USE_A] = TRUE
myR.Update
'perform tasks and such
'then just before closing
myR.Edit
myR![IN_USE_A] = FALSE
myR.Update
Set myR = Nothing
I am inserting data from my vb.net application to msaccess db.
I am confused in way of getting the last inserted record added to a table. IN MS-SQL we get ##IDENTITY for that but it didn't worked for me in MSAccess.
so what should be do for getting the last inserted record added to a table?
Example:
Dim db As Database
Set db = CurrentDb
db.Execute "INSERT INTO Table1 (atext) Values('abc')", dbFailOnError
Dim rs As dao.Recordset
Set rs = db.OpenRecordset("select ##identity")
Debug.Print rs(0)
It does require that there is an autoincrement key on the table.
Here is a short example using OleDb. Notice that I create a command from the connection and then reuse that object to make my select identity call. This ensures we are in the same scope and get the identity of the record we just inserted. This has the same effect of chaining the commands together with ";", like you would want to do in other DB SQL calls to return the identity with the insert command. ExecuteScalarAsync returns the response object which we can cast to our ID type.
Dim Identity As Integer
Dim recordsAffected As Integer
Using connection As New OleDbConnection(ConnectionString)
Await connection.OpenAsync()
Using command = connection.CreateCommand()
command.CommandText = "INSERT INTO table (field) VALUES (?)"
recordsAffected = Await command.ExecuteNonQueryAsync()
' Get the ID of last inserted record
command.CommandText = "SELECT ##IDENTITY"
Identity = CInt(Await command.ExecuteScalarAsync())
End Using
connection.Close()
End Using
It's always a good practice to have a numeric (even auto-increment) primary key. Then you can always select the MAX and that's the latest inserted record.
It's more complicated in Access than SQL Server because access doesn't support the execution of multiple statements in a batch or output parameters.
According to the MSDN documentation, you need to add a handler for the RowUpdated event.
Before resorting to this, however, I would try wrapping your insert code in a transaction and then executing the select ##identity method within the transaction. Might not work, but worth a shot.
As far as I know, MS Access does not have the functionality to get the last added row.
In practice, I create an autoincrement column (which is usually the Primary Key anyway). Then I run this query when I desire to get the last row in the table:
SELECT TOP 1 * FROM [Table] ORDER BY [IdColumn] DESC
It simply sorts the the rows in the table by the ID column in reverse order and takes the first one (which is really the last row in the table).
I'm working on an MS Access Database with tons of duplicate entries. The problem is that there is a table of students, and sometimes instead of just updating a certain student's information, someone would just add the student in again with a different ID. I want to get rid of all the duplicates (which is a pain since there's barely any way to differentiate them), which would be fine by just deleting the duplicates, except that other tables may rely on the duplicate. How can I change all the tables that rely on a certain ID to rely on the ID that I choose to keep?
Here's what it looks like:
Student ID | L. Name |F. Name
ANDY-01 | Andy | Andy
ANDY-02 | Andy | Andy
Then in the courses table I'd have courses that ANDY-01 would have taken, and courses ANDY-02 would have taken. I want to merge all entries in all the tables that would have ANDY-01 and ANDY-02 as ANDY-01. How would I go about this?
(Don't worry about how I'm differentiating between ANDY-01 and ANDY-02)
+1 for Riho's answer. To update multiple tables you could create a procedure like the one below, and manually update the ID values and execute the procedure for each student.
If you have a table or query that maps the old and new IDs you could write another procedure to read the table and call this procedure for each student.
Public Sub UpdateStudent()
Dim oldID As String
Dim newID As String
oldID = "ID1"
newID = "ID2"
DoCmd.Execute "update another_table set student_id='" & newID & "' where student_id=" & oldID
DoCmd.Execute "update yet_another_table set student_id='" & newID & "' where student_id=" & oldID
End Sub
You just have to make some update SQL:
update another_table set student_id=:ID2 where student_id=:ID1
Anyone have some good examples (newb worthy) of what bulk inserting should look like or a great way to explain it, utilizing the whole LINQ to SQL method?
I've got a DB with about 7 tables I'm trying to link some .net pages to and as much as I can qry most of these tables, I'm having a heck of a time inserting into them. One complex scenerio I am finding revolves around the use of a GUID and how to get that particular GUID to propogate over into another table...
Anyone have any ideas/examples?
You might want to give a little more insight to the nature of your problem and your current setup.
I haven't really messed with LINQ before so i just set up a really simple project. I was able to insert GUIDs into two seperate tables just fine.
Dim db As New testDBDataContext
' Table1 ID (Primary Key)
Dim gId As Guid = Guid.NewGuid()
' Table2 ID (Primary Key)
Dim gId2 As Guid = Guid.NewGuid()
' Insert Record into Table 1
Dim tb1Insert As New test_tb1 With {.Id = gId, .Name = "TestName"}
db.test_tb1s.InsertOnSubmit(tb1Insert)
' Insert Record into Table 2, with testID referenced to Table1's Primary Key
Dim tb2Insert As New test_tb2 With {.Id = gId2, .test1Id = gId, .OtherName = "OtherName"}
db.test_tb2s.InsertOnSubmit(tb2Insert) '
' Commit Changes
db.SubmitChanges()
The only way to get i got an error is if i set up a relationship in SQL Server between the two tables. Then if i tried to insert table 2 first it would error out because i would be trying to insert an GUID table 2's "test1ID" w/o having that GUID in table 1 yet.
If you are getting a "conflicted with COLUMN FOREIGN KEY constraint" error thats probably what is happening.
I want to duplicate a row, not the keys of course, without explicity using the field names.
Is there a SQL way or do I have to enumerate the field names through code?
I don't want to explicity use field names because I want to minimize code and db dependencies.
I am going to use it in the Ms Access 2003. I mention it in case that no standard way exists.
INSERT INTO `<table>` (column1, column2, ...) -- Not IDENTITY columns
SELECT column1, column2, ... FROM ...
This will also allow you to insert replacement values for the primary key columns, etc. I've used this, along with a common table expression, to take a set of test data from the month of February, and to pretend they're really from June.
I know you said you want to do it without the field names, but I don't think you can. It's also not a good idea, as it would tie you to the order of the columns.
If you don't have any uniques to worry about:
INSERT INTO <table> (SELECT * FROM <table> WHERE <condition>)
Otherwise, John Saunders' answer is probably your best bet.
If your primary key fields have automatic identifiers then you might well be able to script to interogate the system for fields which are not in the PK, and use the existing values for those that are not and only insert those ones (or to insert null for the PK fields).
Consequently I don't think there is going to be a "standard" way.
I'm not an Access person, but in SQL Server you can choose "Script table as --> Insert into" in SQL Server Management Studio. You can easily modify this to filter the rows you want into an INSERT INTO SELECT statement.
Perhaps something like this exists in Access?
Like folks have stated before me, you can do "INSERT INTO TBL SELECT * FROM TBL WHERE X=Y" and you will get one row. And this will fail if you have a primary key.
If you do not have a PK then you probably have bigger problems.
Is this a linked table? If so, there are no database dependencies, because you are dealing with an ODBC link. In that case, you can easily use this to get a list of columns for the table:
SELECT TOP 0 * FROM TBL (on linked tbl will need a round trip to server)
You get a blank recordset, and you just iterate through the columns.
Ms Access 2003 oriented solution
I have a form where the user can press a button to create a new version of the current record.
That part in Ms Access is easy:
DoCmd.GoToRecord , , acNewRec
Now I need to update all the fields on the form (controls are bind with table fields) except the key, ie "id" field, with data from some other record.
I came up with the below routine, which worked good for me:
Private Sub UpdateRow(tblname As String, key_name As String, key_value As String)
Dim Rst As Recordset
Dim field As field
Set DB = CurrentDb
Set Rst = DB.OpenRecordset("select * from " & tblname & " where " & _
key_name & "=" & key_value, dbOpenDynaset)
For Each field In Rst.Fields
If field.Name <> key_name Then
Form(field.Name) = field
End If
Next field
Rst.Close
Set Rst = Nothing
Set DB = Nothing
End Sub
And I use it like this:
DoCmd.GoToRecord , , acNewRec
UpdateRow "TableName", "KeyName", "some_previous_key_value"
Form.Refresh
You would need to explicitly supply the field names for the keys when you supply replacement values, therefore a 'standard' way is simply not possible.
...unless all you tables have a single key, all with the same name (ID is popular), and each key consists of a single column that has the IDENTITY (autonumber) property, in which case you would in fact have no keys at all, merely a way of using the IDENTITY value to uniquely identify your duplicate rows!