服务代理 - 要插入本地数据库的跨数据库SELECT?

时间:2015-01-06 20:59:07

标签: sql-server service-broker

我使用Remus'文章http://rusanu.com/2006/03/07/call-a-procedure-in-another-database-from-an-activated-procedure/作为指南。

我想做的事情:

我有一个激活的存储过程(在Activated SP中)调用2个不同的存储过程。其中一个那些存储过程需要访问另一个数据库中的表来查找一些数据,然后在本地用额外的信息写入记录。由于我正在跨越数据库,我的选择是

  • "守信" (通过,谢谢)
  • "将查找表复制到同一个数据库服务代理是在"
  • "获得证书工作" (这种方法)

所以我做了以下操作,但它仍然失败了"锁定时间超出"并且"无法在当前安全上下文中访问数据库....

在数据库服务代理中运行:

USE database_with_service_broker_and_queue
GO
CREATE CERTIFICATE mysp_Auditing ENCRYPTION 
    BY PASSWORD = '123457' 
    with subject = 'god_i_hope_this_works'
ADD SIGNATURE TO OBJECT::myschema.mystoredprocedure 
    BY CERTIFICATE mysp_Auditing 
    WITH PASSWORD = '123457'
ALTER CERTIFICATE mysp_Auditing REMOVE PRIVATE KEY
BACKUP CERTIFICATE mysp_Auditing to file = 'c:\mysp_auditing.CER'

现在在包含附加表的数据库中:

USE db_with_tables_I_need
GO
CREATE CERTIFICATE mysp_Auditing from file = 'c:\mysp_auditing.CER'
CREATE USER mysp_Auditing FROM CERTIFICATE mysp_Auditing
GRANT AUTHENTICATE to mysp_Auditing
GRANT SELECT ON TABLE1 to mysp_Auditing
GRANT SELECT on TABLE2 to mysp_Auditing

然后我启用队列并观察滚动的错误消息。我甚至尝试更改存储过程以添加EXECUTE AS OWNER,但仍然无法正常工作。

任何帮助表示感谢。

2 个答案:

答案 0 :(得分:2)

发布评论时间太长

  

无法在当前安全上下文中访问数据库....

这意味着证书业务设置不正确(我不怪你,在第一次尝试时很难将其拉下来)。我会看看这些:

  • 确保'dbo'是有效用户。尝试在所涉及的两个数据库上运行EXECUTE AS USER='dbo';。如果一个失败(这意味着数据库是由不再有效的Windows SID创建的),请运行ALTER AUTHORIZATION ON DATABASE:<dbname> TO sa

  • 确保在签名后不更改程序。任何ALTER都会默默地删除签名并使您的信任链无效。

  

添加EXECUTE AS OWNER

该过程必须具有EXECUTE AS子句,但只要有一个,它就不重要了。您正在授予证书的SELECT权限(因此签名),因此无论过程冒充谁,它都应该有效。

对于调试,我建议您只需从SSMS查询窗口手动运行存储过程来执行此操作:

 USE myactivateddb;
 GO

 EXECUTE AS USER='dbo'; -- does not matter who, is important to be AS USER
 GO

 EXEC myotherdb.dbo.myotherproc ...;
 GO

 REVERT;
 GO

从激活的程序尝试执行此操作更容易调试。如果这样做,那么尝试相同但不执行其他DB存储过程,从SSMS查询窗口执行激活过程(没有在队列上激活时调整)。

答案 1 :(得分:0)

看起来像元数据锁定。如果在激活过程中执行任何DDL,例如创建索引或操作列,则可以预期如果多个激活过程实例正在使用,则会发生锁定超时。请记住,激活过程通常是一个长时间运行的事务,如果它对任何对象进行锁定,它会将其锁定直到事务结束。