LINQ to SQL - Bulk Insert Using VB - vb.net

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.

Related

executing queries with a check constraint sql

I created a SQL-Lite Database with a few tables in it.
TBL User:
UsrName PK
TBL Car
CarID PK
NotRentable BOOL
TBL CarUser
UsrName PK, FK CHECK(WHERE Car.CarID = CarID AND NotRentable = FALSE)
CarID PK, FK
Now I came across the possibility to have custom constraints on the to be created database entry using the "CHECK" keyword in different SQL dialects.
The examples the internet provides are more simple in the way that only the table that the entry should be written to can be queried using the CHECK keyword.
Is it possible to execute more complex sql-queries which evaluate as True or False as constraints before adding the new data to the table? This is a huge error source, but my intention would be to only use it for very basic matters. Like in the sample above! Thanks for your suggestions.

Webmatrix - Creating two tables with the primary key from one

I currently have the following SQL statement which creates an entry in my database, and auto creates the primary key. This works fine:
if (IsPost){
var sql = "INSERT INTO Property_Info (PropertyName) VALUES (#0)";
db.Execute(sql, Request["propertyname"]);
}
What I also need to do on the same page, is insert a record into a different table, using the primary key created in the above statement. is this possible, or will i need to do this on a separate page?
Yep, you can get the database ID you created with db.GetLastInsertId() and use that as a parameter in your next query.
http://msdn.microsoft.com/en-us/library/webmatrix.data.database.getlastinsertid(v=vs.111).aspx
I've found that you are best off casting it to an int too, so immediately after your db.Execute() line, try this:
int newId = (int)db.GetLastInsertId();

How do we get last inserted record in msaccess query

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).

Inserting multiple parent rows and multiple child rows for each parent with ADO.NET in one setting

I am looking for a howto or someone expert in ADO.NET who can explain me how to properly solve the following scenario:
I have two datatables in a dataset:
ParentTable (ParentID, Name) for user data
ChildTable (ParentID, ActivityID, ...) for schedule data
Tables are linked together at the database level by ParentID which is an Identity column in ParentTable.
Both tables are data bound to a separate DataGridView on the GUI. There supposed to be a "1 parent/N children" relationship between the tables, meaning if I create a new entry in the ParentTable (a new user) I get a clean DataGrid in the child grid to type schedule data for the user. So I setup two DataAdapters for each table to fill their result into a DataSet. I also set up a DataRelation object and assign it to the DataSet to link the two tables by their ParentID columns. Also when I add a row into the ChildTable via DataGrid I use SetParentRow to set the parent row.
With DAUser
.SelectCommand = New SqlCommand("UsersSelect", conn)
.SelectCommand.CommandType = CommandType.StoredProcedure
.SelectCommand.Parameters.AddWithValue("#UserID", MyID)
.Fill(DSData)
End With
With DAActivity
.SelectCommand = New SqlCommand("ActivitiesSelect", conn)
.SelectCommand.CommandType = CommandType.StoredProcedure
.SelectCommand.Parameters.AddWithValue("#UserID", MyID)
.Fill(DSData)
End With
DSData.Relations.Add(New DataRelation("UserActivity", DSData.Tables(0).Columns("ParentID"), DSData.Tables(1).Columns("ParentID")))
Adding row into the ChildTable:
Private Sub DTChildData_TableNewRow(sender As Object, e As System.Data.DataTableNewRowEventArgs) Handles DTChildData.TableNewRow
e.Row.SetParentRow(ParentDataRow)
End Sub
Still, the ParentID column in ChildTable is not populated with the Identity value retrieved from the DB when ParentTable is updated.
Why? I am starting to loose serious amount of hair over this problem...
A couple of notes:
1) The relation between the two tables is most likely incorrect, since you are referencing ParentID on both sides of the relationship. I am guessing that you need to change it to:
DSData.Relations.Add(New DataRelation("UserActivity", DSData.Tables(0).Columns("UserID"), DSData.Tables(1).Columns("ParentID")))
2) You aren't showing your insert or update commands, but if they are stored procedures and the UserID is generated in that stored procedure, then you will need to pass it back out of the stored procedure as an OUTPUT parameter. You will have to change both the SP and the parameter definition (if you have one) in the insert/updated command.

Is there a standard way to duplicate a row in a database table?

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!