服务代理 - 跨数据库选择插入本地数据库?
Service broker - Cross-database SELECTs to insert into local DB?
我正在使用 Remus 的文章 http://rusanu.com/2006/03/07/call-a-procedure-in-another-database-from-an-activated-procedure/ 作为指南。
我想做什么:
我有一个激活的存储过程(在激活的 SP 中)调用 2 个不同的存储过程。 those 存储过程之一需要访问另一个数据库中的表以查找一些数据,之后它使用额外信息在本地写入记录。由于我正在跨数据库,我的选择是
- "trustworthy"(通过,谢谢)
- "replicate lookup tables to the same database service broker is in"
- "get certificates working"(这种做法)
所以我做了以下操作,但它仍然失败 "lock time out exceeded" 和“无法访问数据库...在当前安全上下文下。
数据库服务代理运行于:
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,但仍然不起作用。
感谢任何帮助。
看起来像元数据锁。如果您在激活过程中执行任何 DDL,例如创建索引或操作列,如果激活过程的多个实例在服务中,您可能会预期锁定超时。请记住,激活过程通常是一个很长的 运行 事务,如果它锁定任何对象,它将保持锁定状态直到事务结束。
太长 post 作为评论
not able to access database... under the current security context.
这意味着证书业务设置不正确(我不怪你,第一次尝试很难成功)。我会看看这些:
确保 'dbo' 是有效用户。在涉及的两个数据库上尝试 运行ning EXECUTE AS USER='dbo';
。如果失败(这意味着数据库是由不再有效的 Windows SID 创建的)运行 ALTER AUTHORIZATION ON DATABASE:<dbname> TO sa
。
确保您在签署后不要更改程序。任何 ALTER 都会默默地删除签名并使您的信任链无效。
add EXECUTE AS OWNER
该过程必须有一个EXECUTE AS 子句,但它是什么并不重要,只要有一个即可。您正在授予对证书的 SELECT 权限(因此对签名),因此无论程序模拟谁,它都应该有效。
对于调试,我建议您通过简单地从 SSMS 查询 window:
手动 运行 手动存储过程来完成
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
这比尝试从激活的程序进行调试更容易调试。如果这有效,则尝试相同但不是执行其他数据库存储过程,而是从 SSMS 查询 window 执行激活过程(w/o t运行ing 在队列上激活) .
我正在使用 Remus 的文章 http://rusanu.com/2006/03/07/call-a-procedure-in-another-database-from-an-activated-procedure/ 作为指南。
我想做什么:
我有一个激活的存储过程(在激活的 SP 中)调用 2 个不同的存储过程。 those 存储过程之一需要访问另一个数据库中的表以查找一些数据,之后它使用额外信息在本地写入记录。由于我正在跨数据库,我的选择是
- "trustworthy"(通过,谢谢)
- "replicate lookup tables to the same database service broker is in"
- "get certificates working"(这种做法)
所以我做了以下操作,但它仍然失败 "lock time out exceeded" 和“无法访问数据库...在当前安全上下文下。
数据库服务代理运行于:
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,但仍然不起作用。
感谢任何帮助。
看起来像元数据锁。如果您在激活过程中执行任何 DDL,例如创建索引或操作列,如果激活过程的多个实例在服务中,您可能会预期锁定超时。请记住,激活过程通常是一个很长的 运行 事务,如果它锁定任何对象,它将保持锁定状态直到事务结束。
太长 post 作为评论
not able to access database... under the current security context.
这意味着证书业务设置不正确(我不怪你,第一次尝试很难成功)。我会看看这些:
确保 'dbo' 是有效用户。在涉及的两个数据库上尝试 运行ning
EXECUTE AS USER='dbo';
。如果失败(这意味着数据库是由不再有效的 Windows SID 创建的)运行ALTER AUTHORIZATION ON DATABASE:<dbname> TO sa
。确保您在签署后不要更改程序。任何 ALTER 都会默默地删除签名并使您的信任链无效。
add EXECUTE AS OWNER
该过程必须有一个EXECUTE AS 子句,但它是什么并不重要,只要有一个即可。您正在授予对证书的 SELECT 权限(因此对签名),因此无论程序模拟谁,它都应该有效。
对于调试,我建议您通过简单地从 SSMS 查询 window:
手动 运行 手动存储过程来完成 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
这比尝试从激活的程序进行调试更容易调试。如果这有效,则尝试相同但不是执行其他数据库存储过程,而是从 SSMS 查询 window 执行激活过程(w/o t运行ing 在队列上激活) .