如何使存储过程从其当前执行范围之外引用DB

时间:2013-12-16 17:56:39

标签: sql-server sql-server-2005 stored-procedures

我有2个DB,构建和联系人,以及从Building DB,building_sp执行的存储过程。

building_sp需要更新联系人中的表TblContact,并且他们引用它的方式是

[Contact].dbo.[TblContact]

由于Contact表可以任意命名,我需要删除这个依赖项。

我可以使用 NOT 选项

  • 将存储过程逻辑移动到代码(即.NET控制器,其中可以在Web服务配置文件中设置Contact DB名称)。
  • 将Contact DB名称存储在Building DB中的元表/行中。
  • 将包含Contact DB名称的字符串变量传入building_sp。

任何关于此的建议或帮助都将受到赞赏,即使只是粗略的想法或部分答案。感谢。

2 个答案:

答案 0 :(得分:1)

我会选择option1:有2个DataAccess组件,一个用于构建,一个用于Contact,让.NET组件(控制器)在事务中调用DAL上的操作(参见TransactionScope类)。

为什么?

  • 稍后,您可能决定将这两个数据库移到不同的位置 机
  • 避免低耦合
  • 稍后您可能会调用第三个数据库,因此您有2个传递2个数据库名称或从SP访问许多数据库
  • 您可能需要调用其他服务(例如发送邮件),在.NET中执行此类操作更为自然
  • 尊重开放/关闭原则:如果联系更新逻辑发生变化,则无需触及构建逻辑,因此影响较小,测试时间较少,产生回归的机会较低
  • 我让其他人在这里添加其他原因......

答案 1 :(得分:0)

我最终将联系人DB名称存储在web.config应用程序设置

<configuration>
   …
  <appSettings>
    …
    <add key="ContactDBName" value="ContactDataBase"/>
  </appSettings>
  …
</configuration>

然后我将其读入Application_Start()

的全局静态字符串
public class WebApiApplication : System.Web.HttpApplication
{
    public static string ContactDBName;

    protected void Application_Start()
    {
        ...        
        ReadContactDBNameFromConfig();
    }

    protected void ReadContactDBNameFromConfig()
    {
        System.Configuration.Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/WebServiceName");
        System.Configuration.KeyValueConfigurationElement contactDBNameElement = rootWebConfig.AppSettings.Settings["ContactDBName"];

        ContactDBName = contactDBNameElement.Value;
    }
}

我还将存储过程存储到字符串中,使用“占位符”文字“{0}”作为数据库名称。

public static string BUILDING_SP = 
@"BEGIN TRANSACTION 
    ...
    UPDATE [{0}].[dbo].[TblContact]
    SET param1 = @Param1,
        param2 = @Param2,
        ...
    WHERE record_id = @RecordID
    ...     
COMMIT";

然后我使用String.Format设置具有数据库名称

的占位符
string sql = String.Format(BUILDING_SP, WebApiApplication.ContactDBName);

然后通过SqlCommand对象执行该字符串。