【问题标题】:Why is SQL Server Database User Writing to the Wrong Schema?为什么 SQL Server 数据库用户写入错误的架构?
【发布时间】:2016-03-14 00:22:00
【问题描述】:

在我的数据库中,我有 2 个模式:[dbo][rch][rch] 被选为我们“存档”数据的名称,这样这些表不会出现在[dbo] 表之前)。

我在 SQL Server Management Studio (SSMS) 中为此表创建了一个名为 rchuser 的用户:

  • 请注意,在添加用户时,rch 被列为默认架构。

  • 请注意,此新用户同时拥有db_ownerrch

假设我有这个 SQL 插入:

public static int AddRecord(object value, string sqlConnection)
{
    int result = 0;
    using (var conn = new System.Data.SqlClient.SqlConnection(sqlConnection))
    {
        conn.Open();
        var sqlCmd =
            "INSERT INTO Table1 ([Value], [Stamp]) " +
            "VALUES (@Value, GETDATE()); ";
        using (var cmd = new System.Data.SqlClient.SqlCommand(sqlCmd, conn))
        {
            cmd.Parameters.AddWithValue("@Value", value);
            result = cmd.ExecuteNonQuery();
        }
    }
    return result;
}

我使用我的rchuser 凭据向该方法传递了一个连接字符串。

 var conn = "Data Source=localhost;Initial Catalog=DatabaseN;User Id=rchuser;Password=password;"

没有错误,结果为 1,但新记录不在我的 [rch] 架构的对应表中。

就像数据库完全忽略了这个用户默认使用[rch] 架构的事实。

我什至尝试使用rchuser 登录SSMS 数据库手动执行命令。同样,没有错误。数据进入[dbo]

如何将所有数据库输入定向到另一个架构?

【问题讨论】:

  • 哦:使用 SQL Server 2014
  • 您能否验证 Table1 存在于这个其他架构中?
  • @WiktorZychla,是的,我在另一个模式中创建了表。它不称为 Table1,目录也不是 DatabaseN。我的雇主对他上网的信息有点偏执。
  • 如果您收回 dbo 所有权(第二屏)怎么办?
  • @WiktorZychla - rchuser 然后无法打开数据库。它可能仍然可以调用代码。我没有检查那部分。根据我的理解,将[rch] 指定为默认值应该可以做到。

标签: c# database tsql sql-server-2014


【解决方案1】:

如果您在数据库中有多个模式,那么我的建议是始终明确指定您想要的模式。 Aaron Bertrand 有 a good article 说明为什么应该这样做,即使您只有一个架构。

所以修改你的sql语句为

INSERT INTO [rch].Table1...

你会好起来的。

我确实注意到这并没有回答你的标题,但它确实回答了你的问题。

至于为什么您的查询不默认为 [rch] 架构,我不知道。我在 SQL Server 2008 R2 中复制了您的设置,当我运行您的原始查询时,插入确实会按预期进入 rch 表。

编辑:

我做了一些谷歌搜索,我怀疑您的问题是由于将sysadmin 服务器角色授予rchuser 登录而引起的。我把我的改成了一个sa

,现在插入默认进入 [dbo] 模式,即使 rchuser 的默认模式是 [rch]。

因此,如果您删除 sysadmin 服务器角色,它应该会按预期开始工作。

【讨论】:

  • 赞成复制它。也许我的 SSMS 有问题。另一个答案也指定显式调用架构。
  • @jp2code 也许删除用户并重新创建它们。这可能足以让它发挥作用。
  • 感谢您的坚持。在删除并重新创建新用户之前,我必须将另一个架构的所有者重新分配给 [dbo]。现在看看它是否有效....
  • 天哪!我深入研究了该代码。引擎盖下的数据适配器经过硬编码,可以将所有内容作为“UPDATE dbo.Table...”或“INSERT INTO dbo.Table...”放在那里。我现在拥有调用该方法的方法,该方法配置为向其传递一个参数,指示这是存档数据还是实时数据。谢谢院长!你强迫我继续挖掘。
【解决方案2】:

您是否尝试在查询中为表指定架构?

var sqlCmd =
            "INSERT INTO rch.Table1 ([Value], [Stamp]) " +
            "VALUES (@Value, GETDATE()); ";

【讨论】:

  • 这可能会起作用 (+1)。不过,这是一个使用自定义数据适配器来操作数据的大型项目。大多数数据将发送到[dbo]。此特定客户的 245 个表,因此需要在自动生成的代码中查找所有 SELECT、UPDATE 和 INSERT 命令并对其进行修改以将该字段作为参数。
  • 如果你在查询中使用不支持显式模式的 orm 层,那么设置默认模式是唯一的选择。
猜你喜欢
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 2014-09-18
相关资源
最近更新 更多