Skip to content

Conversation

arvis108
Copy link
Contributor

@arvis108 arvis108 commented Sep 9, 2025

Work Item / Issue Reference

GitHub Issue: #228


Summary

FEAT: Multi-statement SQL support with temp tables

This PR fixes an issue where multi-statement SQL queries (especially those using temporary tables) executed successfully but returned empty result sets in mssql-python, unlike SSMS and pyodbc.

The solution follows pyodbc’s proven approach by automatically applying SET NOCOUNT ON to multi-statement queries. This prevents DONE_IN_PROC interference, ensuring correct results without breaking existing functionality.


Implementation Highlights

  • Core: Added multi-statement detection and automatic SET NOCOUNT ON injection in cursor.py
  • Tests: 14 new test cases validating temp table usage, multi-statement detection, and real-world production scenarios

Benefits

  • Correct results for temp table queries
  • Zero breaking changes — transparent to existing code
  • Broader SQL Server compatibility (temp tables, stored procs, complex batches)
  • Performance improvement by reducing extra network messages

@arvis108
Copy link
Contributor Author

arvis108 commented Sep 9, 2025

@microsoft-github-policy-service agree

@gargsaumya gargsaumya changed the title Multi-Statement SQL Enhancement for mssql-python FIX: Multi-Statement SQL Enhancement for mssql-python Sep 9, 2025
@bewithgaurav
Copy link
Collaborator

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@bewithgaurav
Copy link
Collaborator

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@microsoft microsoft deleted a comment from azure-pipelines bot Sep 10, 2025
@gargsaumya
Copy link
Contributor

/azp run

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@gargsaumya gargsaumya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @arvis108 ,
Thank you for your contribution and for working on this enhancement! We appreciate the effort you’ve put into addressing this.

I noticed that the PR includes the file PR_SUMMARY.md, which isn’t required for this change. While the PR is currently passing all pipeline checks and everything else looks good, it would be great if we could remove this extra file to keep the PR clean and aligned with our project guidelines.

Let me know if you’d like any help or have questions, we’d be happy to assist!
Thanks again for your work on this!

PR_SUMMARY.md Outdated
@@ -0,0 +1,299 @@
# PR Summary: PyODBC-Style Multi-Statement SQL Enhancement for mssql-python
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please remove this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Copy link
Collaborator

@bewithgaurav bewithgaurav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@arvis108 - thanks a lot for your contribution to the project, this is indeed a detailed implementation of the fix.
I have added some comments requesting a few more testcases and a minor logger change, also I have identified a expected behaviour deviation of pyodbc with this.
Please fel free to add your inputs in the discussion

drop_table_if_exists(cursor, "dbo.money_test")
db_connection.commit()

def test_multi_statement_query(cursor, db_connection):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great testcase, can we add a few more tests targetting the below areas

  • multiple result sets with multiple select statements on temp tables with nextset()
  • semicolons in b/w string literals to ensure no false positives in buffering logic
  • multi-statement batch where the final statement is not a SELECT

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the tests you mentioned, feel free to add more

def test_multi_statement_query(cursor, db_connection):
"""Test multi-statement query with temp tables"""
try:
# Single SQL with multiple statements - tests pyODBC-style buffering
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually - pyodbc strangely gives out below error with this testcase (technically it shouldn't)

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

just curious for discussion, @gargsaumya - if possible, could you please take a look at what pyodbc internally might be doing for this case?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the simplest repro would be

cursor.execute("""
    SELECT 1 as col1, 'test' as col2 INTO #temp1;
    SELECT * FROM #temp1;
""")
rows = cursor.fetchall()
print(rows)

pyodbc gives out the error as mentioned in above comment
whereas mssql-python in this PR branch gives out
[(1, 'test')]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pymssql also gives out [(1, 'test')] with your query

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right about pyodbc, I am getting same error now. Looks like when I was testing, I had "SET NOCOUNT ON" set for the session. I am sorry.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No worries! Since we have a few higher-priority items in progress, we’ll circle back to testing and reviewing this fix a bit later so we can get it merged. Please let us know if this PR is blocking you in any way. Really appreciate your continued efforts to improve the driver.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR is not blocking me, no worries

@arvis108 arvis108 force-pushed the arvis/multi_statement_feature branch from 8ee1a36 to 2fbdab4 Compare September 26, 2025 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants