Sql server 2008 获取返回错误的存储过程的架构
我有几个同名但模式不同的过程。当这些过程引发错误时,是否可以在父过程(调用这些嵌套存储过程)中获取引发错误的过程的架构?例如,我可以从Sql server 2008 获取返回错误的存储过程的架构,sql-server-2008,tsql,error-handling,database-schema,Sql Server 2008,Tsql,Error Handling,Database Schema,我有几个同名但模式不同的过程。当这些过程引发错误时,是否可以在父过程(调用这些嵌套存储过程)中获取引发错误的过程的架构?例如,我可以从ERROR\u PROCEDURE()中获取名称,但是否有一些选项也可以获取模式?因为否则,如果有许多相同名称的过程,我不确定哪个过程会抛出错误 我想这项功能还是没有 但是否有一些解决方法?我可以想到一些可能的解决方案: 重命名每个存储过程,使它们在不同的架构中具有不同的名称 将一些调试输出添加到存储过程中,以便在执行这些过程时,可以看到错误发生时正在进行的调
ERROR\u PROCEDURE()
中获取名称,但是否有一些选项也可以获取模式?因为否则,如果有许多相同名称的过程,我不确定哪个过程会抛出错误
我想这项功能还是没有
但是否有一些解决方法?我可以想到一些可能的解决方案:
- 重命名每个存储过程,使它们在不同的架构中具有不同的名称
- 将一些调试输出添加到存储过程中,以便在执行这些过程时,可以看到错误发生时正在进行的调试输出
- 运行SQL探查器以查看发生错误时调用的内容
然而,这些都是从尝试解决您现在遇到的问题的角度来考虑的,而不是构建一些错误处理,以便将来进行潜在的故障排除。您可以随时让这些存储过程将一些日志文件写入磁盘中的某个位置,以便在遇到错误时可以查询这些日志。遗憾的是,SQL Server中没有100%的解决方法来解决此限制。
MSSQL开发团队在十多年后没有纠正这一点,这让他们感到羞耻。
它应该像添加一个新函数一样简单,比如
ERROR\u ProcedureSchema()
或ERROR\u PROCID()
这是一篇2005年5月重新发布的请求此功能的帖子:
我更喜欢在自定义错误处理逻辑中记录尽可能多的异常细节。
这是我找到架构名称的最佳方法:
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\u SCHEMA\u NAME(OBJECT\u ID(ERROR\u PROCEDURE())
的任何东西,因为传递到OBJECT\u ID()
中的字符串应该已经包含架构(而ERROR\u 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]
如果您只有几个重叠的对象(存储过程和触发器),那么您可能不知道模式,因为模式的起源可能很明显。但是,如果情况并非如此,则您可能需要:
这个选择违背了我的本性
对象\u架构\u名称(@@PROCID)
当记录错误时,在Catch块中当使用多个共享相同名称的存储过程/触发器进行故障排除时,您可能可以编写一个自定义包装存储过程来调用第三方存储过程,然后记录在包装中引发的任何异常,以确切了解是哪个架构/存储过程导致了它 代码气味:
如果有多个同名存储过程/触发器分布在不同的模式中
那我就称之为“代码气味”。
也就是说,您的体系结构存在缺陷。
您可能没有正确封装逻辑以供重用。
有时名称会与模式重叠,但这应该很少见,而且只是巧合 盗用架构来处理多租户/用户组访问:
如果您正在尝试多租户(将来自不同组织/用户组的数据存储在同一数据库中,并阻止它们查看彼此的信息),并且在共享对象名称的每个架构中运行几乎相同的逻辑,那么这就是设计问题。
如果用户将直接访问您的数据,那么您的数据应该位于不同的数据库中
或者拥有一个
TenantID
或UserGroupID
当用户从自定义应用程序访问时,您总是在任何地方传入并过滤。在error\u procedure()
文档页面中,有一条2017年5月25日的评论,距离2008版发布已有10多年了。。。。