Hen*_*sen 10 sql-server azure-sql-database errors
我们的应用程序之一报告错误消息 2628:
string or binary data would be truncated in table '******', column '******'. Truncated value: '******'
代替
String or binary data would be truncated in table 'mytable', column 'mycolumn'. Truncated value: 'myvalue'.
我用 SSMS 得到的。
我需要更改什么设置才能获得完整的消息?
我试图搜索这个,但我得到的只是我需要将 VERBOSE_TRUNCATION_WARNINGS 设置为 ON,并将 compatible_level 设置为 150。我很久以前就这样做了。
该应用程序具有以下错误处理程序:
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);
}
Run Code Online (Sandbox Code Playgroud)
errorHandler 看起来像这样
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
Run Code Online (Sandbox Code Playgroud)
我们以前从未见过这种行为,但我们最近将 .net 框架更新到了 4.7.2 版,所以它可能是相关的。
错误文本“字符串或二进制”来自该位
该错误发生在调用存储过程之后,其中用户可能输入了 varchar(1000) 文本。存储过程增加了一点,表没有空间容纳所有 1100 个字节。因此错误。存储过程没有 try-catch 块。
Jos*_*ell 13
看起来这个表是用动态数据屏蔽定义的,应用程序用来访问数据库的用户没有查看屏蔽数据的权限(这很好!)。
这就是应用程序和 SSMS 之间的行为不同的原因:我希望您在从 SSMS 运行查询时使用更高权限的用户
这是一个演示:
CREATE TABLE dbo.Test
(
Id int IDENTITY PRIMARY KEY,
Filler varchar(100) MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)') NULL
);
GO
CREATE USER TestUser WITHOUT LOGIN;
GRANT SELECT ON dbo.Test TO TestUser;
GRANT INSERT ON dbo.Test TO TestUser;
GO
EXECUTE AS USER = 'TestUser';
INSERT dbo.Test
(Filler)
VALUES
(REPLICATE(N'A', 101));
REVERT;
Run Code Online (Sandbox Code Playgroud)
其结果是:
CREATE TABLE dbo.Test
(
Id int IDENTITY PRIMARY KEY,
Filler varchar(100) MASKED WITH (FUNCTION = 'partial(1,"XXXXXXX",0)') NULL
);
GO
CREATE USER TestUser WITHOUT LOGIN;
GRANT SELECT ON dbo.Test TO TestUser;
GRANT INSERT ON dbo.Test TO TestUser;
GO
EXECUTE AS USER = 'TestUser';
INSERT dbo.Test
(Filler)
VALUES
(REPLICATE(N'A', 101));
REVERT;
Run Code Online (Sandbox Code Playgroud)
要在应用程序中获取完整消息,您需要授予用户UNMASK
权限:
GRANT UNMASK TO TestUser;
Run Code Online (Sandbox Code Playgroud)
INSERT
再次运行代码会得到完整的错误文本:
Msg 2628, Level 16, State 1, Line 12
String or binary data would be truncated in table '******', column '******'. Truncated value: '******'.
Run Code Online (Sandbox Code Playgroud)
使用 Azure SQL 数据库时,还可以在 Azure 门户用户界面中配置动态数据屏蔽。您可能想在那里检查(尽管据我所知,以这种方式设置的掩码仍然会更新sys.columns
元数据):
我还会检查 Azure 中是否还有其他属于同一逻辑 SQL Server 实例的其他数据库——也许正在进行某种奇怪的跨数据库查询。
我发现我已经将敏感度分类添加到我所有的临时表中,(并且只添加到我的一些非临时表中)。
如
add SENSITIVITY CLASSIFICATION to dbo.Mytable.name with (LABEL = 'General', INFORMATION_TYPE = 'Public')
Run Code Online (Sandbox Code Playgroud)
当我删除敏感度分类时,旧的错误消息又回来了。
我有一个演示错误的示例:
drop table if exists dbo.mytable
go
create table dbo.Mytable (i int not null identity(1,1) primary key clustered, name varchar(10) not null)
go
insert into dbo.Mytable ( name ) values ( 'abc' )
go
select * from dbo.Mytable where name = 1 -- programming error; data type mis-match
Run Code Online (Sandbox Code Playgroud)
返回
(1 row affected)
Msg 245, Level 16, State 1, Line 8
Conversion failed when converting the varchar value 'abc' to data type int.
Run Code Online (Sandbox Code Playgroud)
这是正确的错误消息。现在运行这个:
add SENSITIVITY CLASSIFICATION to dbo.Mytable.name with (LABEL = 'General', INFORMATION_TYPE = 'Public')
Run Code Online (Sandbox Code Playgroud)
当你运行这个
select * from dbo.Mytable where name = 1 -- programming error; data type mis-match
Run Code Online (Sandbox Code Playgroud)
你会看到这个
Msg 245, Level 16, State 1, Line 169
Conversion failed when converting the ****** value '******' to data type ******.
Run Code Online (Sandbox Code Playgroud)
这是不正确的错误消息。
我已经在 Azure SQL 数据库上尝试了此代码,在那里我收到了不正确的消息,在 SQL Server 2019 CU6 上,我只收到了正确的消息。
我已经向微软报告了这个问题,他们已经承认这是一个错误,它将在几个月内修复。
我创建了两个脚本来 1) 记录现有分类,以及 2) 删除所有这些分类。
脚本可以在这里找到: 文档和删除分类
错误消息中的屏蔽也可能发生在与动态数据屏蔽(或时态表)无关的场景中。请参阅以下示例:
CREATE DATABASE ErrorMessageTest
GO
USE ErrorMessageTest
GO
CREATE USER SimpleUser WITHOUT LOGIN
GO
ALTER ROLE db_datareader ADD MEMBER SimpleUser
GO
CREATE FUNCTION dbo.Numbers(@MaxNumber int)
RETURNS TABLE AS RETURN
WITH Nbrs_4( n ) AS ( SELECT 1 UNION SELECT 0 ),
Nbrs_3( n ) AS ( SELECT 1 FROM Nbrs_4 n1 CROSS JOIN Nbrs_4 n2 ),
Nbrs_2( n ) AS ( SELECT 1 FROM Nbrs_3 n1 CROSS JOIN Nbrs_3 n2 ),
Nbrs_1( n ) AS ( SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2 ),
Nbrs_0( n ) AS ( SELECT 1 FROM Nbrs_1 n1 CROSS JOIN Nbrs_1 n2 ),
Nbrs ( n ) AS ( SELECT 1 FROM Nbrs_0 n1 CROSS JOIN Nbrs_0 n2 )
SELECT n
FROM ( SELECT ROW_NUMBER() OVER (ORDER BY n)
FROM Nbrs ) D ( n )
WHERE n <= @MaxNumber ;
GO
CREATE FUNCTION dbo.Split(@Param nvarchar(MAX),@Separator NCHAR(1))
RETURNS TABLE AS RETURN
SELECT SUBSTRING(@Param, N, CHARINDEX(@Separator, @Param + @Separator, n) - n) AS VALUE,
ROW_NUMBER() OVER (ORDER BY N) AS Position
FROM dbo.Numbers(LEN(@Param)) n
WHERE SUBSTRING(@Separator + @Param, n, 1) = @Separator
GO
EXECUTE AS USER='SimpleUser'
DECLARE @ApplyToMonth NVARCHAR(101) = '1,2,3,4,5,6, test error message,8'
SELECT t.VALUE AS OriginalValue, TRY_CAST(REPLACE(t.VALUE, ' ', '') AS INT) AS IntValue
FROM dbo.Split(@ApplyToMonth, ',') t
SELECT x.OriginalValue, x.IntValue,
CASE WHEN x.IntValue IS NULL THEN CAST(x.OriginalValue AS INT) ELSE 0 END AS RaisErrorColumn
FROM (
SELECT t.VALUE AS OriginalValue, TRY_CAST(REPLACE(t.VALUE, ' ', '') AS INT) AS IntValue
FROM dbo.Split(@ApplyToMonth, ',') t
) x
GO
REVERT
GO
USE master
GO
DROP DATABASE ErrorMessageTest
Run Code Online (Sandbox Code Playgroud)
在 SQL Server 2016 和 SQL Server 2017 中,这会产生以下错误消息:
Conversion failed when converting the ****** value '******' to data type ******.
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,这种情况下的解决方案与其他情况相同: GRANT UNMASK TO SimpleUser
我倾向于说这是一个错误,因为在 SQL Server 2019 CU5 中,我收到了完整的错误消息(没有授予 UNMASK):
Conversion failed when converting the nvarchar value ' test error message' to data type int.
Run Code Online (Sandbox Code Playgroud)
您看到的行为(即元数据***
在非sysadmin
/非dbo
帐户的错误消息中被替换)似乎是跟踪标志 3625: Metadata Visibility Configuration 的影响。我没有可用于测试的 Azure 帐户,但文档确实表明此功能在 Azure SQL 数据库中可用。
一种不太可能的可能性(实际上,此时甚至不应该)是有人为 配置了短暂的(谢天谢地!)“功能限制”选项ERRORMESSAGE
,这实际上与跟踪标志 3625 相同。我相信有几个月,当“功能限制”功能被逐步淘汰时,它可能之前已配置但不再完全可访问。但是,最迟应在 2020 年 3 月 4 日之前(从 Azure SQL 数据库中)100% 删除该功能。
归档时间: |
|
查看次数: |
1356 次 |
最近记录: |