小编Ela*_*tor的帖子

SQL Server - 向现有表添加不可为空的列 - SSDT 发布

由于业务逻辑,我们需要在表中添加一个新列,以确保始终填充该列。因此,应将其添加到表中NOT NULL。与之前解释如何手动执行此操作的问题不同,这需要由 SSDT 发布管理。

由于一些认识,我一直在用头撞墙一段时间来完成这个听起来简单的任务:

  1. 默认值不合适,不能是计算列。也许它是一个外键列,但对于其他列,我们不能使用像 0 或 -1 这样的假值,因为这些值可能具有重要意义(例如数字数据)。
  2. 在预部署脚本中添加列将在第二次自动尝试创建同一列时发布失败(即使预部署脚本被编写为幂等)(这真的很糟糕,否则我可以想一个简单的解决方案)
  3. 每次发生 SSDT 架构刷新时,在部署后脚本中将列更改为 NOT NULL 将被恢复(因此,至少我们的代码库将在源代码控制和服务器上的实际内容之间不匹配)
  4. 现在将列添加为可空,以便将来更改为 NOT NULL 在源代码管理中的多个分支/分支中不起作用,因为目标系统在下次升级时不一定都具有相同状态的表(并不是说这无论如何都是一个好方法 IMO)

我听别人说的方法是直接更新表定义(这样schema刷新是一致的),写一个预部署脚本,表的全部内容移动到一个包含新列填充逻辑的临时表,然后移动后部署脚本中的行。尽管如此,这似乎很危险,并且当它检测到一个 NOT NULL 列被添加到一个包含现有数据的表中时仍然会激怒发布预览(因为验证在预部署脚本之前运行)。

我应该如何添加一个新的、不可为空的列,而不会冒孤立数据的风险,或者在每次发布时使用固有风险的冗长迁移脚本来回移动数据?

谢谢。

null sql-server scripting ssdt

16
推荐指数
1
解决办法
5510
查看次数

SQL Server - TRY/CATCH 在某些情况下不起作用

我如何编写受保护的代码,CATCH每个预期的* 情况下调用代码块(而不是像在动态 SQL 中包装所有东西那样做一些时髦的垃圾)?

例如,这不起作用:

  1. 定义一个没有步骤的 SQL 代理作业
  2. 尝试在一个内部开始工作 TRY/CATCH

    BEGIN TRY
        EXEC msdb.dbo.sp_start_job @job_name = 'my_empty_job'
    END TRY
    BEGIN CATCH
        SELECT [MyError] = 'Error caught: ' + ISNULL(ERROR_MESSAGE(), 'NULL')
    END CATCH
    
    Run Code Online (Sandbox Code Playgroud)

消息 22022,级别 16,状态 1,第 0 行 SQLServerAgent 错误:请求运行作业 my_empty_job(来自用户 xyz)被拒绝,因为作业没有作业步骤。

请注意,其错误严重性为 16,因此它不应绕过 CATCH 块。卧槽?!?

CATCH如果作业忙于处理请求,它也会绕过我的块(我在测试中发送停止和启动请求)。

消息 22022,级别 16,状态 1,第 0 行 SQLServerAgent 错误:请求运行作业 my_simple_job(来自用户 xyz)被拒绝,因为作业已经有来自用户 xyz 的挂起请求。

相关案例:链接服务器引用无效

PS请不要假设我只想要一个处理作业调用的窄范围解决方案。我正在寻找一个可以在未来重复使用的通用解决方案。

PPS 我能够捕捉到尝试启动/停止不存在的作业的情况(“指定的@job_name ('missing_job') 不存在。”)。为什么表现不同?

