How to insert data into two tabels? - c#

I have two tables FILM(Id, Title, Director, Year, Category) and Record(Id, Film_id)
Id from FILM table is used as a foreign key as Film_id in Record table.
I want to insert data at the same time date into both tables. How construct a sql query with INSERT?
using (var connection = new MySqlConnection(constring))
{
connection.Open();
using (var cmdDataBase = connection.CreateCommand())
{
cmdDataBase.CommandText = "INSERT INTO film(Title, Director, Year, Category) VALUES (#Title, #Director, #Year, #Category) ";
cmdDataBase.Parameters.Add(new MySqlParameter("#Title", fm.Title));
cmdDataBase.Parameters.Add(new MySqlParameter("#Director", fm.Director));
cmdDataBase.Parameters.Add(new MySqlParameter("#Year", fm.Year));
cmdDataBase.Parameters.Add(new MySqlParameter("#Category",n));
cmdDataBase.ExecuteNonQuery();
}
}

You get the last auto-generated ID with LAST_INSERT_ID(). Then, you'd use a transaction, because you don't want to insert a parent record, if you can't also insert the child record, or so I understand.
This is it more or less. You should add error handling (try, catch) of course.
// Start transaction
MySqlTransaction transaction = connection.BeginTransaction();
MySqlCommand command = new MySqlCommand();
command.Connection = connection;
command.Transaction = transaction;
// Parent record
command.CommandText = "INSERT INTO film(Title, Director, Year, Category) VALUES (#Title, #Director, #Year, #Category) ";
command.Parameters.Add(new MySqlParameter("#Title", fm.Title));
command.Parameters.Add(new MySqlParameter("#Director", fm.Director));
command.Parameters.Add(new MySqlParameter("#Year", fm.Year));
command.Parameters.Add(new MySqlParameter("#Category",n));
command.ExecuteNonQuery();
// Child record
command.CommandText = "INSERT INTO record (Film_id) VALUES (LAST_INSERT_ID())";
command.ExecuteNonQuery();
// Commit inserts
transaction.Commit();

You need to do it in sequence. First, add record to your main table Film, then other table Record. Check below:
INSERT INTO Film(Title, Director, Year, Category)
VALUES('Title', 'DirectorName', 1990, 'Action');
--Assuming ID for Record table is AUTO_INCREMENT column
INSERT INTO Record(Film_id)
VALUES ((SELECT id FROM Film WHERE Title='Title' and Director='Director'));
Also, LAST_INSERT_ID() can be used:
INSERT INTO Film
...
INSERT INTO Record
...
film_id = LAST_INSERT_ID()
Ref: Mysql: How to insert values in a table which has a foreign key

If you are using MySQL try to add ;return LAST_INSERT_ID(); at the end of you query and add return parameter as below.
var returnVal = cmdDataBase.Parameters.Add("#ReturnVal", SqlDbType.Int);
returnVal.Direction = ParameterDirection.ReturnValue;
After cmdDataBase.ExecuteNonQuery(); extract id from returnVal
var id = returnParameter.Value;
After that you can use id to perform the second insert.

Related

C# Insert Value Foreign Key

