Estamos percebendo um erro como este:
InterfaceError: ('HY104', 0, '[Microsoft][SQL Server Native Client 11.0]
Invalid precision value', 10226)
Isso acontece quando inserimos um determinado comprimento de caracteres junto com o conteúdo Unicode como \u3000
( Espaço ideográfico ). Isso acontece apenas quando estamos usando o Driver MSSQL do Windows e a consulta é parametrizada.
A coluna é um VARCHAR(MAX)
. Portanto, deve suportar 2 GB.
- Qual poderia ser a razão para isso?
- Por que esse comprimento importa?
Se eu apenas inserir esse caractere Unicode sozinho, isso não causará problemas!
Eu estava tentando ver isso de um ponto de vista teórico. Mudar para NVARCHAR
não é uma opção para nós atualmente, mas remover o Unicode é.
Aqui estão mais alguns detalhes de acordo com as perguntas feitas por Solomon Rutzky:
- O agrupamento de colunas é
SQL_Latin1_General_CP1_CI_AS
- O comprimento da string em que começo a ver o erro é
4019
. sqlalchemy.connectors.mxodbc, line 86, in error_handler
é onde recebo o erro inicial. Isso é do rastreamento.- Funciona bem com um único caractere Unicode.
- Uma string de 20.000 caracteres sem Unicode funciona bem.
- Faz com que seja ASCII quando tento isso neste software (Web App). Testei no Dbeaver exportando os dados.
Ajudaria muito saber:
VARBINARY(MAX)
. O caractere Unicode foi traduzido ou algo mais?É possível que a string que apresenta erros esteja um pouco acima de um limite de 4.000 ou 8.000 caracteres que requer o uso de um
MAX
tipo e o driver está inicialmente adivinhando (ou sendo informado) que é um tamanho e depois descobre que é outro. A mensagem de erro diz "valor de precisão inválido", que deve estar se referindo a como a coluna está sendo configurada (ou seja, semelhante a configurar umSqlParameter
em .NET e declarar o tamanho máximo, comonew SqlParameter("@name", SqlDbType.VarChar, 8000)
). Portanto, esse tipo de erro só deve realmente acontecer se o software estiver tentando configurar a colunaVARCHAR
acima de 8.000 ouNVARCHAR
acima de 4.000, pois qualquer uma dessas condições seria uma "precisão" inválida. Agora, para obter esse número, suspeito que algum código esteja contando o número de bytes (ou seja,DATALENGTH
) da string, que será maior que o número de caracteres. Claro, isso seria verdade para qualquer caractere em um .NETstring
ou C++wchar
, então estou suspeitando que a diferença de ter alguns caracteres Unicode versus não ter nenhum é que, sem nenhum caractere Unicode, ele pode converter a string em uma codificação de 8 bits (ou seja, byte único para uso comVARCHAR
), mas de alguma forma ter um caractere Unicode impede isso. É um tiro no escuro (até que haja mais informações fornecidas), mas é bastante claro onde o erro está ocorrendo.Como você está inserindo o personagem? Através do mesmo software que está gerando o erro, ou no SSMS? Se você estiver fazendo isso manualmente por meio de uma
INSERT
instrução, esse não é um bom teste, pois o SQL Server converte U+3000 em um espaço regular, U+0020 (um byte), em vez de dois pontos de interrogação (ainda 2 bytes, como faria acontecer se não houver caractere equivalente):retorna:
Se possível, tente passar as duas strings geradas pelo código a seguir por meio do software, não por meio do SSMS:
A
@String4k
string é de 3999 caracteres que podem ser convertidos de forma limpa em uma codificação de 8 bits (ou seja,VARCHAR
) mais o caractere U+3000 que provavelmente permanecerá como 2 bytes. Então talvez isso apareça, através desse software, como 4001 caracteres. Duvido que seja esse o problema, mas não custa testar.A
@String8k
string é de 7999 caracteres que podem ser convertidos de forma limpa em uma codificação de 8 bits (ou seja,VARCHAR
) mais o caractere U+3000 que provavelmente permanecerá como 2 bytes. Então talvez isso apareça, através desse software, como 8001 caracteres.