Skip to content

Commit 48ca73c

Browse files
committed
Merge branch 'arvis/multi_statement_feature' of https://github.com/arvis108/mssql-python into arvis/multi_statement_feature
2 parents 551142b + 7e60e94 commit 48ca73c

File tree

4 files changed

+1076
-496
lines changed

4 files changed

+1076
-496
lines changed

mssql_python/cursor.py

Lines changed: 58 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
# Constants for string handling
2222
MAX_INLINE_CHAR = 4000 # NVARCHAR/VARCHAR inline limit; this triggers NVARCHAR(MAX)/VARCHAR(MAX) + DAE
23+
SMALLMONEY_MIN = decimal.Decimal('-214748.3648')
24+
SMALLMONEY_MAX = decimal.Decimal('214748.3647')
25+
MONEY_MIN = decimal.Decimal('-922337203685477.5808')
26+
MONEY_MAX = decimal.Decimal('922337203685477.5807')
2327

2428
class Cursor:
2529
"""
@@ -282,18 +286,39 @@ def _map_sql_type(self, param, parameters_list, i):
282286
0,
283287
False,
284288
)
285-
289+
286290
if isinstance(param, decimal.Decimal):
287-
parameters_list[i] = self._get_numeric_data(
288-
param
289-
) # Replace the parameter with the dictionary
290-
return (
291-
ddbc_sql_const.SQL_NUMERIC.value,
292-
ddbc_sql_const.SQL_C_NUMERIC.value,
293-
parameters_list[i].precision,
294-
parameters_list[i].scale,
295-
False,
296-
)
291+
# Detect MONEY / SMALLMONEY range
292+
if SMALLMONEY_MIN <= param <= SMALLMONEY_MAX:
293+
# smallmoney
294+
parameters_list[i] = str(param)
295+
return (
296+
ddbc_sql_const.SQL_VARCHAR.value,
297+
ddbc_sql_const.SQL_C_CHAR.value,
298+
len(parameters_list[i]),
299+
0,
300+
False,
301+
)
302+
elif MONEY_MIN <= param <= MONEY_MAX:
303+
# money
304+
parameters_list[i] = str(param)
305+
return (
306+
ddbc_sql_const.SQL_VARCHAR.value,
307+
ddbc_sql_const.SQL_C_CHAR.value,
308+
len(parameters_list[i]),
309+
0,
310+
False,
311+
)
312+
else:
313+
# fallback to generic numeric binding
314+
parameters_list[i] = self._get_numeric_data(param)
315+
return (
316+
ddbc_sql_const.SQL_NUMERIC.value,
317+
ddbc_sql_const.SQL_C_NUMERIC.value,
318+
parameters_list[i].precision,
319+
parameters_list[i].scale,
320+
False,
321+
)
297322

298323
if isinstance(param, str):
299324
if (
@@ -348,16 +373,16 @@ def _map_sql_type(self, param, parameters_list, i):
348373
if utf16_len > MAX_INLINE_CHAR: # Long strings -> DAE
349374
if is_unicode:
350375
return (
351-
ddbc_sql_const.SQL_WLONGVARCHAR.value,
376+
ddbc_sql_const.SQL_WVARCHAR.value,
352377
ddbc_sql_const.SQL_C_WCHAR.value,
353-
utf16_len,
378+
0,
354379
0,
355380
True,
356381
)
357382
return (
358-
ddbc_sql_const.SQL_LONGVARCHAR.value,
383+
ddbc_sql_const.SQL_VARCHAR.value,
359384
ddbc_sql_const.SQL_C_CHAR.value,
360-
len(param),
385+
0,
361386
0,
362387
True,
363388
)
@@ -379,27 +404,24 @@ def _map_sql_type(self, param, parameters_list, i):
379404
False,
380405
)
381406

382-
if isinstance(param, bytes):
383-
# Use VARBINARY for Python bytes/bytearray since they are variable-length by nature.
384-
# This avoids storage waste from BINARY's zero-padding and matches Python's semantics.
385-
return (
386-
ddbc_sql_const.SQL_VARBINARY.value,
387-
ddbc_sql_const.SQL_C_BINARY.value,
388-
len(param),
389-
0,
390-
False,
391-
)
392-
393-
if isinstance(param, bytearray):
394-
# Use VARBINARY for Python bytes/bytearray since they are variable-length by nature.
395-
# This avoids storage waste from BINARY's zero-padding and matches Python's semantics.
396-
return (
397-
ddbc_sql_const.SQL_VARBINARY.value,
398-
ddbc_sql_const.SQL_C_BINARY.value,
399-
len(param),
400-
0,
401-
False,
402-
)
407+
if isinstance(param, (bytes, bytearray)):
408+
length = len(param)
409+
if length > 8000: # Use VARBINARY(MAX) for large blobs
410+
return (
411+
ddbc_sql_const.SQL_VARBINARY.value,
412+
ddbc_sql_const.SQL_C_BINARY.value,
413+
0,
414+
0,
415+
True
416+
)
417+
else: # Small blobs → direct binding
418+
return (
419+
ddbc_sql_const.SQL_VARBINARY.value,
420+
ddbc_sql_const.SQL_C_BINARY.value,
421+
max(length, 1),
422+
0,
423+
False
424+
)
403425

404426
if isinstance(param, datetime.datetime):
405427
return (

0 commit comments

Comments
 (0)