FEAT: Complex Data Type Support- money & smallmoney by gargsaumya · Pull Request #230 · microsoft/mssql-python

Left a few comments

Thanks for the feedback! I have addressed the comments and I wanted to provide context for why we currently bind MONEY and SMALLMONEY as SQL_VARCHAR/SQL_C_CHAR rather than SQL_NUMERIC.

  1. Precision/scale issues with SQL_NUMERIC_STRUCT:
    In practice, many ODBC drivers including SQL Server’s return unexpected results when fetching MONEY/SMALLMONEY types using SQL_NUMERIC_STRUCT. A common behavior is that the precision may be reported as the maximum allowed (e.g., 38), and scale may be reported as 0, which discards fractional parts entirely. This was exactly the issue I faced.
  2. Overflow risk:
    Our current NumericData struct uses a 64-bit integer to hold val × 10^scale. While this works for most MONEY/SMALLMONEY values, it’s extremely sensitive to boundary cases and cannot support arbitrary precision numerics safely.

To avoid all this, we have bound these types as strings (SQL_VARCHAR/SQL_C_CHAR). SQL Server handles the implicit conversion from string to MONEY/SMALLMONEY on insert, and we can fetch numeric values as strings and then parse them to Python Decimal without losing precision. This approach also avoids integer overflow issue.
While exploring solutions, I found that Pyodbc follows the same strategy, it reads and writes values as text strings rather than using SQL_NUMERIC_STRUCT. This is also discussed in [this StackOverflow thread], where contributors note that fetching numeric/decimal/money via SQL_C_NUMERIC can discard fractional digits - precisely the problem I encountered.