I have 2 tables which are tableCustomerLogin and tableCustomerRegister. There is Foreign Key for the tableCustomerLogin i.e. cust_id.
In the tableCustomerLogin, I have tableCustomerLogin
cust_login_id
cust_id
cust_email
cust_username
cust_password
and for tableCustomerRegister,
tableCustomerRegister
cust_id
cust_fullname
cust_username
cust_email
cust_password
cust_mobile_number
cust_image
cust_address1
cust_address2
cust_city
cust_postcode
cust_create_acc_time
When customer register, the data will store in the tableCustomerRegister. How to make it register in the tableCustomerLogin?
string sql = #"INSERT INTO tableCustomerRegister VALUES (#cust_fullname, #cust_username, #cust_email, #password, #cust_mobile_phone, #cust_address1, #cust_address2, #cust_image, #cust_city, #cust_state, #cust_postcode, #cust_create_acc_time, #role, #enabled)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#cust_fullname", txtFirstName.Text + " " + txtLastName.Text);
cmd.Parameters.AddWithValue("#cust_username", txtUsername.Text);
cmd.Parameters.AddWithValue("#cust_email", txtEmail.Text);
cmd.Parameters.AddWithValue("#password", passwordhash);
cmd.Parameters.AddWithValue("#cust_mobile_phone", txtMobilePhone.Text);
cmd.Parameters.AddWithValue("#cust_address1", txtAddress1.Text);
cmd.Parameters.AddWithValue("#cust_address2", txtAddress2.Text);
cmd.Parameters.AddWithValue("#cust_image", txtProfilePicture.Text);
cmd.Parameters.AddWithValue("#cust_city", ICityString());
cmd.Parameters.AddWithValue("#cust_state", ddState.SelectedValue.ToString());
cmd.Parameters.AddWithValue("#cust_postcode", txtPostcode.Text);
cmd.Parameters.AddWithValue("#cust_create_acc_time", DateTime.Now);
cmd.Parameters.AddWithValue("#role", "user");
cmd.Parameters.AddWithValue("#enabled", enabled);
try
{
conn.Open();
cmd.ExecuteNonQuery();
lblStatus.Text = "Status: Data successfully saved.";
}
well, first of all you need to change your query
string sql = #"INSERT INTO tableCustomerRegister OUTPUT INSERTED.cust_id VALUES (#cust_fullname, #cust_username, #cust_email, #password, #cust_mobile_phone, #cust_address1, #cust_address2, #cust_image, #cust_city, #cust_state, #cust_postcode, #cust_create_acc_time, #role, #enabled)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#cust_fullname", txtFirstName.Text + " " + txtLastName.Text);
cmd.Parameters.AddWithValue("#cust_username", txtUsername.Text);
//so on (all your parameters)
var custid = (int)cmd.ExecuteScalar()
ExecuteScalar return int, in this case it will return cust_id as your query have OUTPUT INSERTED.cust_id. Now You have your inserted cust_id saved in tableCustomerRegister. Now all you need to do just write another query for save data into your tableCustomerLogin with foreign key cust_id. like this,
string Sql2 = "INSERT INTO tableCustomerLogin (column_names) VALUES (parameters values)";
SqlCommand cmd = new SqlCommand(sq2, conn);
cmd.Parameters.AddWithValue("#cust_id",custid); //as foreign key
//all other Parameters
You can first insert a tableCustomerRegister record and then insert another data the tableCustomerLogin table. You would be better do this in the transaction block.
The other way , You can add a trigger to the tableCustomerLogin table.
CREATE TRIGGER trg_tableCustReg ON tableCustomerRegister
FOR INSERT
AS
/*
* if CustLoginID is a identity , no dont need to add
*/
INSERT INTO tableCustomerLogin
(cust_login_id, cust_id, cust_email, cust_username, cust_password)
Select
'CustLoginID',
cust_id ,
cust_email,
cust_username,
user_password
FROM inserted
go
Probably the best solution is to follow the DRY principle, Dont Repeat Yourself.
I think that you can store all information in a single table customer_table for example and then retrive the necessary data with a more simple logic from only this table.
Instead, if you want to stay on your actual data structure, simply add new insert statement after firstseparate by semicolon
how to insert data into multiple tables at once
there are two different way. you shold use SCOPE_IDENTITY
string sql = #"INSERT INTO tableCustomerRegister VALUES (#cust_fullname, #cust_username, #cust_email, #password, #cust_mobile_phone, #cust_address1, #cust_address2, #cust_image, #cust_city, #cust_state, #cust_postcode, #cust_create_acc_time, #role, #enabled) SELECT SCOPE_IDENTITY()";
SCOPE_IDENTITY Returns the last identity value inserted into an
identity column in the same scope
var newId= cmd.ExecuteScaler();
newId created new Primary Key ID for you cust_id
you have this ID(cust_id) and you can register in the Login table.
INSERT INTO tableCustomerLogin (cust_login_id,**cust_id**,cust_email,cust_username,cust_password)
cust_id = newId
If Cust_id is auto-created in the tableCustomerRegister table, then you can save the same id in the tableCustomerLogin table (cust_id). then only your foreign Key relation work.
try
{
conn.Open();
cmd.ExecuteNonQuery();
SqlCommand get_custid_cmd = new SqlCommand("select ##identity", conn);
int cust_id = Convert.ToInt32(get_custid_cmd.ExecuteScalar());
string sql_insert = #"INSERT INTO tableCustomerLogin VALUES (#cust_id, #cust_username, #cust_email, #password)";
SqlCommand cmd_insert = new SqlCommand(sql_insert, conn);
cmd_insert.Parameters.AddWithValue("#cust_id",cust_id);
cmd_insert.Parameters.AddWithValue("#cust_username", txtUsername.Text);
cmd_insert.Parameters.AddWithValue("#cust_email", txtEmail.Text);
cmd_insert.Parameters.AddWithValue("#password", passwordhash);
cmd_insert.ExecuteNonQuery();
lblStatus.Text = "Status: Data successfully saved.";
}

