【发布时间】:2016-05-26 23:23:15
【问题描述】:
背景
我有一个多租户方案和一个独特的 Sql Server 项目,该项目将部署到同一台服务器上的多个数据库实例中。每个租户将有一个 db,外加一个“模型”db。
“模型”数据库有三个用途:
- 强制某些“系统”数据始终存在于每个租户数据库中
- 作为具有特殊权限的用户编辑系统数据的访问点(将准时同步到所有租户)
- 创建新租户时,数据库将被复制并附加一个代表租户的新名称
有触发器检查租户数据库中修改/删除的数据是否对应于“模型”数据库中的“系统”数据。如果是这样,则会引发错误,指出无法更改系统数据。
问题
下面是触发器的一部分,用于检查是否允许删除:
IF DB_NAME() <> 'ModelTenant' AND EXISTS
(
SELECT
[deleted].*
FROM
[deleted]
INNER JOIN [---MODEL DB NAME??? ---].[MySchema].[MyTable] [ModelTable]
ON [deleted].[Guid] = [ModelTable].[Guid]
)
BEGIN;
THROW 50000, 'The DELETE operation on table MyTable cannot be performed. At least one targeted record is reserved by the system and cannot be removed.', 1
END
我似乎找不到应该代替 --- MODEL DB NAME 的东西??? --- 在上面的代码中,可以让项目正确编译。当引用一个完全不同的项目时,我知道该怎么做:使用对用 SQLCMD 变量表示的项目的引用。但在这种情况下,项目引用本质上是同一个项目;仅在不同的数据库上。我似乎无法以这种方式添加自引用。
我能做什么? SSDT 是否为这种情况提供某种支持?
【问题讨论】:
-
我不明白。您是在尝试查看模型数据库或其中一个租户中的数据吗?如果是模型,只需将该名称放在您拥有它的括号内。如果是租户数据库,这将更具挑战性,因为您可能需要动态 sql。但这取决于代码的上下文。这段代码在哪个数据库上执行?
-
@SeanLange 我不能只将模型数据库的名称放在括号中。该项目将无法编译 DACPAC,并给出“未解决的对象引用”错误。同意,在纯 TSQL 中,将数据库的名称放在那里是可以做的,但我在这里使用 SSDT。 :)
-
为什么不把你的sql代码移动到一个过程中呢?您需要在某些时候将业务/显示层与数据层分开。
-
@SeanLange 我不能,该过程将无权访问触发器的已删除/插入表。即使这样做了,我仍然需要跨两个数据库的 JOIN。在程序中会有什么不同?
-
哦,是的......这是一个触发器。我的错。对我来说,这似乎是 DACPAC 中的一个错误,因为语法完全有效。
标签: sql-server visual-studio sql-server-data-tools sqlcmd dacpac