Skip to content

fast_executemany: Passing decimal(m,n) parameter value as string can throw "String data, right truncation" error #845

Description

@gordthompson

Passing a negative parameter value as string for a decimal(m,n) column can throw a "String data, right truncation" error. Using setinputsizes does not resolve the issue.

print(platform.version())
# #126-Ubuntu SMP Wed Oct 21 09:40:11 UTC 2020

print("Python version: " + sys.version.replace("\n", ""))
# Python version: 3.6.5 (default, Apr  1 2018, 05:46:30) [GCC 7.3.0]

print(f"pyodbc version: {pyodbc.version}")
# pyodbc version: 4.0.30

connection_string = get_connection_string()
cnxn = pyodbc.connect(connection_string, autocommit=True)

print(
    f"ODBC driver: {cnxn.getinfo(pyodbc.SQL_DRIVER_NAME)} "
    f"[{cnxn.getinfo(pyodbc.SQL_DRIVER_VER)}]"
)
# ODBC driver: libmsodbcsql-17.6.so.1.1 [17.06.0001]

crsr = cnxn.cursor()

print(crsr.execute("SELECT @@VERSION").fetchval())
"""console output:
Microsoft SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64) 
	Jun 15 2019 00:26:19 
	Copyright (C) 2017 Microsoft Corporation
	Express Edition (64-bit) on Windows 8.1 Pro 6.3 <X64> (Build 9600: )
"""

table_name = "gh_pyodbc_845"
crsr.execute(f"DROP TABLE IF EXISTS {table_name}")
crsr.execute(f"CREATE TABLE {table_name} (id int primary key, num decimal(4,2))")

crsr.fast_executemany = True
sql = f"INSERT INTO {table_name} (id, num) VALUES (?, ?)"
crsr.setinputsizes(
    [
        (pyodbc.SQL_INTEGER,),
        (pyodbc.SQL_DECIMAL, 4, 2),
    ]
)

data = [(1, "0.07")]
crsr.executemany(sql, data)
# no error

data = [(2, "-0.07")]
crsr.executemany(sql, data)
# pyodbc.ProgrammingError: ('String data, right truncation: length 10 buffer 8', 'HY000')

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions