【问题标题】:Accessing multiple SQL databases with the same schema访问具有相同架构的多个 SQL 数据库
【发布时间】:2014-06-13 08:01:59
【问题描述】:

我正在创建一个新的 SQL 数据库,它需要连接到多个现有数据库,所有这些数据库都具有相同的架构。

我想创建可用于访问任何现有数据库的存储过程,同时尽可能重用代码。我的问题是,编写可用于访问这些现有数据库中的任何一个的通用 SP 的最佳方法是什么?

以下是我目前考虑过的一些选项。请注意,这些只是简单的代码 sn-ps 来说明问题,而不是真实世界的代码。首先我尝试打开数据库名称:

IF @db = 'A' 
BEGIN
    SELECT * FROM A.dbo.SERIES_DATA
END
IF @db = 'B' 
BEGIN
    SELECT * FROM B.dbo.SERIES_DATA
END

这样做的缺点是同一个 SQL 语句会重复多次。于是我想到了使用动态SQL:

DECLARE @Command varchar(100)
SET @Command = 'select * from ' + @db + '.dbo.SERIES_DATA'
EXEC (@Command)

这解决了重复语句的问题,但存在动态 SQL 的风险(例如注入攻击等)。所以最后我想到了创建一个表值函数:

CREATE FUNCTION [dbo].[ufnSeries_Data] (@db varchar(10))
RETURNS TABLE 
AS
RETURN (
    SELECT * FROM A.dbo.Series_Data WHERE @db = 'A'
    UNION
    SELECT * FROM B.dbo.Series_Data WHERE @db = 'B'
)
GO

这使我能够编写单个通用代码来访问任何数据库:

SELECT * FROM ufnSeries_Data(@db)

这种方法的问题在于,我必须按顺序授予系统的所有用户对所有数据库的读取权限为使此查询正常工作,否则我会收到拒绝访问错误。我也不确定创建这样的 TVF 对性能的影响。

对于如何构建代码以最大程度地减少语句重复,是否有人有任何其他想法?也许我缺少一种更简单的方法?如果有任何建议,我将不胜感激。

【问题讨论】:

  • 你能写一个VIEW 来进行连接并让存储过程查询该视图吗?
  • 你应该可以使用EXECUTE AS解决权限问题,但是我不能说性能影响部分。
  • View 是比 TVF 更好的选择
  • @adrianm 设计视图不会查询所有数据库,而 TVF 只会查询一个?在那种情况下,哪个“更好”将取决于用例。还是您有其他的视图设计?
  • @JoachimIsaksson,视图的定义不会成为执行计划的一部分,并且只访问需要的数据库/表。即如果查询包含WHERE [Database] = 'A',则只会访问数据库“A”。 TVF 的定义不是计划的一部分

标签: sql sql-server database


【解决方案1】:

您可以通过删除对数据库和架构的引用来做到这一点

SELECT * FROM SERIES_DATA

这是一个在所有数据库中创建架构并授予对数据库和架构的登录访问权限的问题(在这种情况下,您使用的是默认的 dbo 架构)。 如果您使用的是管理工作室,当您创建登录时,您可以使用用户映射来处理其余部分。 如果您有相同的架构(例如 dbo),您可以将您的选择更改为:

SELECT * FROM dbo.SERIES_DATA

您真的不想包含数据库名称,除非您要跨数据库连接表。

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多