What's wrong with my code, i tried to combine two query into one. But the second query is not working, i already follow the answer of this link INSERT INTO two tables at one query but i think mine doesn't work, am i missing something in my code?
string sql = "INSERT INTO tbladdbook(fBookTitle,fAuthor,fBookYr,fEdition,fPublication,fAccNo,fCallNo,fCategory,fBarCodeNo,fCurrentCopies) VALUES('"
+ txtTITLE.Text + "','"
+ txTAUTHOR.Text + "','"
+ txtBOOKYR.Text + "','"
+ txtEDITION.Text + "','"
+ txtPUBLICATION.Text + "','"
+ txtACCESSNO.Text + "','"
+ txtCALLNO.Text + "','"
+ txtCATEGORY.SelectedItem + "','"
+ txtBARCODE.Text + "','"
+ txtCOPIES.Text + "'); INSERT INTO tbltruecopies(fBookTitle,fAuthor,fBarCodeNo,fTrueCopies) VALUES('"
+ txtTITLE.Text + "','"
+ txTAUTHOR.Text + "','"
+ txtBARCODE.Text + "','"
+ txtCOPIES.Text + "')";
cfgotcall.inputQ(sql);
Table definition: for tbladdbook
fBookTitle varchar
fAuthor varchar
fEdition varchar
fBookYr varchar
fPublication varchar
fAccNo varchar
fCallNo varchar
fCategory varchar
fBarCodeNo varchar
fCurrentCopies float
Table definition: for tbltrue
fBookTitle varchar
fAuthor varchar
fBarCodeNo bigint
fTrueCopies bigint
Old and working code:
string sql = "INSERT INTO tbladdbook(fBookTitle,fAuthor,fBookYr,fEdition,fPublication,fAccNo,fCallNo,fCategory,fBarCodeNo,fCurrentCopies) VALUES('"
+ txtTITLE.Text + "','"
+ txTAUTHOR.Text + "','"
+ txtBOOKYR.Text + "','"
+ txtEDITION.Text + "','"
+ txtPUBLICATION.Text + "','"
+ txtACCESSNO.Text + "','"
+ txtCALLNO.Text + "','"
+ txtCATEGORY.SelectedItem + "','"
+ txtBARCODE.Text + "','"
+ txtCOPIES.Text + "')";
cfgotcall.inputQ(sql);
sql = "INSERT INTO tbltruecopies(fBookTitle,fAuthor,fBarCodeNo,fTrueCopies) VALUES('"
+ txtTITLE.Text + "','"
+ txTAUTHOR.Text + "','"
+ txtBARCODE.Text + "','"
+ txtCOPIES.Text + "')";
cfgotcall.inputQ(sql);
Captain Teemo asked if I was able to rewrite using parameters.
This is a relatively easy operation; however, I write for SQL Server and there may be slight differences with the MySql commands and I do not the cfgotcall
methods ( is this Cold Fusion? ) that are being used for the Data Layer, so I will just write this in ADO.
In this case I simply replaced all of the values in the VALUES
clause with SQL Variables, and basically reused the column names with a preceding @, so the column fBookTitle
is assigned the value @fBookTitle
. Then we can assign those parameters to the command
object via the Parameters.AddWithValue()
method. For the above @fBookTitle value the call would be cmd.Parameters.AddWithValue("@Title", txtTITLE.Text);
I noticed that the variables being used in the second query were all in the first query, but not vice versa; so I am going to build up execute Qry2
first, then we can simply change the CommandText
and add in the additional parameters. One of the things with using parameters is that you will need to add the values with the correct type, so adding in a value that is a BigInt in the database will need to be added in as the corresponding C# type of Int64.
What I can do is show how this would be done via ADO
with SQL Server, and you can modify what needs to be done. If you can't find a cfgotcall
that works with parameters then you could just change this for use with MySql which has nearly identical syntax to the SQL Server syntax.
string Qry1 = "INSERT INTO tbladdbook(fBookTitle,fAuthor,fBookYr,fEdition,fPublication,fAccNo,fCallNo,fCategory,fBarCodeNo,fCurrentCopies) VALUES (@Title, @Author, @BookYr, @Edition, @Publication, @AccNo, @CallNo, @Category, @BarCode, @Copies)";
string Qry2 = "INSERT INTO tbltruecopies(fBookTitle, fAuthor, fBarCodeNo, fTrueCopies) VALUES (@Title, @Author, @Barcode, @Copies)";
using (SqlConnection conn = new SqlConnection(connectionstring)) {
conn.Open();
using (SqlCommand cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = Qry2;
cmd.Parameters.AddWithValue("@Title", txtTITLE.Text);
cmd.Parameters.AddWithValue("@Author", txTAUTHOR.Text);
cmd.Parameters.AddWithValue("@Barcode", Int64.parse(txtBARCODE.Text));
cmd.Parameters.AddWithValue("@Copies", Int64.parse(txtCOPIES.Text));
try { cmd.ExecuteNonQuery(); }
catch (Exception) { /* your error handling */ }
cmd.CommandText = Qry1;
cmd.Parameters.AddWithValue("@BookYr", txtBOOKYR.Text);
cmd.Parameters.AddWithValue("@Edition", txtEDITION.Text);
cmd.Parameters.AddWithValue("@Publication", txtPUBLICATION.Text);
cmd.Parameters.AddWithValue("@AccNo", txtACCESSNO.Text);
cmd.Parameters.AddWithValue("@CallNo", txtCALLNO.Text);
cmd.Parameters.AddWithValue("@Category", txtCATEGORY.SelectedItem);
try { cmd.ExecuteNonQuery(); }
catch (Exception) { /* your error handling */ }
}
conn.Close();
}
Tetsuya Yamamoto suggests that this be converted over to a
Stored Procedure
This is an easy enough task on SQL Server, but I do not know the MySql implementation; sorry you are going to get what I would be typing in Query Analyzer or SSMS, and this would most likely to be translated for MySql as well.
The syntax for this procedure is going to be rather simple, as all we are going to do is wrap the 2 queries within it.
CREATE PROCEDURE usp_addBookAndCopies (
@Title VARCHAR(100),
@Author VARCHAR(100),
@BookYr VARCHAR(100),
@Edition VARCHAR(100),
@Publication VARCHAR(100),
@AccNo VARCHAR(100),
@CallNo VARCHAR(100),
@Category VARCHAR(100),
@BarCode BIGINT,
@Copies BIGINT
) AS
BEGIN
INSERT tbladdbook ( fBookTitle, fAuthor, fBookYr, fEdition, fPublication,
fAccNo, fCallNo, fCategory, fBarCodeNo, fCurrentCopies )
VALUES (@Title, @Author, @BookYr, @Edition, @Publication,
@AccNo, @CallNo, @Category, @BarCode, @Copies )
INSERT tbltruecopies ( fBookTitle, fAuthor, fBarCodeNo, fTrueCopies)
VALUES (@Title, @Author, @Barcode, @Copies)
END
GO
Once we have the Stored Procedure created, we would need to modify the original code, removing the 2 INSERT queries and replace them with the one command calling the procedure. We would also change the command type to reflect that we are running a procedure instead of a text command.
// Not Needed: string Qry1 = "INSERT INTO tbladdbook..."
// Not Needed: string Qry2 = "INSERT INTO tbltruecopies..."
using (SqlConnection conn = new SqlConnection(connectionstring)) {
conn.Open();
using (SqlCommand cmd = new SqlCommand()) {
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure; // Changed
cmd.CommandText = "usp_addBookAndCopies"; // Changed
cmd.Parameters.AddWithValue("@Title", txtTITLE.Text);
cmd.Parameters.AddWithValue("@Author", txTAUTHOR.Text);
cmd.Parameters.AddWithValue("@Barcode", Int64.parse(txtBARCODE.Text));
cmd.Parameters.AddWithValue("@Copies", Int64.parse(txtCOPIES.Text));
cmd.Parameters.AddWithValue("@BookYr", txtBOOKYR.Text);
cmd.Parameters.AddWithValue("@Edition", txtEDITION.Text);
cmd.Parameters.AddWithValue("@Publication", txtPUBLICATION.Text);
cmd.Parameters.AddWithValue("@AccNo", txtACCESSNO.Text);
cmd.Parameters.AddWithValue("@CallNo", txtCALLNO.Text);
cmd.Parameters.AddWithValue("@Category", txtCATEGORY.SelectedItem);
try { cmd.ExecuteNonQuery(); }
catch (Exception) { /* your error handling */ }
}
conn.Close();
}
My Comments
Looking at the actual statements and the code this appears to be adding books to a library of sorts. There is a table of Books ( tbladdbook ) and another for Book Copies ( tbltruecopies ), and the only thing different between the two tables is that Copies would reflect how many copies are currently on hand, but the Count is of dissimilar types; one being Float
and the other as BigInt
. My opinion would be that these two should be of the same type, and I really don't think it is realistic that these values would ever exceed the capacity of a 32 bit integer, if not 16 bit. Not too mention that Float and Double are only approximations.
This a rather long answer, and my aging eyes may have a syntax error or two. Please forgive me and let me know of any errors or suggestions, I will be happy to update this for you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.