Python pyodbc exec存储过程的参数/输出参数-更新不工作

Python pyodbc exec存储过程的参数/输出参数-更新不工作,python,python-3.6,pyodbc,Python,Python 3.6,Pyodbc,正在尝试使用python3.6中详述的方法调用存储过程并使用pyodbc执行更新。我有一个方法来处理实例的启动,还有一个方法来完成任务 启动实例非常有效: def start_instance(self, count): params = [1, count] sql = """ DECLARE @out as int; EXEC [dbo].[my_sproc] @id = ?, @count = ?, @instance_id = NULL,

正在尝试使用python3.6中详述的方法调用存储过程并使用pyodbc执行更新。我有一个方法来处理实例的启动,还有一个方法来完成任务

启动实例非常有效:

def start_instance(self, count):
    params = [1, count]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @count = ?, @instance_id = NULL, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    self.instance = val
def end_instance(self):
    params = [1, self.instance]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @instance_id = ?, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    print(val)
ALTER PROCEDURE [dbo].[my_sproc] @id int, @count int = NULL, @instance_id int = NULL, @output int OUTPUT
AS

IF(@instance_id IS NULL)
    BEGIN
        DECLARE @OutputTbl TABLE (ID INT)
        INSERT INTO [dbo].[my_table]([id], [record_count]) OUTPUT INSERTED.id VALUES(@id, COALESCE(@count, 0));
    END

IF(@instance_id IS NOT NULL)
    BEGIN
        UPDATE [dbo].[my_table] SET [instance_end] = GETDATE(), [records_processed] = COALESCE(@count, 0) WHERE [id] = @id AND [instance_id] = @instance_id;
        SET @output = 1
    END
结束它会产生错误:

def start_instance(self, count):
    params = [1, count]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @count = ?, @instance_id = NULL, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    self.instance = val
def end_instance(self):
    params = [1, self.instance]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @instance_id = ?, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    print(val)
ALTER PROCEDURE [dbo].[my_sproc] @id int, @count int = NULL, @instance_id int = NULL, @output int OUTPUT
AS

IF(@instance_id IS NULL)
    BEGIN
        DECLARE @OutputTbl TABLE (ID INT)
        INSERT INTO [dbo].[my_table]([id], [record_count]) OUTPUT INSERTED.id VALUES(@id, COALESCE(@count, 0));
    END

IF(@instance_id IS NOT NULL)
    BEGIN
        UPDATE [dbo].[my_table] SET [instance_end] = GETDATE(), [records_processed] = COALESCE(@count, 0) WHERE [id] = @id AND [instance_id] = @instance_id;
        SET @output = 1
    END
错误为
pyodbc.ProgrammingError:无结果。以前的SQL不是查询。

我的存储过程:

def start_instance(self, count):
    params = [1, count]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @count = ?, @instance_id = NULL, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    self.instance = val
def end_instance(self):
    params = [1, self.instance]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @instance_id = ?, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    print(val)
ALTER PROCEDURE [dbo].[my_sproc] @id int, @count int = NULL, @instance_id int = NULL, @output int OUTPUT
AS

IF(@instance_id IS NULL)
    BEGIN
        DECLARE @OutputTbl TABLE (ID INT)
        INSERT INTO [dbo].[my_table]([id], [record_count]) OUTPUT INSERTED.id VALUES(@id, COALESCE(@count, 0));
    END

IF(@instance_id IS NOT NULL)
    BEGIN
        UPDATE [dbo].[my_table] SET [instance_end] = GETDATE(), [records_processed] = COALESCE(@count, 0) WHERE [id] = @id AND [instance_id] = @instance_id;
        SET @output = 1
    END
我可以在SSMS中运行以下sql,它可以正常工作:

DECLARE @out as int;
EXEC [dbo].[my_sproc] @id = 1, @count = NULL, @instance_id = 12, @output = @out OUTPUT;
SELECT @out as op
更新:

def start_instance(self, count):
    params = [1, count]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @count = ?, @instance_id = NULL, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    self.instance = val
def end_instance(self):
    params = [1, self.instance]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @instance_id = ?, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    print(val)
ALTER PROCEDURE [dbo].[my_sproc] @id int, @count int = NULL, @instance_id int = NULL, @output int OUTPUT
AS

IF(@instance_id IS NULL)
    BEGIN
        DECLARE @OutputTbl TABLE (ID INT)
        INSERT INTO [dbo].[my_table]([id], [record_count]) OUTPUT INSERTED.id VALUES(@id, COALESCE(@count, 0));
    END

IF(@instance_id IS NOT NULL)
    BEGIN
        UPDATE [dbo].[my_table] SET [instance_end] = GETDATE(), [records_processed] = COALESCE(@count, 0) WHERE [id] = @id AND [instance_id] = @instance_id;
        SET @output = 1
    END
多亏了Gord Thompson关于
设置NOCOUNT ON
的提示,它才开始工作。但是,我最终希望
end\u instance()
运行atexit。我目前正在这样做:

atexit.register(self.clean_up_on_exit)
然后:

    def clean_up_on_exit(self):
        self.check_in_records()
        self.end_instance()
        self.dbObj.close_conn()
如果我只是为了测试而在
start\u instance()
的末尾调用
end\u instance()
,我会得到预期的结果。但是,将它添加到我的
clean\u on\u exit()
方法不会产生错误,但也不起作用

更新2:

def start_instance(self, count):
    params = [1, count]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @count = ?, @instance_id = NULL, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    self.instance = val
def end_instance(self):
    params = [1, self.instance]
    sql = """
        DECLARE @out as int;
        EXEC [dbo].[my_sproc] @id = ?, @instance_id = ?, @output = @out OUTPUT;
        SELECT @out as op;
    """
    val = self.dbObj.query(sql, params).fetchval()
    print(val)
ALTER PROCEDURE [dbo].[my_sproc] @id int, @count int = NULL, @instance_id int = NULL, @output int OUTPUT
AS

IF(@instance_id IS NULL)
    BEGIN
        DECLARE @OutputTbl TABLE (ID INT)
        INSERT INTO [dbo].[my_table]([id], [record_count]) OUTPUT INSERTED.id VALUES(@id, COALESCE(@count, 0));
    END

IF(@instance_id IS NOT NULL)
    BEGIN
        UPDATE [dbo].[my_table] SET [instance_end] = GETDATE(), [records_processed] = COALESCE(@count, 0) WHERE [id] = @id AND [instance_id] = @instance_id;
        SET @output = 1
    END
单独注册我的函数修复了第二个问题:

    atexit.register(self.check_in_records)
    atexit.register(self.end_instance)

可以添加
设置NOCOUNT ON到存储过程的开头?你是我的英雄…它成功了。“它为什么起作用?”GordThompson-刚刚更新了我的问题,并进行了后续跟进。似乎我的atexit函数有问题。可能是