繁体   English   中英

通过一个查询插入两个表

[英]Inserting into two tables with one query

我的代码有什么问题,我尝试将两个查询合并为一个。 但是第二个查询不起作用,我已经按照这个链接的答案在一个查询中插入了两个表,但是我认为我的方法不起作用,我的代码中缺少什么吗?

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);

表定义:用于tbladdbook

fBookTitle   varchar
fAuthor      varchar
fEdition     varchar
fBookYr      varchar
fPublication varchar
fAccNo       varchar
fCallNo      varchar
fCategory    varchar
fBarCodeNo   varchar
fCurrentCopies  float

表定义:用于tbltrue

fBookTitle  varchar
fAuthor     varchar
fBarCodeNo  bigint
fTrueCopies bigint

旧的工作代码:

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);

蒂莫船长问我是否能够使用参数进行重写。

这是一个相对容易的操作; 但是,我是为SQL Server写的,与MySql命令可能会有细微的差别,并且我没有用于数据层的cfgotcall方法( 这是Cold Fusion吗? ),所以我只会在ADO中编写它。

在这种情况下,我只是用SQL变量替换了VALUES子句中的所有值,并基本上在前面的@处重用了列名,因此为fBookTitle列分配了值@fBookTitle 然后,我们可以通过Parameters.AddWithValue()方法将这些参数分配给command对象。 对于上述@fBookTitle值,调用将为cmd.Parameters.AddWithValue("@Title", txtTITLE.Text); 我注意到第二个查询中使用的变量都在第一个查询中,但反之则不然。 因此,我将首先构建执行Qry2 ,然后我们只需更改CommandText并添加其他参数即可。 使用参数的一件事是您将需要添加具有正确类型的值,因此需要在数据库中添加作为BigInt的值作为相应的Int64 C#类型。

我能做的是显示如何通过ADO与SQL Server来完成此操作,并且您可以修改需要完成的操作。 如果找不到适用于参数的cfgotcall ,则可以将其更改为与SQL语法几乎相同的MySql一起使用。

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();
}

山本哲也建议将其转换为Stored Procedure

在SQL Server上,这很容易完成,但是我不知道MySql的实现。 抱歉,您将得到我将在查询分析器或SSMS中键入的内容,并且很可能还会将其翻译成MySql。

该过程的语法将非常简单,因为我们要做的就是将其中的两个查询包装在其中。

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

一旦创建了存储过程 ,我们将需要修改原始代码,删除2个INSERT查询,并将其替换为一个调用该过程的命令。 我们还将更改命令类型以反映我们正在运行过程而不是文本命令。

// 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();
}

我的评论

查看实际的语句和代码,这似乎是将书籍添加到各种库中。 有一个Books表( tbladdbook )和另一个Book Book副本( tbltruecopies ),这两个表之间唯一的不同是Copies将反映当前有多少副本,但是Count是不同的类型。 一个是Float ,另一个是BigInt 我的意见是这两个应该属于同一类型,而且我真的认为这些值超过16位的32位整数的容量是不现实的。 不太提及Float和Double仅是近似值。

这是一个相当长的答案,而且我的眼睛老化可能有一两个语法错误。 请原谅我,让我知道任何错误或建议,我们很乐意为您更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM