由于业务逻辑,我们需要在表中添加一个新列,以确保始终填充该列。因此,应将其添加到表中NOT NULL。与之前解释如何手动执行此操作的问题不同,这需要由 SSDT 发布管理。
由于一些认识,我一直在用头撞墙一段时间来完成这个听起来简单的任务:
我听别人说的方法是直接更新表定义(这样schema刷新是一致的),写一个预部署脚本,将表的全部内容移动到一个包含新列填充逻辑的临时表,然后移动后部署脚本中的行。尽管如此,这似乎很危险,并且当它检测到一个 NOT NULL 列被添加到一个包含现有数据的表中时仍然会激怒发布预览(因为验证在预部署脚本之前运行)。
我应该如何添加一个新的、不可为空的列,而不会冒孤立数据的风险,或者在每次发布时使用固有风险的冗长迁移脚本来回移动数据?
谢谢。
我如何编写受保护的代码,CATCH在每个预期的* 情况下调用代码块(而不是像在动态 SQL 中包装所有东西那样做一些时髦的垃圾)?
例如,这不起作用:
尝试在一个内部开始工作 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) …
当将 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不一致地显示机器精度错误?
谢谢。
我有一个仅由自动增量列索引的大表,该列还填充了当前时间戳(未编入索引)。
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。
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 实例大约 3 个小时,运行密集计算,消耗了所有分配的物理 RAM (由于我的工作站硬件有限,我将它限制为 2GB),突然它(和许多其他东西?)释放了所有他们的内存明显切换到专门使用页面文件。
在我被迫重新启动之后,我的计算机出现了令人难以置信的滞后(仅访问电源选项就花了 10 分钟)。
我能够在重新启动之前获得任务管理器的屏幕截图(我以低更新速度在后台运行)。调整窗口大小以显示最大历史记录后,如下所示:
这种令人惊讶的行为导致了停机。这是记录在案的功能吗?
我正在运行带有 Enterprise 2014 数据库引擎的 Windows Server 2008 R2。
谢谢。