Нет необходимости в явной транзакции в вашем текущем коде; одна транзакция автоматического подтверждения оператора предоставит все-ничего и вызовет ошибку по умолчанию. В этом случае T-SQL TRY / CATCH не предоставляет значения, поэтому вы можете просто использовать:
ALTER PROCEDURE [dbo].[addPacient]
@name NVARCHAR(20),
@surname NVARCHAR(20),
@middle NVARCHAR(20),
@passport NCHAR(10),
@address NVARCHAR(20),
@age INT,
@name_diagnoz NVARCHAR(30),
@stage CHAR(1)
AS
INSERT INTO Pacient(Name, Surname, Middle_name, Column__Passport,
Legal_address_Clinic, Age, id_diagnoz)
VALUES (@name, @surname, @middle, @passport,
@address, @age,
(SELECT id_diagnoz FROM Diagnoz
WHERE Name_diagnoz = @name_diagnoz and Stage = @stage));
GO
Если у вас есть несколько операторов, которые выполняют модификации данных в явной транзакции T-SQL, убедитесь, что вы включили SET XACT_ABORT ON
в коде proc, чтобы обеспечить автоматический откат транзакции в случае тайм-аута клиента (где блок CATCH не выполнит). Я предлагаю этот шаблон обработки ошибок в процедурах с несколькими утверждениями:
ALTER PROCEDURE [dbo].[addPacient]
@name NVARCHAR(20),
@surname NVARCHAR(20),
@middle NVARCHAR(20),
@passport NCHAR(10),
@address NVARCHAR(20),
@age INT,
@name_diagnoz NVARCHAR(30),
@stage CHAR(1)
AS
SET XACT_ABORT ON;
BEGIN TRY
BEGIN TRAN;
INSERT INTO Pacient(Name, Surname, Middle_name, Column__Passport,
Legal_address_Clinic, Age, id_diagnoz)
VALUES (@name, @surname, @middle, @passport,
@address, @age,
(SELECT id_diagnoz FROM Diagnoz
WHERE Name_diagnoz = @name_diagnoz and Stage = @stage));
--other data modification statements
COMMIT;
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK;
THROW;
END CATCH;
GO
Кроме того, лучше избегать AddWithValue
и передавать строго типизированные параметры. Это улучшит повторное использование кэша на стороне сервера, а также предоставит другие преимущества .
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand("addPacient", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("@name", SqlDbType.NVarChar, 20).Value = txtName.Text;
command.Parameters.Add("@surname", SqlDbType.NVarChar, 20).Value = txtSurname.Text;
command.Parameters.Add("@middle", SqlDbType.NVarChar, 20).Value = txtMiddle.Text;
command.Parameters.Add("@passport", SqlDbType.NChar, 10).Value = mskPassport.Text;
command.Parameters.Add("@address", SqlDbType.NVarChar, 20).Value = cbAddres.Text;
command.Parameters.Add("@age", SqlDbType.Int, 20).Value = int.Parse(cbAge.Text);
command.Parameters.Add("@name_diagnoz", SqlDbType.NVarChar, 30).Value = cbxNameDiagnoz.Text;
command.Parameters.Add("@stage", SqlDbType.Char, 1).Value = cbxStage.Text;
connection.Open();
using (SqlDataReader dr = command.ExecuteReader())
{
while (dr.Read())
{
int intColumn = dr.GetInt32(dr.GetOrdinal("intColumnName"));
string stringColumn = dr.GetString(dr.GetOrdinal("stringColumnName"));
}
}
}
}
catch (Exception ex)
{
MessageGox.Show(ex.Message);
}