如何解决SqlException: 插入语句与外键约束冲突
我正在尝试向数据库中的两个表添加值,一个包含主键,另一个是纯外键。我试过先用主键再用外键添加到表中,但无济于事。
表单上执行插入命令的代码:
public static int AddBooking(int DogID,int ClientID)
{
using (sqlConnection connection = new sqlConnection(_connectionstring))
{
connection.open();
sqlCommand insertClientCommand = new sqlCommand();
insertClientCommand.Connection = connection;
insertClientCommand.CommandType = System.Data.CommandType.StoredProcedure;
insertClientCommand.CommandText = "AddBooking";
insertClientCommand.Parameters.Add(new sqlParameter("@DogID",DogID));
insertClientCommand.Parameters.Add(new sqlParameter("@ClientID",ClientID));
int rowsAffected = insertClientCommand.ExecuteNonQuery();
connection.Close();
return rowsAffected;
}
}
public static int AddBookingInfo(string GroomOption,string Hair,string Teeth,string Nails,string DateOfAppointment,string IsFirstTime,string StartTime,string FinishTime,string Duration,double Price)
{
using (sqlConnection connection = new sqlConnection(_connectionstring))
{
connection.open();
sqlCommand insertClientCommand = new sqlCommand();
insertClientCommand.Connection = connection;
insertClientCommand.CommandType = System.Data.CommandType.StoredProcedure;
insertClientCommand.CommandText = "AddBookingInfo";
insertClientCommand.Parameters.Add(new sqlParameter("@GroomOption",GroomOption));
insertClientCommand.Parameters.Add(new sqlParameter("@Hair",Hair));
insertClientCommand.Parameters.Add(new sqlParameter("@Teeth",Teeth));
insertClientCommand.Parameters.Add(new sqlParameter("@Nails",Nails));
insertClientCommand.Parameters.Add(new sqlParameter("@DateOfAppointment",DateOfAppointment));
insertClientCommand.Parameters.Add(new sqlParameter("@IsFirstTime",IsFirstTime));
insertClientCommand.Parameters.Add(new sqlParameter("@StartTime",StartTime));
insertClientCommand.Parameters.Add(new sqlParameter("@FinishTime",FinishTime));
insertClientCommand.Parameters.Add(new sqlParameter("@Duration",Duration));
insertClientCommand.Parameters.Add(new sqlParameter("@Price",Price));
int rowsAffected = insertClientCommand.ExecuteNonQuery();
connection.Close();
return rowsAffected;
}
}
ProjectDal 中的代码:
CREATE TABLE [dbo].[BookingInfo]
(
[BookingID] INT IDENTITY (101,1) NOT NULL,[GroomOption] NCHAR(10) NULL,[Hair] NCHAR(10) NULL,[Teeth] NCHAR(10) NULL,[Nails] NCHAR(10) NULL,[DateOfAppointment] NVARCHAR(50) NULL,[IsFirstTime] NCHAR(10) NULL,[StartTime] NCHAR(10) NULL,[FinishTime] NCHAR(10) NULL,[Duration] NCHAR(10) NULL,[Price] FLOAT(53) NULL,PRIMARY KEY CLUSTERED ([BookingID] ASC)
)
CREATE TABLE [dbo].[Booking]
(
[BookingID] INT IDENTITY (101,[DogID] INT NOT NULL,[ClientID] INT NOT NULL,PRIMARY KEY CLUSTERED ([BookingID] ASC),CONSTRAINT [FK_Booking_TodogInfo]
FOREIGN KEY ([DogID]) REFERENCES [dbo].[DogInfo] ([DogID]),CONSTRAINT [FK_Booking_ToOwner]
FOREIGN KEY ([ClientID]) REFERENCES [dbo].[Owner] ([ClientID]),CONSTRAINT [FK_Booking_ToBookingInfo]
FOREIGN KEY ([BookingID]) REFERENCES [dbo].[BookingInfo]([BookingID])
)
两个表的 sql:
$filemanagerToken = '123456';
$this->data['scripts_admin'] = '
<!-- Scripts Admin -->
<script src="//cdn.ckeditor.com/4.16.0/full/ckeditor.js"></script>
<script src="'.base_url().'/assets/admin/post/js/post_editor.js">
var fmKey = '.json_encode($filemanagerToken).';
</script>';
解决方法
您的代码有很多问题:
-
Booking
不应该是IDENTITY
列,也不应该是主键(至少不是它本身),因为它只接受来自BookingInfo
。您可能希望将其设为具有另一列的主键。 - 因此您需要从
BookingInfo
插入返回 ID,然后传递到另一个插入。
BookingID
表上的 其他注意事项:
- 仔细选择您的数据类型:
nchar
是固定长度并且会填充空格,使用nvarchar
代替可变长度。日期应位于date
或datetime
列中。布尔值应该放在bit
列中。任何涉及金钱的东西都需要在decimal
而不是float
。 - 指定参数类型、长度和精度
- 将
SqlCommand
放入using
块
您的 SQL 代码将如下所示:
CREATE OR ALTER PROCEDURE AddBookingInfo
@GroomOption NCHAR(10)
.....
@BookingInfoID int OUTPUT
AS
INSERT BookingInfo
(GroomOption,....)
VALUES (@GroomOption,...);
SELECT CAST(SCOPE_IDENTITY() AS int);
GO
您的 C# 方面将如下所示:
public static int AddBookingInfo(string GroomOption,string Hair,string Teeth,string Nails,string DateOfAppointment,string IsFirstTime,string StartTime,string FinishTime,string Duration,double Price)
{
using (SqlConnection connection = new SqlConnection(_connectionstring))
using (SqlCommand insertClientCommand = new SqlCommand("AddBookingInfo",connection))
{
insertClientCommand.CommandType = System.Data.CommandType.StoredProcedure;
insertClientCommand.Parameters.Add("@GroomOption",SqlDbType.VarChar,10).Value = GroomOption;
// ......... etc
connection.Open();
return (int)insertClientCommand.ExecuteScalar(); // the result is the ID
}
}
public static int AddBooking(int BookingInfoId,int DogID,int ClientID)
{
using (SqlConnection connection = new SqlConnection(_connectionstring))
using (SqlCommand insertClientCommand = new SqlCommand("AddBooking",connection))
{
insertClientCommand.CommandType = System.Data.CommandType.StoredProcedure;
insertClientCommand.Parameters.Add("@BookingInfoID",SqlDbType.Int).Value = BookingInfoId;
insertClientCommand.Parameters.Add("@DogID",SqlDbType.Int).Value = DogID;
insertClientCommand.Parameters.Add("@ClientID",SqlDbType.Int).Value = ClientID;
connection.Open();
int rowsAffected = insertClientCommand.ExecuteNonQuery();
connection.Close();
return rowsAffected;
}
}
老实说,您的数据模型似乎有些可疑:Booking
和 BookingInfo
之间有什么区别,它们代表不同的概念还是应该在同一个表中?
另外,Duration
应该是一个计算列,因为它可以从其他列中计算出来,并且当您真正想要数据在那里时,您不应该将列声明为 NULL
。>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。