I have a ms sql table PRODUCTS.
And it has three columns ID (int),NAME (nvarchar),TSTAMP (timestamp)
I want to get new inserted row's both id and timestamp (like multiple select scope_identity).
I can achieve that in sql as following:
INSERT INTO PRODUCTS (NAME)
OUTPUT inserted.ID,inserted.TSTAMP
VALUES ('Example Product')
But how can i read it in vb.net with sqlclient.sqlcommad on insertation? Which function of sqlcommand do i have to use and how? ExecuteReader maybe?
Using the ExecuteReader() method of SqlCommand would work the same as with SELECT.
OUTPUT clause works like a SELECT statement but its usage differs in
INSERT, UPDATE and DELETE commands
Here's a sample code. Try it.
Dim connString As String = "server=Test; database=Test;" + _
"uid=sa; pwd="
Dim conn As New SqlConnection(connString)
Dim cmdString As String = "INSERT INTO PRODUCTS (NAME) " + _
"OUTPUT inserted.ID,inserted.TSTAMP " + _
"VALUES ('Example Product')"
Dim cmd As New SqlCommand(cmdString, conn)
conn.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader()
conn.Close()
Here're some links
Running The OUTPUT Clause From C#
Implementing the OUTPUT Clause in SQL Server 2008
Related
I have a parameterized query GET_CUSTOMER:
SELECT * FROM Customer WHERE id = [customer_id]
I want to call this query from another query and pass it a parameter:
SELECT * FROM GET_CUSTOMER(123)
Note the above code is not valid, it is here to give you an idea of what I'm trying to do. Is it possible to do this in MS Access?
UPDATE 1:
The queries I posted are for example. The actual queries are much more complex. I know I can use table joins, but in my specific case it would be much easier if I could run parameterized queries inside other queries (that are parameterized as well). I can't use access forms because I'm using access with my .NET application.
This is how I end up solving this with help of https://stackoverflow.com/a/24677391/303463 . It turned out that Access shares parameters among all queries so there is no need to specifically pass parameters from one query to another.
Query1:
SELECT * FROM Customer WHERE ID > [param1] AND ID < [param2]
Query2:
SELECT * FROM Query1
VB.NET code:
Dim ConnString As String = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=Database.mdb"
Dim SqlString As String = "Query2"
Using Conn As New OleDbConnection(ConnString)
Using Cmd As New OleDbCommand(SqlString, Conn)
Cmd.CommandType = CommandType.StoredProcedure
Cmd.Parameters.AddWithValue("param1", "1")
Cmd.Parameters.AddWithValue("param2", "3")
Conn.Open()
Using reader As OleDbDataReader = Cmd.ExecuteReader()
While reader.Read()
Console.WriteLine(reader("ID"))
End While
End Using
End Using
End Using
You can build the SQL on the fly.
MyID = prompt or get from user some ID
strSQl = "Select * from tblCustomer where ID in " & _
"(select * from tblTestCustomers where id = " & MyID
So you can nest, or use the source of one query to feed a list of ID to the second query.
there's anyone can help me with my vb.codes? i'm new in vb.net and i want to know how to add data in mysql database using n-tier in vb.net. this is may current code in adding data:
Data Layer:
Public Function addData() As DataTable
Dim myCommand As String = "Insert Into tblItems VALUES (#Itemcode, #Itemname, #Itemdescription, #Itemtype, #Itempricing, #Itemonstock, #Itemprice, #Datemod)"
con.Open()
Dim sda As New MySqlDataAdapter(myCommand, con)
Dim dt As DataTable = New DataTable
sda.Fill(dt)
Return dt
End Function
sorry for my code. i really don't know how can i use that in BLL and PL. please help me. i really want to learn from all of you guys..
PS: sorry for my english i'm a 14 yr old and i want to learn programming. i did a research but i can't find what i'm really looking for. thanks in advance.
To insert a new record in a datatable you need to execute a command and provide the values to be sent to the database table.
You need something like this.
Public Function addData(itmCode as String, itmName as String.... omitted the other values) As Integer
Dim myCommand As String = "Insert Into tblItems VALUES " & _
"(#Itemcode, #Itemname, #Itemdescription, " & _
"#Itemtype, #Itempricing, #Itemonstock, #Itemprice, #Datemod)"
con.Open()
Dim cmd As New MySqlCommand(myCommand, con)
cmd.Parameters.AddWithValue("#ItemCode", itmCode)
cmd.Parameters.AddWithValue("#ItemName", itmName)
.... other parameters for the other values to insert will follow....
Dim rowInserted = cmd.ExecuteNonQuery()
return rowInserted
End Function
This requires that you pass to the function the values through a set of variables which values are added to the parameter collection of the command and finally execute the command.
The execution returns the number of records inserted/changed/deleted.
Notice also that your query doesn't specify a field list, so you need to pass the values to update every single field in the underlying datatable with the exact order.
I have a table customers where each cust has UserID as "A000" now I need to get the last entered ID from the database and display it in my textbox.
Can anyone suggest me how do I do this?
As I have seen many articles describing about
SELECT ##IDENTITY
SELECT SCOPE_IDENTITY()
SELECT IDENT_CURRENT('TableName')
but unable to know where to use it correctly.
And here is how I'm doing it :
Dim strConnection As String = "Data Source=.\SqlExpress;Initial Catalog=Subscription;Integrated Security=True"
'Establish SQL Connection
Dim con As New SqlConnection(strConnection)
'Open database connection to connect to SQL Server
con.Open()
'Data table is used to bind the resultant data
Dim dtusers As New DataTable()
'Create a new data adapter based on the specified query.
Dim da As New SqlDataAdapter("SELECT MAX(UserID) FROM Customers", con)
Dim cmd As New SqlCommandBuilder(da)
da.Fill(dtusers)
con.Close()
Use ExecuteScalar :
Dim comm as new SqlCommand
comm.CommandText = "SELECT MAX(UserID) FROM Customers"
comm.Connection = con
Dim MaxUserID as object = comm.ExecuteScalar()
Use the ExecuteScalar method to retrieve a single value (for example,
an aggregate value) from a database
Side Note : ExecuteScalar() may return a null reference (Nothing in VB.NET) if the result of the command is empty like when there are no records in the table or there is condition that doesn't produce any records. Make sure you check that before assigning the value to your TextBox.
I understand that there are other posts such as this, however I cannot find one that will work for me and Im really at the end of my tether with this, I really dont know what to do.
I have a few tables with ID columns and name columns, that are connected by Link Tables through foreign keys etc. I'm trying to enter data into the database via a GUI and to do so I'm using insert statements into the 'regular' tables, then Select statements to get the autogen IDs from the regular table to then insert into the link tables.
The code below is what I've been trying to use to do this.
Imports System.Data.SqlClient
Public Class Test
Private cs As New SqlConnection(".....")
Private Sub btnInsertNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInsertNext.Click
Dim ContID As Integer
Dim FName As Integer
cs.Open()
Using command As New SqlCommand("Select FamID From Family Where Name = '" & FName & " '", cs)
command.Parameters.AddWithValue("#FamID", ContID)
command.ExecuteNonQuery()
End Using
Using command As New SqlCommand("Select DocID From Doctors Where DocName LIKE'" & AddFam.Doctor & " '", cs)
command.Parameters.AddWithValue("#DocID", AddFam.Doctor) ''AddFam is another form I'm using to add a family member to a Doctor
command.ExecuteNonQuery()
End Using
cs.close()
I'm using:
VB 2010
SQL server management 2008 r2
I understand its a bit muddley but any help would be greatly appreciated, and I'm sorry if this has come up before.
It's not really clear what problem you actually have, i assume that you don't know how to retrieve newly generated IDs.
Here is an self-explanatory example on how to retrieve new identity values with ADO.NET:
Using con = New SqlConnection(connectionString)
Dim newID As Int32
Using insertCommand = New SqlCommand("INSERT INTO Test(Value)VALUES(#Value);SELECT CAST(scope_identity() AS int)", con)
insertCommand.Parameters.AddWithValue("#Value", "Value1")
con.Open()
newID = DirectCast(insertCommand.ExecuteScalar, Int32)
End Using
If newID <> 0 Then
Using updateCommand = New SqlCommand("UPDATE TEST SET Value='Value1.1' WHERE idTest=#idTest", con)
updateCommand.Parameters.AddWithValue("#idTest", newID)
If con.State <> ConnectionState.Open Then con.Open()
Dim updatedRecordCount = updateCommand.ExecuteNonQuery
End Using
End If
End Using
The 2 important parts are:
SELECT CAST(scope_identity() AS int)
which will return the new identity value
DirectCast(insertCommand.ExecuteScalar, Int32)
which will return the new Identity column value if a new row was inserted, 0 on failure.
Since you're mixing using parameters with string-concatenation: using parameters is very important because it will prevent SQL-Injection.
SCOPE_IDENITY
ExceuteScalar-Method
Commands and Parameters in ADO.NET
NO! Parameterise your queries like this.
command = New SqlCommand("Select FamID From Family Where Name = #Fname", cs)
command.Parameters.AddWithValue("#Fname", ContID)
FamID = command.ExecuteScalar()
And ideally, you should use Scope_Identity() to get the Identity from you insert statement
You can try with this code on two queries based on # symbol
...
Using command As New SqlCommand("Select FamID From Family Where Name = #FamID", cs)
command.Parameters.AddWithValue("#FamID", ContID)
...
Using command As New SqlCommand("Select DocID From Doctors Where DocName LIKE #DocID", cs)
command.Parameters.AddWithValue("#DocID", AddFam.Doctor)
...
I have a SQLClient.DataSet in VB.NET, and I want to insert the entire thing into a SQL Server table without having to do the following:
For Each dr as Datarow in MyDataset
Dim sc As New SqlCommand("INSERT INTO MyNewTable " & _
"VALUES (#column1, #column2)", MyDBConnection)
sc.Parameters.AddWithValue("#column1", dr.Item(0))
sc.Parameters.AddWithValue("#column2", dr.Item(1))
sc.ExecuteNonQuery()
Next
Since I've got close to a million rows (all pretty skinny, so it's not much space), I obviously don't want to run this loop and generate a million INSERT statements.
I know that one option is to use a linked server when I initially fetch the data, since it's coming from another SQL Server, and just have it to the INSERT from there. However, if I already have the data in my application, is there a more efficient way to bulk insert it? Can I somehow pass the DataTable as a parameter to SQL Server and have it sort it out and insert the rows?
try with SqlBulkCopy
With SQL Server 2008 you can use Table-Valued Parameters:
Dim sc As New SqlCommand(
"INSERT INTO MyNewTable (field1, field2,...)"&
"SELECT field1, field2,... FROM #MyTable;", MyDBConnection)
sc.Parameters.AddWithValue("#MyTable", MyDataset)
sc.ExecuteNonQuery()
Use the SqlDataAdapter's InsertCommand to define your Insert query. Then call the DataAdapter's Update Method with your dataset as a parameter to have it push the data.
Something like:
Dim DA As SqlDataAdapter = New SqlDataAdapter
Dim Parm As New SqlParameter
DA.InsertCommand = New SqlCommand("Insert Into tbl1(fld0, fld1, fld2) Values(#fld0, #fld1, #fld2)", conn)
Parm = DA.InsertCommand.Parameters.Add(New SqlParameter ("#fld0", NVarChar, 50, "fld0"))
Parm = sqlDA.InsertCommand.Parameters.Add(New SqlParameter ("#fld1", SqlDbType.NVarChar, 50, "fld1"))
Parm = sqlDA.InsertCommand.Parameters.Add(New SqlParameter ("#fld2", SqlDbType.NVarChar, 50, "fld2"))
DA.Update(dataset1, "tbl1")
You could call .WriteXML() on the DataSet and dump that into the database in one insert.
A way simplier way is to use a table adapter. Then you can use the Fill method to give a datatable as argument :
Dim oStronglyTypedTable As StronglyTypedDataTable = GetTable() 'A custom function that creates your table from wherever you want)
If Not oStronglyTypedTable Is Nothing Then
Using oAdapter As New StronglyTypedTableAdapter
Dim res As Integer = oAdapter.Update(oStronglyTypedTable)
MsgBox(res & " rows have been updated.")
End Using
End If
Do not forget to change your Database "Copy to Output Directory" property to "Do net copy" and set your connection string properly...