【问题标题】:Selecting data from a different schema within a stored procedure从存储过程中的不同模式中选择数据
【发布时间】:2013-05-30 12:45:49
【问题描述】:

考虑一下:

CREATE PROCEDURE [dbo].[setIdentifier](@oldIdentifierName as varchar(50), @newIdentifierName as varchar(50))
AS
BEGIN
    DECLARE @old_id as int;
    DECLARE @new_id as int;

    SET @old_id = (SELECT value FROM Configuration WHERE id = @oldIdentifierName);
    SET @new_id = (SELECT value FROM Configuration WHERE id = @newIdentifierName);

    IF @old_id IS NOT NULL AND @new_id IS NOT NULL
    BEGIN
        UPDATE Customer
        SET type = @new_id
        WHERE type = @old_id;
    END; 
END

[...]

EXECUTE dbo.setIdentifier '1', '2';

这样做是创建一个存储过程,该过程接受两个参数,然后用于更新客户表。

问题是上面的整个脚本在“dbo”以外的模式中运行。让我们假设架构是“company1”。当调用存储过程时,我从 SELECT 语句中得到一个错误,它说找不到配置表。我猜这是因为默认情况下 MS SQL 在与存储过程的位置相同的架构中查找表,而不是在调用上下文中。

我的问题是这样的:

  1. 是否有一些选项或参数或某种类型的开关会 告诉 MS SQL 在“调用者的默认模式”中查找表,并且 不在存储过程本身的架构中?
  2. 如果不是, 你会推荐什么?我真的不想给表格加前缀 使用模式名称,因为这样做有点不灵活 那。所以我正在考虑使用动态 sql(和 schema_name() 即使在过程中也返回正确值的函数), 但我只是没有足够的 MS SQL 经验来构建 正确的语法。

【问题讨论】:

  • 查看此处:stackoverflow.com/questions/1569690/… 了解潜在的解决方案。
  • 是否可以选择更改Configuration 表的架构?模式与“配置”字符串一样是名称的一部分。硬编码可能是个问题,但Softcoding
  • 好吧。语义不是。那么用户名和密码是否也是配置的一部分?根据我的经验,应用程序代码将通过连接按名称访问表,因此可以对表名进行硬编码。但是架构可以很容易地改变,我希望在不做任何代码修改的情况下实现这一点(在我的书中,一个 sql 脚本算作代码)

标签: sql sql-server


【解决方案1】:

显式指定模式名称会更有效。一般来说,模式主要用于将数据库划分为逻辑区域。我不会经常期望表模式跳跃。

关于您的问题,您可能想查看 msdn 上的“execute as”文档,因为它允许显式控制您的执行上下文。

【讨论】:

  • 感谢您的评论。我实际上尝试了execute as,但即使我使用“所有者”或“调用者”也找不到表。
【解决方案2】:

我最终将架构名称作为“sqlcmd”命令的命令行属性传递给我的脚本。像这样:

C:/> sqlcmd -vSCHEMANAME=myschema -imysqlfile

在 SQL 脚本中,我可以像这样访问这个变量:

SELECT * from $(SCHEMANAME).myTable WHERE.... etc

不如动态 sql 灵活,但“足够好”。

感谢大家花时间回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2017-08-24
    • 1970-01-01
    相关资源
    最近更新 更多