我有几个具有相同名称但程序不同的程序。当这些过程引发错误时,父进程(调用这些嵌套的存储过程)可能会获得引发错误的过程的模式吗?例如,我可以从ERROR_PROCEDURE()
获取名称,但是还有一些选项可以获得SCHEMA吗?因为否则我不确定如果有许多具有相同名称的错误,那么哪个程序会引发错误。
但是有一些解决方法吗?
答案 0 :(得分:1)
遗憾的是,SQL Server中对此限制没有100%变通办法。
遗憾的是,MSSQL开发团队没有纠正此错误,这在整个Decade之后很久了。
它应该像添加ERROR_ProcedureSchema()
或ERROR_PROCID()
之类的新功能一样简单。
这是自2005年5月以来重新发布的要求此功能的帖子:
https://feedback.azure.com/forums/908035-sql-server/suggestions/32894584-schema-not-reported-in-the-error-procedure-functio
我希望记录有关我在自定义错误处理逻辑中捕获的异常的尽可能多的详细信息。
这是我能想到的最好的方案名称:
DECLARE @Error_ProcSchemaName nVarChar(128)--Leave as Null if found in more than 1 Schema.
--Only Populate the @Error_ProcSchemaName if it Belongs to 1 Schema. - 04/08/2019 - MCR.
SELECT @Error_ProcSchemaName = S.name
FROM sys.objects as O
JOIN sys.schemas as S
ON S.schema_id = O.schema_id
JOIN
(
SELECT O.name[ObjectName], COUNT(*)[Occurrences]
FROM sys.objects as O
GROUP BY O.name
) AS Total
ON Total.ObjectName = O.name
WHERE O.name = ERROR_PROCEDURE()
AND Total.Occurrences = 1
避免,应将OBJECT_SCHEMA_NAME(OBJECT_ID(ERROR_PROCEDURE()))
之类的内容用作传递给OBJECT_ID()
的字符串(ERROR_PROCEDURE()
不应包含)。
否则,它将默认为您的默认架构,在大多数情况下为dbo
。
运行此查询以查看在架构之间重用的所有对象名称:
--View Object Names that Exist in Multiple Schemas: - 04/08/2019 - MCR.
SELECT S.name[SchemaName], O.name[ObjectName], Total.Occurrences,
O.type[Type], O.type_desc[TypeDesc],
O.object_id[ObjectID], O.principal_id[PrincipalID], O.parent_object_id[ParentID],
O.is_ms_shipped[MS], O.create_date[Created], O.modify_date[Modified]
FROM sys.objects as O
JOIN sys.schemas as S
ON S.schema_id = O.schema_id
JOIN
(
SELECT O.name[ObjectName], COUNT(*)[Occurrences]
FROM sys.objects as O
GROUP BY O.name
) AS Total
ON Total.ObjectName = O.name
WHERE Total.Occurrences > 1
ORDER BY [ObjectName], [SchemaName]
如果只有几个重叠的对象(Sproc和触发器),那么您可能会不知道该模式,因为它的起源很明显。
但是,如果不是这种情况,那么您可能需要:
OBJECT_SCHEMA_NAME(@@PROCID)
手动添加Sproc / Trigger的架构
记录错误时,在捕获块中输入。注意:由于使用了不允许编辑的第三方存储,这些选项可能无法使用。
使用共享相同名称的多个Sproc / Trigger进行故障排除时,您可以编写一个Custom Wrapper-Sproc来调用您的第3方Sproc,然后记录包装器中引发的所有异常以确切地了解是哪个模式/ Sproc引起了该异常。 / p>
代码异味:
如果您有多个名称相同的Sproc / Triggers分布在各种模式中,则
那么我会称其为“ 代码异味”。
意思是您的架构有缺陷。
您可能没有正确封装逻辑以供重用。
有时候,名称会与模式重叠,但这很少见,而且只是出于巧合。
用于处理多租户/用户组访问的错误架构:
如果您尝试使用多租户(在同一数据库中存储来自不同组织/用户组的数据,并防止它们看到彼此的信息)并在共享对象名称的每个模式中运行几乎相同的逻辑,那么这就是设计问题。 br />
如果用户将直接访问数据,则应将数据存储在“其他数据库”中
或拥有TenantID
或UserGroupID
,当用户从自定义应用程序访问时,您总是会传入并过滤到任何地方。
答案 1 :(得分:0)
我能想到的一些可能的解决方案:
但是,这些更多来自于尝试解决您当前遇到的问题,而不是构建一些错误处理以便将来进行可能的故障排除。您总是可以使用这些存储过程将某些日志文件写入磁盘,以便在遇到错误时可以查询这些日志。