#sql-server #stored-procedures
#sql-сервер #хранимые процедуры
Вопрос:
как вернуть данные из таблицы, если ввод производится с помощью хранимой процедуры, которая вводит данные в несколько таблиц, но при вводе данных в одну таблицу возникает ошибка. Так что теперь я должен вернуть данные и из других таблиц. Как это сделать?
Комментарии:
1. Извините, но ваш вопрос слишком общий. Вы можете обновлять / удалять данные об ошибках
2. Вы можете использовать транзакции; обязательно добавьте обработку ошибок и взаимоблокировок должным образом!
3. Вообще говоря, вы используете транзакции, чтобы принудительно зафиксировать все изменения вместе или откатить их. Похоже, вы пытаетесь сделать это после фиксации (возможно, вызванной аварией или какой-либо проблемой). Если это так, то вы опоздали. Нет встроенной функциональности, которая будет делать то, что вы хотите. Вам нужно будет вручную «отменить» изменения самостоятельно или попытаться восстановить на определенный момент времени (что, вероятно, выходит за рамки ваших возможностей на данный момент).
Ответ №1:
Используйте явные транзакции и TRY...CATCH
. Это простой пример, но он демонстрирует идею:
--Create Sampel tables
CREATE TABLE dbo.SampleTable1 (ID int IDENTITY PRIMARY KEY,
SomeString varchar(20));
GO
CREATE TABLE dbo.SampleTable2 (ID int IDENTITY PRIMARY KEY,
fID int,
SomeInt int);
ALTER TABLE dbo.SampleTable2 ADD CONSTRAINT FK_Sample2Sample1 FOREIGN KEY (fID) REFERENCES dbo.SampleTable1 (ID);
GO
--Workign sample
BEGIN TRY
BEGIN TRANSACTION YourTransaction;
INSERT INTO dbo.SampleTable1 (SomeString)
VALUES('abc123');
INSERT INTO dbo.SampleTable2 (fID, SomeInt)
VALUES(1,2);
COMMIT TRANSACTION YourTransaction;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION YourTransaction;
THROW;
END CATCH;
GO
--Failing example
BEGIN TRY
BEGIN TRANSACTION YourTransaction;
INSERT INTO dbo.SampleTable1 (SomeString)
VALUES('def456');
INSERT INTO dbo.SampleTable2 (fID, SomeInt)
VALUES(3,2); --Invalid foreign key
COMMIT TRANSACTION YourTransaction;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION YourTransaction;
THROW;
END CATCH;
GO
SELECT * --Notice ID 2 missing.
FROM dbo.SampleTable1;
GO
DROP TABLE dbo.SampleTable2;
DROP TABLE dbo.SampleTable1;