Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 获取返回错误的存储过程的架构_Sql Server 2008_Tsql_Error Handling_Database Schema - Fatal编程技术网

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多年了。。。。