I need to insert a product into a ProductDB table and at the same time get the id from the product I just inserted, so I can use it in the next query as a Foreign Key I have been looking at different methods like "select last_insert_rowid()" and "SCOPE_IDENTITY()" but I can't get it to work, how do I get it to work
public static void SaveProduct(ProductModel product)
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
cnn.Execute("INSERT INTRO ProductDB (Name, Price) VALUES (#Name, #Price);",
product);
string ForeignKey = "the id from the last entry from the query above";
cnn.execute("INSERT INTO ImageDB (Filename, Path, FK_Product) VALUES (#Filename, #Path," + ForeignKey + " )");
}
}
In SQL Server has 3 functions (methods) for getting the last inserted id from the table.
IDENT_CURRENT() - returns the last-inserted identity value for a given table.
SCOPE_IDENTITY() - returns the last identity value inserted into an identity column in any table in the current session and current scope.
##IDENTITY - returns the last inserted identity value in any table in the current session, regardless of scope.
We need SCOPE_IDENTITY(), so ATTENTION!!!
This function must be used in the current scope, which located insert command.
Example:
declare
#new_id integer;
INSERT INTRO ProductDB (Name, Price) VALUES (#Name, #Price);
SET #new_id = SCOPE_IDENTITY();
If you would use System.Data.SQLite you could use the LastInsertRowId property.
Example:
using (SQLiteConnection conn = new SQLiteConnection(#"Data Source=.\Test.db"))
{
conn.Open();
SQLiteCommand cmd = conn.CreateCommand();
cmd.CommandText = $"INSERT INTO Test (name) values ('{Guid.NewGuid().ToString()}');";
cmd.ExecuteNonQuery();
id = conn.LastInsertRowId;
conn.Close();
}
Related
I have a table structured as,
Table 3
Fruit ID - Foreign Key (Primary Key of Table 1)
Crate ID - Foreign Key (Primary Key of Table 2)
Now I need to execute a query which will,
Update Crate ID of Fruit ID if Fruit ID is already in Table, and if not then insert record in table 3 as new record.
This is what I got in code right now,
private void RelateFuirtWithCrates(List<string> selectedFruitIDs, int selectedCrateID)
{
string insertStatement = "INSERT INTO Fruit_Crate(FruitID, CrateID) Values " +
"(#FruitID, #CrateID);"; ?? I don't think if it's right query
using (SqlConnection connection = new SqlConnection(ConnectionString()))
using (SqlCommand cmd = new SqlCommand(insertStatement, connection))
{
connection.Open();
cmd.Parameters.Add(new SqlParameter("#FruitID", ????? Not sure what goes in here));
cmd.Parameters.Add(new SqlParameter("#CrateID",selectedCrateID));
}
You can do an "upsert" with the MERGE syntax in SQL Server:
MERGE [SomeTable] AS target
USING (SELECT #FruitID, #CrateID) AS source (FruitID, CrateID)
ON (target.FruitID = source.FruitID)
WHEN MATCHED THEN
UPDATE SET CrateID = source.CrateID
WHEN NOT MATCHED THEN
INSERT (FruitID, CrateID)
VALUES (source.FruitID, source.CrateID);
Otherwise, you can use something like:
update [SomeTable] set CrateID = #CrateID where FruitID = #FruitID
if ##rowcount = 0
insert [SomeTable] (FruitID, CrateID) values (#FruitID, #CrateID)
I am updating a database with a new registered user. they will then be given a userid. I want to use that number when updating there location in another table. but i dont know what the user id will be. (it is autoincrement number) So i was thinkning i would update the first table. And then select the maximum user id and insert that id as the location user id in the other table but I cant get it to work.
Here is the code.
String StrSQL = "INSERT INTO Fastelejer (Fornavn,Efternavn) VALUES ('" + fornavn + "','" +
Efternavn + "')";
OleDbCommand InsertCommand = new OleDbCommand(StrSQL, conn);
InsertCommand.ExecuteNonQuery();
StrSQL = "INSERT INTO Bådpladser (Fastelejerid) SELECT MAX (Fastelejerid) FROM
StrSQL = "INSERT INTO Bådpladser (Fastelejerid) SELECT MAX (Fastelejerid)FROM
Fastelejer WHERE Pladsnummer = " + Pladsnummer;
The pladsnummer represents the input for their location. So the registration should put the user id into the location that is chosen.
In MS Access, "autoincrement" is usually called "identity". You can use the special ##IDENTITY variable to retrieve the ID of the last inserted identity column. Once you know the new ID, you can add it as a parameter in the second insert, like:
command.CommandText = "INSERT Table1 (...) values (...); SELECT ##IDENTITY";
var identity = (int) command.ExecuteScalar();
command.CommandText = "INSERT Table2 (user_id, ...) VALUES (#user_id, ...)";
command.Parameters.AddWithValue("#user_id", identity);
command.ExecuteNonQuery();
I have an entity Report whose values I want to insert into a database table. The following attributes of Report have to be inserted:
reportID - int
RoleID - int
Created_BY = SYSTEM(default)
CURRENT_TIMESTAMP
Now the problem is with the 2nd attribute. I have a report with the LIST<ROLES> attributes. ROLES is a well defined entity which has an ID and a NAME. From this list I have to extract every role and insert each role's ID into the table.
So my query presently looks as below :
INSERT INTO REPORT_MARJORIE_ROLE(REPORT_ID, ROLE_ID, CREATED_BY, CREATED)
VALUES({0}, {1}, 'SYSTEM', CURRENT_TIMESTAMP)
The C# code from where I am parsing these values is as follows :
try
{
StringBuilder _objSQL = new StringBuilder();
_objSQL.AppendFormat(Queries.Report.ReportQueries.ADD_NEW_ROLES, report.ID, "report.MarjorieRoles.Add(MarjorieRole"));
_objDBWriteConnection.ExecuteQuery(_objSQL.ToString());
_objDBWriteConnection.Commit();
_IsRolesAdded = true;
}
So please guide me how to add roles from C# function
I'm assuming you say SQL (structured query language) and you really mean Microsoft SQL Server (the actual database product) instead - right?
You cannot insert a whole list as a whole into SQL Server - you need to insert one row for each entry. This means, you need to call the INSERT statement multiple times.
Do it like this:
// define the INSERT statement using **PARAMETERS**
string insertStmt = "INSERT INTO dbo.REPORT_MARJORIE_ROLE(REPORT_ID, ROLE_ID, CREATED_BY, CREATED) " +
"VALUES(#ReportID, #RoleID, 'SYSTEM', CURRENT_TIMESTAMP)";
// set up connection and command objects in ADO.NET
using(SqlConnection conn = new SqlConnection(-your-connection-string-here))
using(SqlCommand cmd = new SqlCommand(insertStmt, conn)
{
// define parameters - ReportID is the same for each execution, so set value here
cmd.Parameters.Add("#ReportID", SqlDbType.Int).Value = YourReportID;
cmd.Parameters.Add("#RoleID", SqlDbType.Int);
conn.Open();
// iterate over all RoleID's and execute the INSERT statement for each of them
foreach(int roleID in ListOfRoleIDs)
{
cmd.Parameters["#RoleID"].Value = roleID;
cmd.ExecuteNonQuery();
}
conn.Close();
}
let say lstroles is your LIST<ROLES>.
lstroles.ForEach(Role =>
{
/* Your Insert Query like
INSERT INTO REPORT_MARJORIE_ROLE(REPORT_ID, ROLE_ID, CREATED_BY, CREATED)
VALUES(REPORT_ID, Role.ID, {0}, {1}, 'SYSTEM', CURRENT_TIMESTAMP);
Commit you query*\
});
On a personal note: Beware of SQL Injection.
Using C# in Visual Studio, I'm inserting a row into a table like this:
INSERT INTO foo (column_name)
VALUES ('bar')
I want to do something like this, but I don't know the correct syntax:
INSERT INTO foo (column_name)
VALUES ('bar')
RETURNING foo_id
This would return the foo_id column from the newly inserted row.
Furthermore, even if I find the correct syntax for this, I have another problem: I have SqlDataReader and SqlDataAdapter at my disposal. As far as I know, the former is for reading data, the second is for manipulating data. When inserting a row with a return statement, I am both manipulating and reading data, so I'm not sure what to use. Maybe there's something entirely different I should use for this?
SCOPE_IDENTITY returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
You can use SqlCommand.ExecuteScalar to execute the insert command and retrieve the new ID in one query.
using (var con = new SqlConnection(ConnectionString)) {
int newID;
var cmd = "INSERT INTO foo (column_name)VALUES (#Value);SELECT CAST(scope_identity() AS int)";
using (var insertCommand = new SqlCommand(cmd, con)) {
insertCommand.Parameters.AddWithValue("#Value", "bar");
con.Open();
newID = (int)insertCommand.ExecuteScalar();
}
}
try this:
INSERT INTO foo (column_name)
OUTPUT INSERTED.column_name,column_name,...
VALUES ('bar')
OUTPUT can return a result set (among other things), see: OUTPUT Clause (Transact-SQL). Also, if you insert multiple values (INSERT SELECT) this method will return one row per inserted row, where other methods will only return info on the last row.
working example:
declare #YourTable table (YourID int identity(1,1), YourCol1 varchar(5))
INSERT INTO #YourTable (YourCol1)
OUTPUT INSERTED.YourID
VALUES ('Bar')
OUTPUT:
YourID
-----------
1
(1 row(s) affected)
I think you can use ##IDENTITY for this, but I think there's some special rules/restrictions around it?
using (var con = new SqlConnection("connection string"))
{
con.Open();
string query = "INSERT INTO table (column) VALUES (#value)";
var command = new SqlCommand(query, con);
command.Parameters.Add("#value", value);
command.ExecuteNonQuery();
command.Parameters.Clear();
command.CommandText = "SELECT ##IDENTITY";
int identity = Convert.ToInt32(command.ExecuteScalar());
}
Using C# in Visual Studio, I'm inserting a row into a table like this:
INSERT INTO foo (column_name)
VALUES ('bar')
I want to do something like this, but I don't know the correct syntax:
INSERT INTO foo (column_name)
VALUES ('bar')
RETURNING foo_id
This would return the foo_id column from the newly inserted row.
Furthermore, even if I find the correct syntax for this, I have another problem: I have SqlDataReader and SqlDataAdapter at my disposal. As far as I know, the former is for reading data, the second is for manipulating data. When inserting a row with a return statement, I am both manipulating and reading data, so I'm not sure what to use. Maybe there's something entirely different I should use for this?
SCOPE_IDENTITY returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch. Therefore, two statements are in the same scope if they are in the same stored procedure, function, or batch.
You can use SqlCommand.ExecuteScalar to execute the insert command and retrieve the new ID in one query.
using (var con = new SqlConnection(ConnectionString)) {
int newID;
var cmd = "INSERT INTO foo (column_name)VALUES (#Value);SELECT CAST(scope_identity() AS int)";
using (var insertCommand = new SqlCommand(cmd, con)) {
insertCommand.Parameters.AddWithValue("#Value", "bar");
con.Open();
newID = (int)insertCommand.ExecuteScalar();
}
}
try this:
INSERT INTO foo (column_name)
OUTPUT INSERTED.column_name,column_name,...
VALUES ('bar')
OUTPUT can return a result set (among other things), see: OUTPUT Clause (Transact-SQL). Also, if you insert multiple values (INSERT SELECT) this method will return one row per inserted row, where other methods will only return info on the last row.
working example:
declare #YourTable table (YourID int identity(1,1), YourCol1 varchar(5))
INSERT INTO #YourTable (YourCol1)
OUTPUT INSERTED.YourID
VALUES ('Bar')
OUTPUT:
YourID
-----------
1
(1 row(s) affected)
I think you can use ##IDENTITY for this, but I think there's some special rules/restrictions around it?
using (var con = new SqlConnection("connection string"))
{
con.Open();
string query = "INSERT INTO table (column) VALUES (#value)";
var command = new SqlCommand(query, con);
command.Parameters.Add("#value", value);
command.ExecuteNonQuery();
command.Parameters.Clear();
command.CommandText = "SELECT ##IDENTITY";
int identity = Convert.ToInt32(command.ExecuteScalar());
}