Skip to content

Commit f7ab2a0

Browse files
committed
Optimized fix with proper testing
1 parent 1a64ea7 commit f7ab2a0

File tree

6 files changed

+37
-866
lines changed

6 files changed

+37
-866
lines changed

PR_SUMMARY.md

Lines changed: 0 additions & 172 deletions
This file was deleted.

mssql_python/cursor.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -965,10 +965,6 @@ def execute(
965965
# Executing a new statement. Reset is_stmt_prepared to false
966966
self.is_stmt_prepared = [False]
967967

968-
# Enhanced multi-statement handling - pyodbc approach
969-
# Apply SET NOCOUNT ON to all multi-statement queries to prevent result set issues
970-
if self._is_multistatement_query(operation):
971-
operation = self._add_nocount_to_multistatement_sql(operation)
972968

973969
log('debug', "Executing query: %s", operation)
974970
for i, param in enumerate(parameters):
@@ -1010,9 +1006,9 @@ def execute(
10101006

10111007
self.last_executed_stmt = operation
10121008

1013-
# Update rowcount after execution
1009+
# Update rowcount after execution (before buffering)
10141010
# TODO: rowcount return code from SQL needs to be handled
1015-
self.rowcount = ddbc_bindings.DDBCSQLRowCount(self.hstmt)
1011+
initial_rowcount = ddbc_bindings.DDBCSQLRowCount(self.hstmt)
10161012

10171013
# Initialize description after execution
10181014
# After successful execution, initialize description if there are results
@@ -1024,12 +1020,16 @@ def execute(
10241020
# If describe fails, it's likely there are no results (e.g., for INSERT)
10251021
self.description = None
10261022

1027-
# Reset rownumber for new result set (only for SELECT statements)
1023+
# Buffer intermediate results automatically (pyODBC-style approach)
1024+
self._buffer_intermediate_results()
1025+
1026+
# Set final rowcount based on result type (preserve original rowcount for non-SELECT)
10281027
if self.description: # If we have column descriptions, it's likely a SELECT
10291028
self.rowcount = -1
10301029
self._reset_rownumber()
10311030
else:
1032-
self.rowcount = ddbc_bindings.DDBCSQLRowCount(self.hstmt)
1031+
# For non-SELECT statements (INSERT/UPDATE/DELETE), preserve the original rowcount
1032+
self.rowcount = initial_rowcount
10331033
self._clear_rownumber()
10341034

10351035
# After successful execution, initialize description if there are results
@@ -2188,11 +2188,11 @@ def tables(self, table=None, catalog=None, schema=None, tableType=None):
21882188
("table_type", str, None, 128, 128, 0, False),
21892189
("remarks", str, None, 254, 254, 0, True)
21902190
]
2191-
2191+
21922192
# Use the helper method to prepare the result set
21932193
return self._prepare_metadata_result_set(fallback_description=fallback_description)
21942194

21952195
except Exception as e:
21962196
# Log the error and re-raise
21972197
log('error', f"Error executing tables query: {e}")
2198-
raise
2198+
raise

tests/test_004_cursor.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10754,3 +10754,30 @@ def test_close(db_connection):
1075410754
pytest.fail(f"Cursor close test failed: {e}")
1075510755
finally:
1075610756
cursor = db_connection.cursor()
10757+
10758+
def test_multi_statement_query(cursor, db_connection):
10759+
"""Test multi-statement query with temp tables"""
10760+
try:
10761+
# Single SQL with multiple statements - tests pyODBC-style buffering
10762+
multi_statement_sql = """
10763+
CREATE TABLE #TestData (id INT, name NVARCHAR(50), value INT);
10764+
INSERT INTO #TestData VALUES (1, 'Test1', 100), (2, 'Test2', 200);
10765+
SELECT COALESCE(name, 'DEFAULT') as result_name, SUM(value) as total_value INTO #TempResult FROM #TestData GROUP BY name;
10766+
SELECT result_name, total_value, 'SUCCESS' as status FROM #TempResult ORDER BY result_name;
10767+
"""
10768+
10769+
cursor.execute(multi_statement_sql)
10770+
results = cursor.fetchall()
10771+
10772+
assert len(results) > 0, "Multi-statement query should return results"
10773+
assert results[0][2] == 'SUCCESS', "Should return success status"
10774+
10775+
except Exception as e:
10776+
pytest.fail(f"Multi-statement query test failed: {e}")
10777+
finally:
10778+
try:
10779+
cursor.execute("DROP TABLE #TestData")
10780+
cursor.execute("DROP TABLE #TempResult")
10781+
db_connection.commit()
10782+
except:
10783+
pass

0 commit comments

Comments
 (0)