0

Trying to use the method detailed here to call a stored proc and perform an update using pyodbc in python3.6. I have one method that handles starting the instance and one that wraps things up.

Starting the instance works perfectly:

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

Ending it produces an error:

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)

The error is pyodbc.ProgrammingError: No results. Previous SQL was not a query.

My Stored Proc:

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

I can run the below sql in SSMS and it will work fine:

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

UPDATE:

Got it working initially thanks to Gord Thompson's hint regarding SET NOCOUNT ON. However, I ultimately want end_instance() to run atexit. I'm currently doing this:

atexit.register(self.clean_up_on_exit)

and then:

    def clean_up_on_exit(self):
        self.check_in_records()
        self.end_instance()
        self.dbObj.close_conn()

If I just call end_instance() at the end of start_instance() just for testing purposes, I get the expected result. However, adding it to my clean_up_on_exit() method doesn't produce an error, but doesn't work either.

UPDATE 2:

Registering my functions separately fixed the second problem:

    atexit.register(self.check_in_records)
    atexit.register(self.end_instance)
hyphen
  • 2,368
  • 5
  • 28
  • 59
  • 1
    Can you add `SET NOCOUNT ON;` to the beginning of your stored procedure? – Gord Thompson Jul 16 '18 at 16:41
  • you're my hero...it worked. why did it work? – hyphen Jul 16 '18 at 17:11
  • @GordThompson - just updated my question with a follow-up. seems that i've got an issue with my atexit function. – hyphen Jul 16 '18 at 17:20
  • Possible duplicate of [pyodbc returns pyodbc.ProgrammingError: No results. Previous SQL was not a query, when using declare statements](https://stackoverflow.com/questions/48061304/pyodbc-returns-pyodbc-programmingerror-no-results-previous-sql-was-not-a-query) – Gord Thompson Jul 16 '18 at 22:50

0 Answers0