我必须使用一个交易插入两个表(联系人和患者)。插入到联系表中的工作正常,尽管它将contactID递增2.例如,如果最近添加的行的contactID为25,则此方法将插入一个contactID为27的新行。但是,插入进入患者表什么都没做。患者表仅由两列组成:
patientID INT PRIMARY KEY contactID INT FOREIGN KEY
患者表中的contactID列引用联系人表中的contactID列。由于插入首先进入联系表,我不确定为什么会有任何问题。
public static bool CreatePatient(string lName, string fName, DateTime dob, string streetAddress, string city, string state, string zip, string phone, string gender, string ssn)
{
bool isCreated = false;
int newContactID = 0;
string insertStmt1 = "INSERT INTO contact (lName, fName, dob, mailingAddressStreet, mailingAddressCity, mailingAddressState, mailingAddressZip, phoneNumber, gender, SSN, userType) " +
"VALUES (@last, @first, @dob, @street, @city, @state, @zip, @phone, @gender, @ssn, 4)";
string selStmt = "SELECT MAX(contactID) AS MaxContactID FROM contact";
string insertStmt2 = "INSERT INTO patient (contactID) VALUES (@contact);";
using (SqlConnection connect = DBConnection.GetConnection())
{
connect.Open();
SqlTransaction tran = connect.BeginTransaction();
try
{
using (SqlCommand cmd = new SqlCommand(insertStmt1, connect, tran))
{
cmd.Parameters.AddWithValue("@last", lName);
cmd.Parameters.AddWithValue("@first", fName);
cmd.Parameters.AddWithValue("@dob", dob);
cmd.Parameters.AddWithValue("@street", streetAddress);
cmd.Parameters.AddWithValue("@city", city);
cmd.Parameters.AddWithValue("@state", state);
cmd.Parameters.AddWithValue("@zip", zip);
cmd.Parameters.AddWithValue("@phone", phone);
cmd.Parameters.AddWithValue("@gender", gender);
cmd.Parameters.AddWithValue("@ssn", ssn);
cmd.ExecuteNonQuery();
}
using (SqlCommand cmd = new SqlCommand(selStmt, connect, tran))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read())
{
newContactID = (int)reader["MaxContactID"];
}
}
}
if (newContactID > 0)
{
using (SqlCommand cmd = new SqlCommand(insertStmt2, connect, tran))
{
cmd.Parameters.AddWithValue("@contact", newContactID);
cmd.ExecuteNonQuery();
}
}
isCreated = true;
tran.Commit();
connect.Close();
}
catch
{
tran.Rollback();
return false;
}
}
return isCreated;
}
public static List<Patient> SearchPatientByFirstAndLastName(string fName, string lName)
{
List<Patient> patientList = new List<Patient>();
string selectStatement = "SELECT * FROM contact INNER JOIN patient ON contact.contactID = patient.contactID "
+ "WHERE contact.fName LIKE '%'+@fName+'%' AND contact.lName LIKE '%'+@lName+'%'";
try
{
using (SqlConnection connection = DBConnection.GetConnection())
{
connection.Open();
using (SqlCommand selectCommand = new SqlCommand(selectStatement, connection))
{
selectCommand.Parameters.AddWithValue("@fName", fName);
selectCommand.Parameters.AddWithValue("@lName", lName);
using (SqlDataReader reader = selectCommand.ExecuteReader())
{
while (reader.Read())
{
Patient patient = new Patient();
patient.PatientID = (int)reader["patientID"];
patient.ContactID = (int)reader["contactID"];
patient.LastName = reader["lName"].ToString();
patient.FirstName = reader["fName"].ToString();
patient.Dob = (DateTime)reader["dob"];
patient.Address = reader["mailingAddressStreet"].ToString();
patient.City = reader["mailingAddressCity"].ToString();
patient.State = reader["mailingAddressState"].ToString();
patient.Zip = reader["mailingAddressZip"].ToString();
patient.Phone = reader["phoneNumber"].ToString();
patient.Gender = reader["gender"].ToString();
patient.Ssn = reader["ssn"].ToString();
patientList.Add(patient);
}
reader.Close();
}
}
connection.Close();
}
}
catch (SqlException ex)
{
throw;
}
catch (Exception ex)
{
throw;
}
return patientList;
}
修改
我现在正在尝试不同的方法。我没有在程序中处理这一切,而是按如下方式创建了一个存储过程:
CREATE PROCEDURE [dbo].[uspCreatePatient] @last VARCHAR(45), @first VARCHAR(45), @dob DATE, @street VARCHAR(100), @city VARCHAR(100), @state CHAR(2), @zip CHAR(5),
@phone VARCHAR(20), @gender CHAR(1), @ssn CHAR(9), @isCreated BIT OUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @contact INT;
BEGIN TRAN
BEGIN TRY
INSERT INTO contact (lName, fName, dob, mailingAddressStreet, mailingAddressCity, mailingAddressState, mailingAddressZip, phoneNumber, gender, SSN, userType)
VALUES (@last, @first, @dob, @street, @city, @state, @zip, @phone, @gender, @ssn, 4);
SET @contact = SCOPE_IDENTITY();
INSERT INTO patient (contactID) VALUES (@contact)
COMMIT TRAN
SET @isCreated = 1;
END TRY
BEGIN CATCH
ROLLBACK TRAN
SET @isCreated = 0;
END CATCH
END
然后我在C#中更新了CreatePatient方法,如下所示:
public static bool CreatePatient(string lastName, string firstName, DateTime dob, string streetAddress, string city, string state, string zip, string phone, string gender, string ssn)
{
int result = 0;
bool isCreated = false;
using (SqlConnection connect = DBConnection.GetConnection())
{
using (SqlCommand cmd = new SqlCommand("uspCreatePatient", connect))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@last", lastName);
cmd.Parameters.AddWithValue("@first", firstName);
cmd.Parameters.AddWithValue("@dob", dob);
cmd.Parameters.AddWithValue("@street", streetAddress);
cmd.Parameters.AddWithValue("@city", city);
cmd.Parameters.AddWithValue("@state", state);
cmd.Parameters.AddWithValue("@zip", zip);
cmd.Parameters.AddWithValue("@phone", phone);
cmd.Parameters.AddWithValue("@gender", gender);
cmd.Parameters.AddWithValue("@ssn", ssn);
result = cmd.ExecuteNonQuery();
}
}
if (result == 1)
{
isCreated = true;
}
return isCreated;
}
然而,同样的问题正在发生。仅更新联系表。当我在SQL Server中使用硬编码值运行这些相同的命令时,两个表都会像我想要的那样更新。