我有几个相同名称但程序不同的程序。当这些过程引发错误时,父进程(调用这些嵌套的存储过程)可能会获得引发错误的过程的模式吗?例如,我可以从ERROR_PROCEDURE()
获得名称,但是还有一些选项可以获得SCHEMA吗?因为否则我不确定如果有许多具有相同名称的错误,那么确切的过程会引发错误。
但是有一些解决方法吗?
我能想到的一些可能的解决方案:
但是,这些更多来自于尝试解决您现在遇到的问题,而不是构建一些错误处理,以便将来进行故障排除。您总是可以使用这些存储过程将某些日志文件写入磁盘,以便在遇到错误时可以查询这些日志。
遗憾的是,SQL-Server中没有针对此限制的100%解决方法。
对MSSQL开发团队感到羞耻,因为没有对此进行纠正,以后会在十年内完成。
它应该像添加像ERROR_ProcedureSchema()
或ERROR_PROCID()
这样的新函数一样简单。
这是从2005年5月开始请求此功能的复活帖子:
https://feedback.azure.com/forums/908035-sql-server/suggestions/32894584-schema-not-reported-in-the-error-procedure-functio
我更喜欢尽可能详细地记录我在自定义错误处理逻辑中捕获的异常。 这是我能找到的最好的Schema名称:
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()
的字符串应该已经包含了Schema(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]
如果你只有几个重叠的对象(Sprocs和Triggers),那么你可能不知道Schema,因为它可能是显而易见的。 但是,如果不是这种情况,那么您可能需要:
OBJECT_SCHEMA_NAME(@@PROCID)
的Sproc / Trigger的Schema。注意:由于使用了不允许编辑的第三方Sproc,可能无法使用这些选项。 使用共享相同名称的多个Sprocs / Triggers进行故障排除时,您可以编写一个Custom Wrapper-Sproc来调用您的第三方Sproc,然后记录Wrapper中抛出的任何异常,以确切知道哪个Schema / Sproc引起了它。
守则气味: 如果您有多个Sprocs / Triggers具有相同的名称,分布在不同的Schema中 然后我会称之为“代码嗅觉”。 意思是,您的架构存在缺陷。 您可能无法正确封装逻辑以供重用。 有时名称会与Schemas重叠,但这应该是罕见的,而且只是巧合。
挪用模式处理多租户/用户组访问:
如果您正在尝试多租户(在同一数据库中存储来自不同组织/用户组的数据并阻止他们查看彼此的信息)并在每个共享对象名称的模式中运行几乎相同的逻辑,那么这就是设计问题。
如果用户将直接访问它,您应该将数据放在不同的数据库中
或者有一个TenantID
或UserGroupID
,当用户从自定义应用程序访问时,你总是传入并过滤到任何地方。