我有一个这样的存储过程
CREATE PROCEDURE StudentSproc
(@StudentID VARCHAR(50),
@Name VARCHAR(50))
AS
BEGIN
BEGIN TRAN
BEGIN TRY
INSERT INTO Student(StudentID, Name)
VALUES (@StudentID,@Name)
COMMIT TRAN;
END TRY
BEGIN CATCH
ROLLBACK TRAN
END CATCH
END;
我正在尝试从python执行它:
db_conn_str = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=' + server + ';PORT=1433;DATABASE=' + database + ';UID=' + username + ';PWD=' + password
cnxn = pyodbc.connect(db_conn_str)
cursor = cnxn.cursor()
st = f"exec master.dbo.StudentSproc @StudentID = ?, @Name = ? "
s_id = "101"
name = "Charles"
params = (s_id, name)
cursor.execute(st, params)
print(f"executed sproc by {st}")
这没有错误,并且执行存储过程,但是它不会更新数据库,我很惊讶。我知道我必须在connect()
调用中使用autocommit=True
,但是如果存储过程中存在提交,为什么有必要这样做呢
没有错误,因为您正在使用
try/catch
。它的工作原理与其他语言中的工作原理相同-如果catch
出现异常,则不会返回到客户端。它被抓住了您可以在catch中回滚tran,然后再次
throw
以将错误返回给客户端我还注意到您在
master
数据库中有您的过程。您可能不希望它出现在那里,master
是一个系统数据库你还提到你知道你必须使用自动提交,但根据我们的讨论,我现在知道你实际上没有使用它,你只是想知道为什么你必须使用它。这引入了第二种可能性
在SQL Server中,唯一重要的提交是“最外层”的提交。任何“嵌套”提交实际上除了减少
@@trancount
的值之外,不会做任何事情例如:
另一方面,
rollback
的工作方式不同。单个rollback
将回滚所有嵌套事务,将@@trancount
值减为零如果您启动两个事务(一个在客户端代码中,一个在存储过程中),但只发出一个提交,那么您的“真正”事务实际上仍然处于打开状态
相关问题 更多 >
编程相关推荐