Insert into multiple tables using INSERT_IDENTITY - ADO.Net

I want to INSERT records in multiple tables with ADO.NET.
I want to INSERT a new record into a table called Professionals. It has a foreign key mapped to a different table.
tables:
Example:
cmd.CommandText = "insert T_Name select (Name.T_Name,Date.T_Name,DId.Date) values (#N,GETDATE(),???)from T_Name inner join Date ON Date.DId=T_Name.DId; ";
cmd.Parameters.AddWithValue("#N", txt_Name.Text);
OR
...
How can I add values into these tables at one time?
After add insert sql for first table
SELECT SCOPE_IDENTITY();
then you get last inserted id. You can use second sql parameters.
Example:
var dateNow = DateTime.Now;
var cmd = new SqlCommand("INSERT INTO Date (Date) VALUES (#Date);SELECT SCOPE_IDENTITY();", cnn);
cmd.Parameters.AddWithValue("#Date", dateNow);
var insertedId = cmd.ExecuteScalar();
cmd = new SqlCommand("INSERT INTO T_Name (Name,Date,DId) VALUES (#Name,#Date,#DId);", cnn);
cmd.Parameters.AddWithValue("#Name", "Test");
cmd.Parameters.AddWithValue("#Date", dateNow);
cmd.Parameters.AddWithValue("#DId", insertedId);
cmd.ExecuteNonQuery(); //or ExecuteScalar() for get last insertedId

asp.net : INSERT in oracle table only if the clause WHERE of the UPDATE find zero records

I am developping an asp.net application. I would like to know how to update a field of an oracle table record, and if the record is not present, inserting it.
I have a table with the following fields NAME and SURNAME.
I would like to change the SURNAME to "new_surname" of the record where the NAME equals="name". However, if none of the records in table contains a field NAME equals to name I would like to insert a new record (SURNAME=new_surname and NAME=name).
This is my code :
OracleConnection connection = new OracleConnection(connectionstring);
try
{
connection.Open();
OracleCommand command = connection.CreateCommand();
string sql = "UPDATE TABLE SET SURNAME=\'new_surname\' WHERE NAME=\'name\'";
command.CommandText = sql;
command.ExecuteNonQuery();
connection.Close();
}
catch (Exception exp)
{
}
Is there an optimal way to do the insert only if the update find zero records matching the "where" clause. I was thinking of first doing a select count of the record matching the "where" clause, and then if I found zero results I would do an insert, and if I found at least one result I would do an update. But I find this solution a little bit heavy.
Cannot test but you could try this
using(OracleConnection connection = new OracleConnection(connectionstring))
using(OracleCommand command = connection.CreateCommand())
{
connection.Open();
string sql = #"MERGE INTO TABLE t USING dual on(name='name')
WHEN NOT MATCHED THEN INSERT (name, surname) values ('name', 'new_surname')
WHEN MATCHED THEN UPDATE SET surname = 'new_surname'";
command.CommandText = sql;
command.ExecuteNonQuery();
}
you can modify the query as :
string sql = #"IF EXISTS (SELECT * FROM \'Given Table\' WHERE NAME=\'name\') THEN
BEGIN
--your update query
END
ELSE
BEGIN
-- your Insert Query
END
END IF";

Convert ID to Int and save to datatable

