MSSQL Ошибка «Числовое значение вне диапазона» для 20-значного Python Long Int в числовой (24,0) столбец - PullRequest
0 голосов
/ 03 января 2019

Я пытаюсь вставить 20-разрядное 64-разрядное целое число Python в столбец MSSQL Numeric (24,0).Это приводит к ошибке «Числовое значение вне диапазона» из MSSQL.Я использую модуль pypyodbc и драйвер ODBC 13 для SQL Server, чтобы вставить данные из моего приложения на Python.

Я пытался использовать числовой (38,0) столбец в SQL только для проверки предела, но получил ту же ошибку.В операторе вставки я также попытался явным образом преобразовать идентификатор в тип данных Numeric (24,0).Все попытки привели к одной и той же ошибке.

#Python SQL Insert Code
id = 'ADD7A9FA-E77B-4BBB-92AA-3D9C7BBB44D0'
idlist =  id.split('-')

val = [int(idlist[0] + idlist[1] + idlist[2], 16), 
int(idlist[3] + idlist[4], 16)]

cmd = "INSERT INTO jssuser.dbo.API_VIMSPost (\
[id_int1], \
[id_int2]) \
VALUES (?, ?)"

#function to simplify the use of pypyodbc
sqlcmd.sqlCmd(cmd, values = val)

#SQL Table Code
USE [jssuser]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[API_VIMSPost](
    [id_int1] [numeric](24, 0) NOT NULL,
    [id_int2] [numeric](24, 0) NOT NULL,
 CONSTRAINT [PK_PostID] PRIMARY KEY CLUSTERED 
(
    [id_int1] ASC,
    [id_int2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = 
OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

Я ожидаю, что int длиной в Python, состоящий из 20 цифр и 64 бит, поместится в столбец MSSQL типа Numeric (20,0) или более.Однако вставка приводит к ошибке «Числовое значение вне диапазона».

1 Ответ

0 голосов
/ 03 января 2019

Размер целочисленных значений Python ограничен только доступной памятью; они не ограничены произвольным числом битов. Однако наибольшее целочисленное значение, которое может обрабатывать драйвер (ы) ODBC для SQL Server, - это (64-разрядная подпись) bigint с максимальным положительным значением math.pow(2, 63) - 1 или 9223372036854775807, длина которого составляет девятнадцать (19) цифр.

Когда pypyodbc пытается передать 20-значное целое число, драйвер ODBC блокирует его, поэтому это не удается

x = 13807673592980537824
crsr.execute("CREATE TABLE ##tmp (id INT PRIMARY KEY, id_int1 NUMERIC(24, 0))")
sql = "INSERT INTO ##tmp (id, id_int1) VALUES (?, ?)"
params = (1, x)
crsr.execute(sql, params)

Однако следующее работает, потому что pypyodbc не сообщает драйверу ODBC ожидать целое число

x = 13807673592980537824
crsr.execute("CREATE TABLE ##tmp (id INT PRIMARY KEY, id_int1 NUMERIC(24, 0))")
sql = "INSERT INTO ##tmp (id, id_int1) VALUES (?, ?)"
params = (1, Decimal(x))  # convert Python `int` to Python `decimal.Decimal`
crsr.execute(sql, params)
...