Order query and OrderDetail - asp.net

Order Table
OrderId
CustomerId
Date
Total
OrderDetails
OrderDetailId
OrderId
ProductId
Quantity
UnitPrice
i am using Order query
INSERT INTO dbo.Orders (CustomerId, Date, Total)
VALUES (1, 2011-04-10, 50000);
I am executing OrderDetail query many times.
DECLARE #OrderID int
SET #OrderID = SCOPE_IDENTITY()
INSERT INTO dbo.OrderDetail (OrderId,ProductDescriptionId,Quantity,UnitPrice)
VALUES (#OrderID,11,2,50000)
The problem here is that the value of #OrderID changes, and no longer matches the foreign key from the Orders table after i execute this query for the second time. so what should i do to fix this?

I. You have to use the same connection to:
Insert the Order:
INSERT INTO dbo.Orders (CustomerId, Date, Total)
VALUES (1, 2011-04-10, 50000);
Retrieve SCOPE_IDENTITY() and store it in some place in your code (you havn't supplied the .NET code, so I could give you more precise advice) :
command.CommandText = "SELECT SCOPE_IDENTITY()";
int lastOrderId = (int)command.ExecuteScalar();
II. Then (same connection or not):
Insert OrderDetails using:
-- concatenation:
"INSERT INTO dbo.OrderDetail (OrderId,ProductDescriptionId,Quantity,UnitPrice)
VALUES ('" + lastOrderId.ToString() + "',11,2,50000)"
-- or Parameters:
command.Parameters.Add("#OrderID", SqlDbType.Int);
command.Parameters("#OrderID").Value = lastOrderId;
INSERT INTO dbo.OrderDetail (OrderId,ProductDescriptionId,Quantity,UnitPrice)
VALUES (#OrderID,11,2,50000)

If your order detail as an identity field, then when you call INSERT INTO dbo.OrderDetail it's going to change SCOPE_IDENTITY. You'd need to set or #OrderID once for each Order entry and not call SCOPE_IDENTITY again until you've added another column to your Orders table.
--Run this once per order
INSERT INTO dbo.Orders (CustomerId, Date, Total)
VALUES (1, 2011-04-10, 50000);
--Run this once per order
DECLARE #OrderID int
SET #OrderID = SCOPE_IDENTITY()
--Run this once per orderdetail
INSERT INTO dbo.OrderDetail (OrderId,ProductDescriptionId,Quantity,UnitPrice)
VALUES (#OrderID,11,2,50000)

Related

Sqlite INSERTION optimization

Good day SO,
I'm working on a program in PowerShell to manipulate an SQLite DB I created. I've never written a serious applications to utilize a DB so right now I'm super interested in optimizing my querys, so I'm really interested in feed back. My primary issue is I have a lot of data that I want to include in a separate table that may or not exist already. All my research really seemed to lead to perform an INSERT and let the UNIQUE constraints sort it out, than do a select on the new record which seemed like two table scans and inefficient. So my solution was Create a temp table, insert into the temp table FROM the table with data I want and perform an INSERT if the data was not in the temporary table. I'm a few drinks in tonight and haven't tested the code so please don't critique small typos, I just want to know if my methodology is out to lunch, and if so please provide better direction.
My table is as shown:
CREATE TABLE Processes (
pk INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE,
hostname INTEGER NOT NULL,
artifacttype INTEGER REFERENCES ArtifactType (pk),
processname INTEGER REFERENCES ProcessesName (pk),
filelocation INTEGER NOT NULL
REFERENCES files (pk),
pid INTEGER,
ppid INTEGER,
starttime INTEGER,
stoptime INTEGER,
token STRING,
logonid INTEGER,
exitstatus INTEGER,
threadcount INTEGER,
commandline INTEGER REFERENCES ProcessesCommandline (pk),
user INTEGER REFERENCES users (pk),
PeakVirtualSize INTEGER,
VirtualSize INTEGER,
PeakWorkingSetSize INTEGER,
suspicious BOOLEAN,
malicious BOOLEAN
);
Transaction:
#"
CREATE TEMPORARY TABLE IF NOT EXISTS Results(pk INTEGER, data TEXT);
INSERT INTO Results(pk, data) VALUES ((SELECT pk, name FROM ProcessesName WHERE name = #processname));
INSERT INTO ProcessesName(name) VALUES (SELECT #processname WHERE NOT EXISTS (SELECT pk FROM Results WHERE data = #processname));
INSERT INTO Results (pk, data) VALUES ((SELECT last_insert_row_id, #processname WHERE NOT EXISTS (SELECT pk FROM Results WHERE data =#processname)));
INSERT INTO Results(pk, data) VALUES ((SELECT pk, file FROM Files WHERE file = #filelocation));
INSERT INTO Files(file) VALUES (SELECT #filelocation WHERE NOT EXISTS (SELECT pk FROM Results WHERE data = #filelocation));
INSERT INTO Results (pk, data) VALUES ((SELECT last_insert_row_id, #filelocation WHERE NOT EXISTS (SELECT pk FROM Results WHERE data =#filelocation)));
INSERT INTO Results(pk, data) VALUES ((SELECT pk, commandline FROM ProcessesCommandline WHERE commandline = #commandline));
INSERT INTO ProcesseCommandline(commandline) VALUES (SELECT #commandline WHERE NOT EXISTS (SELECT pk FROM Results WHERE data = #commandline));
INSERT INTO Results (pk, data) VALUES ((SELECT last_insert_row_id, #filelocation WHERE NOT EXISTS (SELECT pk FROM Results WHERE data =#commandline)));
INSERT INTO Results(pk, data) VALUES ((SELECT pk, SID FROM Users WHERE SID = #SID));
INSERT INTO Users(SID) VALUES (SELECT #SID WHERE NOT EXISTS (SELECT pk FROM Results WHERE data = #filelocation));
INSERT INTO Results (pk, data) VALUES ((SELECT last_insert_row_id, #SID WHERE NOT EXISTS (SELECT pk FROM Results WHERE data =#SID)));
INSERT INTO processes(hostname, artifacttype, processname, filelocation, pid, ppid, starttime, threadcount, commandline, user, PeakVirtualSize, VirtualSize, PeakWorkingSetSize)
VALUES (#hostname, #artifacttype, (SELECT pk FROM Results WHERE data = #processname), (SELECT pk FROM Results WHERE data #filelocation), #pid, #ppid, #starttime, #threadcount, (SELECT pk FROM Results where data = #commandline), SELECT pk FROM Results WHERE data = #SID, #PeakVirtualSize, #VirtualSize, #PeakWorkingSetSize);
DROP TABLE Results;
"#
*there are a few foreign keys where the data is being tracked application side so no complex queries are required.
So my core question is, is there a more efficient way to do this?
Thanks guys!

JDBC - SQLITE Select to variable

I am trying to run a query / select statement and save it in a variable. I know how to get something specific from a specific column but not from counting rows.
This is working as I getting MYID specifically.
ResultSet MYIDrs = stmtCFG.executeQuery( "SELECT rowid, MYID from MYINDEX order by rowid desc limit 1;" );
MYID = MYIDrs.getString("MYID");
Now I am trying to count the rows that works in SQLite client but not in the jdbc as I can't figure out what to request.
this is what I have but is not resulting in what I am expecting.
ResultSet FILE_COUNTrs = stmtCFG.executeQuery( "SELECT count(*) from TABLE where MYID = '"+MYID+"';");
FILE_COUNT = FILE_COUNTrs.getString(?????);
problem or question is: What do I put in the ????? as I already tried everything.
I am expecting to see a number.
I am really sorry I found what I was looking for by assigning a name TOTAL
This is my code and it works...
ResultSet FILE_COUNTrs = stmtCFG.executeQuery( "SELECT count(*) AS TOTAL from TABLE where MYID = '"+MYID+"';");
FILE_COUNT = FILE_COUNTrs.getString("TOTAL");
You use wrong data type. COUNT(*) returns Integer type, Not String.
You can do like this without assigning a label for COUNT(*)
int FILE_COUNT = FILE_COUNTrs.getInt(1); // 1: is the column index of COUNT(*)

Retrieving id from a row that I've just written to the database

How can I retrieve an id from a row that I've just written to the database?
Basically, I have a function in my ASP.NET a booking form that needs to write to two tables, but I need the id from what's been written in table 1, to also be store in table 2.
So:
write to table 1
retrieve id from table 1
write to table 2
How can I achieve this?
Regards
Tea
In Asp.Net with a Sql 2008 server, you can use the ExecuteScalar function like this:
string query = "INSERT INTO Table1 (id_field)
OUTPUT SCOPE_IDENTITY()
VALUES (...)";
OR
string query = "INSERT INTO Table1 (...) VALUES (...); SELECT SCOPE_IDENTITY() ";
In the last example, notice I'm performing an INSERT and then a SELECT in the same request...
And to get the identity use:
int lastId = (int)command.ExecuteScalar();
If you're using SQL Server use SCOPE_IDENTITY()
http://msdn.microsoft.com/en-us/library/ms190315.aspx
INSERT INTO Table1 ...
DECLARE #RecordID int = SCOPE_IDENTITY()
INSERT INTO Table2 ... VALUES (#RecordID....)
Without using stored procedures, you could attach a SELECT statement to the end of your SQL:
cmd.CommandText = "INSERT INTO Table 1 ...... ; SELECT SCOPE_IDENTITY()"
int recordId = (int)cmd.ExecuteScalar();

Create new sql entry with one value being MAX(Column)+1 gives Invalid use of group function

I want to manually create a ID field where I do MAX + 1, and I want to do it in one QUERY so I am certain 2 entries cant get the same field.
using (MySqlConnection dbConn = new MySqlConnection(ConfigurationManager.ConnectionStrings["ProjektConStr"].ConnectionString))
{
dbConn.Open();
using (MySqlCommand cmd = new MySqlCommand("INSERT INTO Submission (CaseId , SubjectId, CenterId, EmployeeName, Reason, Description, Explanation, Date, Done, ChiefLevel) VALUES (MAX(CaseId)+1, #subject_id, #center_id, #employee_name, #reason, #description, #explanation, #date, #done, #chief)", dbConn))
{
cmd.Parameters.AddWithValue("date", submission.Date);
cmd.Parameters.AddWithValue("subject_id", submission.SubjectId);
cmd.Parameters.AddWithValue("center_id", submission.CenterId);
cmd.Parameters.AddWithValue("employee_name", submission.EmployeeName);
cmd.Parameters.AddWithValue("reason", submission.Reason);
cmd.Parameters.AddWithValue("description", submission.Description);
cmd.Parameters.AddWithValue("explanation", submission.Explanation);
cmd.Parameters.AddWithValue("done", false);
cmd.Parameters.AddWithValue("chief", false);
cmd.ExecuteNonQuery();
}
}
Use subquery to select max and insert a value
INSERT INTO Submission (CaseId , SubjectId, CenterId, EmployeeName, Reason, Description, Explanation, Date, Done, ChiefLevel) VALUES (
(1 + coalesce((SELECT max(CaseId) FROM Submission), 0))
, #subject_id, #center_id, #employee_name, #reason, #description, #explanation, #date, #done, #chief)
using (MySqlCommand cmd = new MySqlCommand("INSERT INTO Submission
(CaseId , SubjectId, CenterId, EmployeeName, Reason, Description, Explanation,
Date, Done, ChiefLevel)
VALUES ((select MAX(CaseId)+1 from YourTable),
#subject_id, #center_id, #employee_name, #reason, #description, #explanation,
#date, #done, #chief)", dbConn))
You cannot do this in a single query, Either you have to fetch the MAX_id and then increment that, and insert or You can make the table as autoincrement, Here you dont have to include the id in the insert query.

Read last Inserted row in Sql according to its Time stamp

sql has a Table called emp.
emp(emp_id int IDENTITY primary key, EmployeeName varchar(50),.......)
I want to Insert a record to above table. Here is my code in asp.net.
DBconnection dbcon = new DBconnection();
string query = "insert into emp values('" + TextBox_EmpName.Text + "','" + ....);
int no1 = dbcon.insertQuery(query);
I have another table called emp-relation
emp-relation(emp_id int primary key, count int, ....)
-- foreign key (emp_id)references emp(emp_id)
My problem is when I inserting the emp row ,I dont know what is the emp_id since it created by auto. And when I am going to insert to emp-relation , I want to get emp-id since it is the foreign key.
How can I do this? Is there any way to read last Insert row in Sql according to Time stamp or some thing? I believe that records are not sorted according to inserted timestamp in nature. please help me.
There's bascally two ways. The first way is to return the new ID from the first insert query:
insert into emp values(...)
select scope_identity() as NewID
The second way is to lookup the first row when you insert into the relation table:
insert emp-relation
(emp_idm, ...)
select emp_id
, ...
from emp
where emp_name = #EmpName
You have to pass in enough columns to make the reference unique.

Resources