I have been trying to add the Customer_ID from the Customer table to Customer_ID in Customer_Ship table. I keep running into the Customer_ID not converting to Int properly. It's possible that I am not actually getting the new row added to Customer_Ship table first. Your help is greatly appreciated and many thanks in advance.
if (customer_ID == "")
{
string SQL = "INSERT INTO Customer (Customer_Name) VALUES (#customer_Name); SELECT Customer_ID FROM Customer WHERE Customer_ID = SCOPE_IDENTITY();";
SqlCommand sqlCommand = new SqlCommand(SQL, sqlConnection);
sqlCommand.Parameters.Add("#customer_Name", SqlDbType.VarChar, 100).Value = customer_Name;
sqlConnection.Open();
int customer_Id = (int)sqlCommand.ExecuteScalar();
SQL = "INSERT INTO Customer_Ship (Customer_ID) VALUES (#customer_Id)";
sqlCommand = new SqlCommand(SQL, sqlConnection);
sqlCommand.Parameters.AddwithValue("#customer_Id", customer_Id);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
Two mistakes I see:
you should be just returning SCOPE_IDENTITY - you can simplify your first INSERT statement to read:
INSERT INTO Customer (Customer_Name) VALUES (#customer_Name); SELECT SCOPE_IDENTITY();";
This will return the newly inserted Customer_ID identity value from the Customer table - no need to do this complicated SELECT that you had in your question
You need to call .ExecuteScalar() right from the beginning - don't call .ExecuteNonQuery() first and then ExecuteScalar() - that'll execute the statement twice - just use:
using(SqlCommand sqlCommand = new SqlCommand(SQL, sqlConnection))
{
sqlCommand.Parameters.Add("#customer_Name", SqlDbType.VarChar, 100).Value = customer_Name;
sqlConnection.Open();
int customer_Id = (int)sqlCommand.ExecuteScalar();
sqlConnection.Close();
}
That'll insert the values into Customer and return the newly created Customer_ID as the return value into customer_id (which already is an Int) from .ExecuteScalar(). You can then use this int value to insert into the Customer_Ship table - no conversion necessary - this already is an int
The possible reason for not converting the value is you are trying to convert an empty string(customer_ID : Refer Line :#1 of your code) and not "customer_Id " what you are fetching from the database .

Get auto_increment id from table

I have this code:
string conStr = ConfigurationManager.ConnectionStrings["BackgammonGame"].ConnectionString;
SqlConnection con = new SqlConnection(conStr);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = ("INSERT INTO Game (playerA, playerB) OUTPUT INSERTED.gameID VALUES (#playerA, #playerB)");
cmd.Parameters.Add("#playerA", SqlDbType.NVarChar).Value = firstPlayer;
cmd.Parameters.Add("#playerB", SqlDbType.NVarChar).Value = secondPlayer;
cmd.ExecuteNonQuery();
int id = (int)cmd.ExecuteScalar();
con.Close();
When I insert into this table, I have an auto_increment int primary key column called gameID, and I declared in the sql statement that I want the gameID in output.
my problem is that when I write this line in the code: int id = (int)cmd.ExecuteScalar(); the inserted parameters apear twice in the table (2 rows with the same info.), but when I delete it it's ok.
I need this row so I can use this id in other table.
Change your command text with this and try
cmd.CommandText = ("INSERT INTO Game (playerA, playerB) VALUES (#playerA,#playerB);
SELECT SCOPE_IDENTITY()");
SCOPE IDENTITY returns the identity value of last inserted row. Hence that will returns the identity filed of the inserted row using the insert query
EDIT
You are executing the query two times
cmd.ExecuteNonQuery(); // Avoid this
int id = (int)cmd.ExecuteScalar();// This is enough
In both case your query gets executed and it cause insertion twice.
ExecuteNonQuery() will execute the insert query and will returns the number of rows affected.
Where as ExecuteScalar() will return the result of the select scope_identity() staement which is the identity column of the inserted row.
Here is your code
con.Open();
cmd.CommandText = ("INSERT INTO Game (playerA, playerB) VALUES (#playerA,#playerB);
SELECT SCOPE_IDENTITY()");
cmd.Parameters.Add("#playerA", SqlDbType.NVarChar).Value = firstPlayer;
cmd.Parameters.Add("#playerB", SqlDbType.NVarChar).Value = secondPlayer;
int id = Convert.ToInt32(cmd.ExecuteScalar());
con.Close();
Modify your command like this
INSERT INTO YourTable(val1, val2, val3 ...)
VALUES(#val1, #val2, #val3...)
SELECT SCOPE_IDENTITY()
But i personally prefer to write a stored procedure and return the primary key as an output parameter of that sp.

Categories

Resources