sql-server - 名称与 SQL Server 中的 sys.sysusers 系统 View 冲突

标签 sql-server

(请注意,这是在 SQL Server 2008 上,但我有一位同事在 SQL Server 2014 上报告了同样的问题。)

我正在使用一个支持多个数据库后端的框架,我们的应用程序有一个名为 sysUsers 的表,它在 MySQL 中运行良好。

我们现在需要在 SQLServer 上安装它,这个名称似乎与内置系统 View 冲突。系统 View 是sys.sysusers,应用表是dbo.sysUsers

我知道大小写差异与 SQL Server 无关,但是由于某种原因似乎忽略了架构。

  • SELECT * FROM sys.sysusers;sys.sysusers 返回记录。这完全符合预期。
  • SELECT * FROM sysUsers;sys.sysusers 返回记录。这令人惊讶(我原以为本地模式会优先)但也许可以解释。
  • 但是,SELECT * FROM dbo.sysUsers; 仍然返回来自 sys.sysusers 的记录。这似乎完全错误,因为我明确选择了 dbo 架构。

我没有在 MS 文档中找到任何说明这些名称已保留的内容。

我已经尝试重命名表并修改代码以使用不同的名称,一切正常(即这与应用程序中的 SQLServer 集成无关)并且从管理运行查询时看到相同的结果直接控制台。因此,这看起来肯定是表名冲突的问题,而不是中间件错误或语法差异。

如果这个表名是保留的,为什么 MSSMS 允许我创建它?如果不是reserved,为什么不让我查询呢?

以及我如何在不需要应用程序更新的情况下解决这个问题(因为这对于其他部署来说是一个令人头疼的迁移问题)。

最佳答案

至少有三种解决方法,但都不能保证无需重写任何代码(除了非常不安全的那个):

  • 在创建数据库时使用区分大小写的排序规则(CREATE DATABASE Foo COLLATE Latin1_General_CS_AS)。在这种情况下,sysUsers 在所有情况下都将是与 sysusers 不同的对象。您可以在创建数据库后立即设置不区分大小写的排序规则,这样您的数据就不会区分大小写,因为这可能不是最终用户想要的。显然,如果您的应用程序实际上依赖于不区分大小写的对象名称,那么这将不起作用,除非您仔细地重写您的查询。请注意,这意味着所有数据库对象(即使是之后创建的对象)都将具有区分大小写的名称,因为它在创建时嵌入到系统表中并且之后无法更改。
  • 使用 dbo 以外的架构。系统表映射仅针对该方案发生,不会针对任何其他方案发生。如果您的应用程序独占使用自己的架构,则您在其中创建的任何 sysusers 都不会别名为 sys.sysusers。 (这在任何地方都没有记录,但它是如何工作的。)请注意,为了使其工作,您必须始终明确指定模式,即使它是您用户的默认模式,否则您将再次获得系统表(我认为这是一个错误,但它可能是必要的,因为旧脚本会假定 sysusers 在任何地方解析)。
  • 启用Dedicated Administrator Connection ,以单用户模式重启SQL Server,将mssqlsystemresource数据库切换为READ_WRITEDROP VIEW sysusers。这将从所有 数据库中删除sys.sysusers这样做会使你的保修失效,如果你向他们哭诉,它会导致 Microsoft 支持人员 mock 你,这可能会导致无法安装 future 的 Service Pack 和更新,强烈建议不要这样做,但我无论如何要提一下,为了科学。任何地方的代码都不应该使用这个 View ,但是,你知道,我不是从事 SQL Server 本身工作的工程师。

请注意,降低兼容性级别不是解决方法,我提到它是为了完整性。这对如何解析这些表名没有影响,即使这是一种理想的方法(事实并非如此)。

我认为 SQL Server 2012 中所做的更改忽略了 dbo 限定符并解析为这些旧的、已弃用的名称无论如何都是一个错误,如果由我来决定,我至少会让它成为可能使用跟踪标志选择退出此行为,但这不取决于我。您可以考虑在 Microsoft Connect 上为它提出一个问题,因为当前的行为使得与 RDBMS 无关的代码的运行不必要地变得复杂。

关于sql-server - 名称与 SQL Server 中的 sys.sysusers 系统 View 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42632840/

相关文章:

java - 使用java和mysql服务器的读/写模式

SQL Server查询,对多列进行排序

SQL Server 删除字符串中小数点后的尾随零

sql - 在 MS SQL Server 2008 下的 T-SQL 中,参数 *value* 前面的 '@' 是什么意思?

Java 连接到 SQL Server 数据库 : Login failed for user 'sa'

sql-server - 使用 EF Core 从数据库获取数据时忽略实体的额外属性

sql-server - SQL哈希密码

sql - 如何检测 SQL 中两个日期时间之间的重叠?

sql-server - 用于 SQL Server 的 MySQL Workbench?

c# - 如何确保使用 EF/LINQ 不会加载行两次