繁体   English   中英

使用外键约束INSERT INTO表

[英]INSERT INTO table with foreign key contraints

我已经阅读了几件事,并提出了以下代码。 我正在使用Access数据库,并通过Visual Studio在C#中编码。

我在这里遇到语法错误。 我试图在Access中创建一个查询来测试这个,但很难创建它。

任何人都可以帮我弄清楚为什么这不起作用?

using(OleDbConnection conn1 = new OleDbConnection(global::InsulationProjectTracker.Properties.Settings.Default.InsulationDB))
{
    using(OleDbCommand command1 = conn1.CreateCommand())
    {
        conn.Open();

        command.CommandText = "INSERT INTO Jobsites (CustomerID, JobsiteName) VALUES ((SELECT Customers.CustomerID FROM Customers WHERE Customers.CustomerName = @cname1 AND Customers.BranchNumber = @bNumber1), @jName1)";
        command.Parameters.Add(new OleDbParameter("@cName1", cboCustomerName.Text));
        command.Parameters.Add(new OleDbParameter("@bNumber1", cboBranch.Text));
        command.Parameters.Add(new OleDbParameter("@jName1", txtJobsiteName.Text));

        command.ExecuteNonQuery();

        conn.Close();
        command.Parameters.Clear();

    }
}

表格设置

分行

PK BranchNumber
分店名称

顾客

PK CustomerID
顾客姓名
FK BranchNumber

工地

PK JobsiteID
JobsiteName
FK CustomerID

编辑***

以下命令不会产生错误,但也不会将数据插入数据库

command.CommandText = "INSERT INTO Jobsites (CustomerID, JobsiteName) SELECT @jName1, c.CustomerID FROM Customers c WHERE c.CustomerName = @cname1 AND c.BranchNumber = @bNumber1";

Access SQL不接受目标表的别名。

例如,这些语句中的任何一个都会触发“INSERT INTO语句中的语法错误”。 ...

INSERT INTO Jobsites j (j.CustomerID, j.JobsiteName) VALUES (1, 'foo');
INSERT INTO Jobsites AS j (j.CustomerID, j.JobsiteName) VALUES (1, 'foo');

没有别名,这个没有错误执行...

INSERT INTO Jobsites (CustomerID, JobsiteName) VALUES (1, 'foo');

为了获得一个查询Access将接受,我认为您可能需要切换到INSERT ... SELECT而不是INSERT ... VALUES ...

command.CommandText = "INSERT INTO Jobsites (CustomerID, JobsiteName) SELECT c.CustomerID, @jName1 FROM Customers AS C WHERE c.CustomerName = @cname1 AND c.BranchNumber = @bNumber1";

所以基本上是@ConradFrix之前建议但没有Jobsites表的别名。

知识管理在评论中提出的答案是正确的。 INSERT INTO查询的目标不可能(并且没有理由)。 相反,它应该是

command.CommandText = "INSERT INTO Jobsites (CustomerID, JobsiteName) VALUES ((SELECT c.CustomerID FROM Customers c WHERE c.CustomerName = @cname1 AND c.BranchNumber = @bNumber1), @jName1)";

好吧,参数名称需要@字符,就像你的查询一样

"INSERT INTO Jobsites j (j.CustomerID, j.JobsiteName) VALUES ((SELECT c.CustomerID FROM Customers c WHERE c.CustomerName = @cname1 AND c.BranchNumber = @bNumber1), @jName1)"

所以你需要改变

command.Parameters.Add(new OleDbParameter("cName1", cboCustomerName.Text));
                                    command.Parameters.Add(new OleDbParameter("bNumber1", cboBranch.Text));
                                    command.Parameters.Add(new OleDbParameter("jName1", txtJobsiteName.Text));

command.Parameters.Add(new OleDbParameter("@cName1", cboCustomerName.Text));
                                    command.Parameters.Add(new OleDbParameter("@bNumber1", cboBranch.Text));
                                    command.Parameters.Add(new OleDbParameter("@jName1", txtJobsiteName.Text));

这部分VALUES ((SELECT c.CustomerID FROM Customers c WHERE c.Customer..是可疑的,因为使用SELECT获取customerID的单个值可能会很棘手,因为多个CustomerID符合您的条件的潜力。

解决此问题的一种方法是将查询重写为

command.CommandText =@"
    INSERT INTO Jobsites j 
      (j.CustomerID, j.JobsiteName) 
    SELECT c.CustomerID ,  @jName1 as Jobsitename 
    FROM Customers c 
    WHERE c.CustomerName = @cname1 AND c.BranchNumber = @bNumber1";

这使用参数作为Jobsitename的常量,但它确实意味着如果返回多个记录,则会插入多个行。

您可以通过添加TOP 1来防止返回多个记录的可能性

您还可以在数据库中查询客户ID,并在更新前检查行计数,如果您获得了多条记录,则抛出异常。 这将需要两次访问数据库,但可能更正确(除非您有一个关于客户名称的唯一索引)

谢谢大家帮忙解决这个问题。 我根据您提供的输入更正了几项内容。

工作代码如下:

using(OleDbCommand command1 = conn1.CreateCommand())
{
    conn.Open();

    command.CommandText = "INSERT INTO Jobsites (JobsiteName, CustomerID) SELECT @jName1, c.CustomerID FROM Customers c WHERE c.CustomerName = @cname1 AND c.BranchNumber = @bNumber1";
    command.Parameters.Add(new OleDbParameter("@jName1", txtJobsiteName.Text));
    command.Parameters.Add(new OleDbParameter("@cName1", cboCustomerName.Text));
    command.Parameters.Add(new OleDbParameter("@bNumber1", cboBranch.Text));

    command.ExecuteNonQuery();

    conn.Close();
    command.Parameters.Clear();


}

主要问题是我需要使用INSERT SELECT和INSERT VALUES。 一旦我改变了这一点,我所要做的就是重新定位参数并确保它们按顺序完成并且代码运行完美。

我还删除了INSERT INTO表中的别名,如此处所述。

非常感谢你们的帮助!

-约瑟夫

暂无
暂无

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

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