Um de nossos aplicativos relata a mensagem de erro 2628:
string or binary data would be truncated in table '******', column '******'. Truncated value: '******'
ao invés de
String or binary data would be truncated in table 'mytable', column 'mycolumn'. Truncated value: 'myvalue'.
que eu recebo com SSMS.
Que configuração preciso alterar para obter a mensagem completa?
Tentei procurar por isso, mas tudo o que consigo é que preciso definir VERBOSE_TRUNCATION_WARNINGS como ON e compatibility_level como 150. O que fiz há muito tempo.
O aplicativo tem este manipulador de erros:
try
{
ES.isWorking = true;
Worker worker = new Worker(new DBConnection(Settings.ConnectionString));
worker.DoWork();
ES.isWorking = false;
}
catch (Exception ex)
{
ES.isWorking = false;
this.eventLog.WriteEntry("In OnTimer exception ! message: " + ex.Message.ToString());
errorHandler.HandleException(ex, "In OnTimer exception !", ErrorSeverities.Error);
}
O errorHandler se parece com isso
Public Function HandleException(ByVal incommingEx As System.Exception,
ByVal note As String,
ByVal errorSeverity As ErrorSeverities,
Optional ByVal sessionId As String = "",
Optional ByVal applicationSource As String = "",
Optional ByVal ignoreDB As Boolean = False,
Optional ByVal noMail As Boolean = False) As Integer
Dim stackTraceBuilder As New System.Text.StringBuilder
Dim targetSite As String = ""
Dim errorTime As DateTime = Now
Dim messageBuilder As New System.Text.StringBuilder
Dim innerEx As Exception = incommingEx.InnerException
Dim errorId As Integer = 0
Dim innerCount As Integer = 1
Dim loggedToDb As Boolean = False
Dim appSource As String = Me._applicationSource
If applicationSource <> "" Then
appSource = applicationSource
End If
'... more code'
messageBuilder.AppendLine("(" + incommingEx.GetType.Name.ToUpper + ")" + vbCrLf + incommingEx.Message + " - SOURCE: " + incommingEx.Source)
'...'
While Not innerEx Is Nothing And innerCount <= 5
messageBuilder.AppendLine("INNER" + Convert.ToString(innerCount) + " (" + innerEx.GetType.Name.ToUpper + "):" + vbCrLf + **innerEx.Message** + " - SOURCE: " + innerEx.Source)
If Not innerEx Is Nothing AndAlso Not innerEx.StackTrace Is Nothing Then
stackTraceBuilder.AppendLine("INNER" + Convert.ToString(innerCount) + ": " + innerEx.StackTrace) 'Me.GetNumberedStack(innerEx))
End If
innerEx = innerEx.InnerException
innerCount += 1
End While
'... more code where the error message is inserted in a log table, via a sproc'
End Function
Não vimos esse comportamento antes, mas atualizamos recentemente o framework .net para a versão 4.7.2, para que possa estar relacionado.
o texto de erro "string ou binário" está vindo do bit que vai
- innerEx.Message + e esse é um tipo de dados Exception interno simples. Portanto, é VB e/ou .net e/ou SQL Server que está construindo a string, não nós.
O erro ocorre após uma chamada para um procedimento armazenado, onde o usuário provavelmente digitou um texto varchar(1000). O procedimento armazenado adiciona um pouco mais e a tabela não tem espaço para todos os 1100 bytes. Daí o erro. O procedimento armazenado não tem um bloco try-catch.
Parece que esta tabela foi definida com mascaramento de dados dinâmico e o usuário que o aplicativo usa para acessar o banco de dados não tem permissão para visualizar dados mascarados (o que é bom!).
É por isso que o comportamento difere entre o aplicativo e o SSMS: espero que você esteja usando um usuário com privilégios mais altos ao executar a consulta do SSMS
Aqui está uma demonstração:
O resultado disso é:
Para obter a mensagem completa no aplicativo, você precisará conceder a
UNMASK
permissão ao usuário:Executar o
INSERT
código novamente resulta no texto completo do erro:Ao usar o Banco de Dados SQL do Azure, o Mascaramento de Dados Dinâmico também pode ser configurado na interface do usuário do Portal do Azure. Você pode querer verificar lá (embora, até onde eu saiba, as máscaras configuradas dessa maneira ainda atualizam os
sys.columns
metadados):Eu também verificaria se há outros bancos de dados que fazem parte da mesma instância lógica do SQL Server no Azure - talvez haja algum tipo de consulta estranha entre bancos de dados em andamento.
Acho que está relacionado a um bug novo e subnotificado no Banco de Dados SQL do Azure (somente), onde as Tabelas Temporais são tratadas de forma diferente das tabelas normais, quando ocorrem os erros 245 e 2628.
Descobri que adicionei a Classificação de Sensibilidade a todas as minhas Tabelas Temporais (e apenas a algumas das minhas Tabelas não Temporais).
Como em
quando eu descarto a Classificação de Sensibilidade, a antiga mensagem de erro está de volta.
Tenho um exemplo que demonstra o erro:
retorna
Esta é a mensagem de erro correta . Agora execute isso:
e quando você executa isso
Você vai ver isso
Esta é a mensagem de erro incorreta .
Eu tentei este código no Banco de Dados SQL do Azure, onde recebo a mensagem incorreta, e no SQL Server 2019 CU6, onde recebo apenas a mensagem correta.
Eu relatei isso à Microsoft, e eles reconheceram que isso é um bug e que será corrigido em alguns meses.
Criei dois scripts para 1) documentar as classificações existentes e 2) eliminar todas essas classificações.
Os scripts podem ser encontrados aqui: document and drop classificações
O mascaramento na mensagem de erro pode ocorrer também em cenários não relacionados ao mascaramento dinâmico de dados (ou tabelas temporais). Veja o exemplo a seguir:
No SQL Server 2016 e no SQL Server 2017, isso produz a seguinte mensagem de erro:
Surpreendentemente, a solução neste caso é a mesma que nos outros casos:
GRANT UNMASK TO SimpleUser
Estou inclinado a dizer que isso é um bug, porque no SQL Server 2019 CU5, recebo a mensagem de erro completa (sem conceder UNMASK):
O comportamento que você está vendo (ou seja, meta-dados sendo substituídos por
***
mensagens de erro para contassysadmin
não/nãodbo
-contas) parece ser o efeito do sinalizador de rastreamento 3625: Configuração de visibilidade de metadados . Não tenho uma conta do Azure para testar, mas a documentação indica que esse recurso está disponível no Banco de Dados SQL do Azure.Uma possibilidade muito menos provável (na verdade, nem deveria ser possível neste momento) é que alguém configurou a opção "restrições de recursos" de curta duração ( felizmente!
ERRORMESSAGE
) para , que era efetivamente a mesma coisa que o sinalizador de rastreamento 3625. Houve alguns meses, acredito, em que o recurso "Restrições de recursos" estava sendo desativado em que era possível que ele fosse configurado anteriormente, mas não estivesse mais totalmente acessível. No entanto, esse recurso deve ter sido 100% removido (do Banco de Dados SQL do Azure) até 4 de março de 2020, o mais tardar.