*什么 TRY/CATCH 不处理(tl; dr 错误严重程度超出范围(10, 20) …

sql-server error-handling sql-server-2014

6
推荐指数
1
解决办法
1084
查看次数

SQL Server - 将 LOG 结果截断为整数时出现不一致、隐藏的机器精度错误

当将 1000 的 log base 10 转换为整数时,我注意到 SQL Server(至少 2008R2)中有一些奇怪的舍入行为。答案显然是确切的值 3,但一定有一些小数 SQL 服务器隐藏在输出中:

SELECT LOG(1000, 10)--returns 3 with no visible decimals
SELECT CONVERT(INT, LOG(1000, 10))--returns 2
Run Code Online (Sandbox Code Playgroud)

当添加到LOG转换前的结果时,我对最小 epsilon 进行逆向工程以获得正确的值,大约为:

SELECT CONVERT(INT, LOG(1000, 10)+0.0000000000000002220446049250313)
SELECT CONVERT(INT, LOG(1000, 10)+0.0000000000000002220446049250312)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

看来我可以整天继续使这个值更精确。

这似乎只在 1000 的情况下是必要的,因为我在不使用任何 epsilon 项的情况下获得了 1、10、100 和 10000 及更大的正确整数值。

错误项似乎是泰勒级数的尾部扩展了 16 项(根据本页),但是当我在 10000 及更大的情况下尝试此操作时,为什么 SQL Server 突然按预期运行(没有隐藏的机器精度错误) ?

为什么 SQL Server不一致地显示机器精度错误?

谢谢。

sql-server

4
推荐指数
1
解决办法
426
查看次数

利用具有相同排序保证的另一列上的索引

我有一个仅由自动增量列索引的表,该列还填充了当前时间戳(未编入索引)。

CREATE TABLE MyTable
(
    ID BIGINT NOT NULL IDENTITY(1, 1) PRIMARY KEY
    ,AuditTimestampUtc DATETIME NOT NULL DEFAULT(GETUTCDATE())
    ,...
)
Run Code Online (Sandbox Code Playgroud)

如果我需要通过行的创建时间戳来查询,我该如何高效地进行查询?添加索引是不可行的,因为表非常庞大(数亿到数十亿行),因为我们无法承受停机时间,而且我正在只读环境中执行罕见的调试任务,这本质上是

SELECT [...] FROM MyTable WHERE AuditTimestampUtc BETWEEN @Start AND @End
Run Code Online (Sandbox Code Playgroud)

我正在尝试调试一个新问题,之前没有做过这个任务,所以我很难提出创建新索引的论点。不幸的是,处理创建和清理完整数据库转储(特别是考虑到其大小)或将其克隆到另一个环境的请求的过程相当多。我有一个过时的转储要试验,但运行最终查询将通过生产中的只读帐户进行监督。

编写自定义二进制搜索似乎有点过头了,尤其是在 RDBMS 中,但唉计算机不是读心者,即使对于一个人来说,身份列可以用作代理排序* 以通过创建有效地搜索表,这是显而易见的时间。

*假设没有人能够IDENTITY_INSERT违反这个时间顺序保证。


PS 我不相信数据库平台第一次与这个问题非常相关(忽略声明索引/默认约束/等的特定语法差异),但我使用的是 SQL Server。

index sql-server

4
推荐指数
1
解决办法
222
查看次数

SSMS - 如何在对象资源管理器中进行不区分大小写的搜索

前言:指的不是 查询

SSMS 中有许多允许过滤的地方,例如对象资源管理器和分析器,但这些都将过滤器视为区分大小写,否则没有可见选项,因此如果您搜索,contains 'ASDF'则包括“ASDF_MyEntity”之类的值,但“asdf_MyEntity” "省略。

在此处输入图片说明

例如,我们在大型服务器上有很多SQL 代理作业,我正在尝试使用对象资源管理器按项目名称过滤它们,我们总是在作业名称前加上前缀。但是,这些显示为大写和小写变体。

另一个用例是在数千个条目中搜索与模块相关的存储过程。如果命名不一致(例如 PascalCase 与 camelCase),过滤搜索将忽略它。这对于调试来说似乎是一个不必要的幻象危险。

此外,对象资源管理器中的排序将每种类型的实体(例如表名、存储过程、作业名称等)的大写变体放在小写之前(因此大写Z在小写之前a),所以我要么必须滚动很多,或检查两个不同的过滤器(如果不是全部大写或全部小写字母,则检查更多过滤器 -准确地说是2 len(name)次)。

我意识到我只能手动查询作业和其他实体,但鉴于 SSMS 存在,这样做是荒谬的,因为它的名称是“SQL Server Management Studio”。

我可以做些什么来使 SSMS(和 SQL Server Profiler)像其他所有 Windows 应用程序一样忽略大小写?也许我可以在本地更改排序规则设置?

另外,为什么微软在实施 SSMS 时做出这个决定?我发现它只是有害的。

此外,SSMS 的加载初始屏幕显示“基于 Visual Studio 构建”,这会忽略解决方案资源管理器中的大小写。

PS 使用 SSMS 2014(版本 12.0.5214.6)。我无法进行任何服务器端更改,并且我的本地开发环境应与目标服务器环境匹配以进行测试。

sql-server collation ssms case-sensitive

3
推荐指数
1
解决办法
1486
查看次数

SQL Server 转而只使用页面文件而不是 RAM 并有效地冻结了世界

昨天我敲打我的 SQL Server 实例大约 3 个小时,运行密集计算,消耗了所有分配的物理 RAM (由于我的工作站硬件有限,我将它限制为 2GB),突然它(和许多其他东西?)释放了所有他们的内存明显切换到专门使用页面文件。

在我被迫重新启动之后,我的计算机出现了令人难以置信的滞后(仅访问电源选项就花了 10 分钟)。

我能够在重新启动之前获得任务管理器的屏幕截图(我以低更新速度在后台运行)。调整窗口大小以显示最大历史记录后,如下所示:

在此处输入图片说明

这种令人惊讶的行为导致了停机。这是记录在案的功能吗?

我正在运行带有 Enterprise 2014 数据库引擎的 Windows Server 2008 R2。

谢谢。

sql-server memory

1
推荐指数
1
解决办法
1887
查看次数