我正在通过源服务器上的视图从链接服务器查询数据。该视图必须包含几个标准化列,例如Created
,Modified
和Deleted
,但在这种情况下,源服务器上的表没有任何合适的信息。因此,列被显式转换为它们各自的类型。我更新了视图,从
NULL AS Modified
Run Code Online (Sandbox Code Playgroud)
到
CAST(NULL as DateTime) as Modified
Run Code Online (Sandbox Code Playgroud)
但是,执行此更新后,视图会触发以下错误消息:
消息 7341,级别 16,状态 2,第 3 行无法从链接服务器“”的 OLE DB 提供程序“SQLNCLI11”获取列“(用户生成的表达式)。Expr1002”的当前行值。
我们已经在源服务器上完成了这种“显式转换” - 无需担心,我怀疑这个问题可能与所涉及的服务器版本有关。我们真的不需要应用这个演员表,但感觉更干净。现在我只是好奇为什么会发生这种情况。
服务器版本(来源):
Microsoft SQL Server 2012 - 11.0.5058.0 (X64) 2014 年 5 月 14 日 18:34:29 版权所有 (c) Microsoft Corporation Enterprise Edition(64 位),Windows NT 6.1(内部版本 7601:Service Pack 1)(管理程序)
服务器版本(链接):
Microsoft SQL Server 2008 R2 (SP1) - 10.50.2500.0 (X64) 2011 年 6 月 17 日 00:54:03 版权所有 (c) Microsoft Corporation Enterprise …
有两个原因促使我提出这个问题:
tSQLt当存在具有非默认排序规则的列时
,T-SQL 测试框架 tSQLt 将其视为“高严重性”问题。测试的作者声明如下:
我并不是建议每个字符串列都应该有一个与数据库的默认排序规则相匹配的排序规则。相反,我建议当它不同时,应该有一个很好的理由。
然而,如前所述,失败测试的严重性被认为是高的。
八达通部署
在配置八达通部署服务器时,在八达通服务器实例的初始化过程中,设置失败并出现致命错误。与错误消息相关的文章并没有解释为什么这是一项要求,而只是说明它将成为未来部署的一项要求,包括 Octopus 3.8 版。
附带说明一下,RedGate 的 CI 工具包DLM 自动化套件支持具有不同排序规则的部署而不会出现投诉。
将所有列排序规则保留为数据库默认值的建议对我来说更像是指南或最佳实践。为什么有人认为这是一个严重的错误?
我的 SSIS 包的控制流未按预期运行。
我想要实现的目标:
测试是否在 SQL Server 上启用了 CLR 使用
SELECT value
FROM sys.configurations
WHERE name = 'clr enabled'
Run Code Online (Sandbox Code Playgroud)
value == 0
,尝试启用 CLR 并显示消息Server is configured.
value == 1
, 显示消息Server is configured.
此流程按预期工作。但是,我想,如果value == 0
,在 之后继续 MessageBox Enable CLR on Server
。
现在,发生的事情是这样的:
value == 0
[CLR Enabled on Server] 将控制交给 [Enable CLR on Server],完成并退出。value == 1
[CLR Enabled on Server] 完成并退出。[MessageBox- 服务器已配置] 永远不会到达。
任何人都可以帮助我理解这一点,和/或向我指出有关 SSIS 条件控制流的好资源吗?
我目前有一个相当大的表(5-7 百万行)。该表由一个过程定期重建,该过程在临时表中构建数据,然后使用该ALTER TABLE .. SWITCH TO ..
语句将数据切换到生产表中。
例子:
BEGIN TRAN;
-- Rebuild indexes
ALTER INDEX IX_NC_GroupEvent_staging_GroupName on [dbo].[GroupEvent_staging]
REBUILD;
ALTER INDEX IX_NC_GroupEvent_staging_Created ON [dbo].[GroupEvent_staging]
REBUILD;
-- Empty production table
TRUNCATE TABLE [dbo].[GroupEvent];
-- Switch data from staging-table into production table
ALTER TABLE [dbo].[GroupEvent_staging] SWITCH TO [dbo].[GroupEvent]
COMMIT;
Run Code Online (Sandbox Code Playgroud)
执行此操作时,索引(或索引数据)的当前状态是否也会切换?我问是因为两个原因:
1) 为了执行SWITCH TO
语句,要求源表和目标表必须包含相同的索引。这让我相信索引数据也可能会被切换,但我不知道如何验证这一点。
2)以这种方式构建表的主要好处是避免在使用生产表时对生产表执行过多的工作。当然,如果我能够在临时表上重建索引并将重建的索引与表一起切换到生产索引,那会让我感到非常高兴。
我正在经历一些THROW
我无法理解的行为。考虑以下存储过程:
CREATE PROCEDURE usp_division_err AS
SET NOCOUNT ON;
BEGIN TRY
EXEC('select 1/0')
END TRY
BEGIN CATCH
THROW;
END CATCH
Run Code Online (Sandbox Code Playgroud)
执行该过程时,会引发以下错误:
消息 8134,级别 16,状态 1,第 1 行
遇到除以零错误。
请注意,没有包含有关在哪个过程中引发错误的信息。那是因为错误的动态 SQL 在另一个作用域中执行,这很好。但是,将CATCH
-block更改为如下所示
BEGIN CATCH
THROW 50000, 'An error occurred.', 1;
END CATCH
Run Code Online (Sandbox Code Playgroud)
并且该过程的执行将引发此错误:
Msg 50000, Level 16, State 1, Procedure usp_division_err, Line 7 [Batch Start Line 0]
发生错误。
执行动态SQL时仍然遇到错误,但是当我手动指定错误号和错误消息( 的第一个和第二个参数THROW
)时,不知何故出现了执行过程的procedure-name。
为什么过程名称出现在第二个错误消息中而不是第一个错误消息中?
问题:在 SQL Server 2016 中,将列更新为相同的值(例如将列从'john'
to更新'john'
)是否会产生与将列更新为不同值时相同数量的事务日志?阅读下文了解更多详情。
我们有几个 SQL 代理作业按计划运行。这些作业从源表(复制数据、链接服务器)中选择数据,对其进行转换,然后相应地插入/更新/删除本地目标表的行。
在试图找到实现这一目标的最佳方式时,我们经历了各种策略。我们试过了
现在,我只是一个初级 DBD,我对事务日志如何工作的理解非常有限。话虽如此,我的前辈已经得出结论,我们不能使用 MERGE 或 UPDATE 语句,其中所有列都在同一语句中处理,因为它会创建过多的日志记录。对此的论点是,当您UPDATE
在 SQL Server 中执行 -语句时,当您设置列值并且新值等于旧值时,它仍会在事务日志中标记为更新。当您执行大量无意义的 SET 操作时,这显然会变得昂贵。
在以下示例中,我们使用源表中的值更新目标表的first_name
和last_name
,由 连接id
。
-- create source- and target-table
CREATE TABLE [#tgt] (
[id] Int PRIMARY KEY,
[first_name] NVarchar(10),
[last_name] NVarchar(10)
)
CREATE TABLE [#src] (
[id] Int PRIMARY KEY,
[first_name] NVarchar(10),
[last_name] NVarchar(10)
)
-- fill some dummy-data …
Run Code Online (Sandbox Code Playgroud) 我推迟问这个问题有一段时间了,因为在没有文字墙的情况下很难概括我们的情况和挑战,但情况越来越糟,所以我会尽力而为。我正在寻求一些帮助,以改进我们开发和管理应用程序数据库和开发人员环境的方式,特别是在跨环境的数据库依赖项方面。
我们是一家拥有大量遗留代码的中型公司。为了了解我们当前的应用程序数据库是什么样子,这里有一些大致的数字:50GB、450 个表、200 个视图和 400 个存储过程。此外,我们的生产服务器运行大约 15 个数据库,其中大部分需要或被我们的应用程序数据库需要。
澄清一下:当我说“需要”时,我指的是不会编译/将编译但不会在没有依赖项的情况下运行的数据库对象。这些对象的示例是链接服务器和复制订阅等服务器对象,或存储过程和视图等数据库对象。
在过去的一年中,我们对开发和部署数据库的方式进行了重大改进。迄今为止的改进包括引入专用开发人员环境、(几乎)所有数据库代码的版本控制、从 Git(基于触发器)自动部署以及向 SQL Server 集群的过渡。
我们正在努力解决的问题是如何处理从我们的应用程序数据库到其他数据库的依赖关系,而我似乎找不到合适的资源。这些依赖关系分为两个不同的挑战:
1. 同一台服务器上的数据库
目前来说,我们的应用数据库依赖于同一台服务器上的 5 个数据库。这些是具有单独存储库、部署管道、库和 Web 项目的数据库。在引导开发人员环境时,我们必须注意以特定顺序创建这些环境,以便成功应用 DDL 和 DML 脚本,以免我们面临依赖错误。仅此过程就引起了很多头痛。事实上,它引起了如此多的头痛,以至于我们的一些开发人员干脆放弃了本地开发人员环境,并在共享数据库中进行所有开发。
2. 远程服务器上的数据库只能用于生产
在我们的生产环境中,我们从少数远程 SQL Server 实例导入数据。其中一些数据是使用存储过程导入的,这些存储过程使用链接服务器对象引用远程服务器。为了运行存储过程,链接服务器对象需要存在。为了使链接服务器对象“成功”存在,它引用的远程服务器必须是可访问的。远程服务器只能从我们的生产服务器访问(这是正确的),但这会导致我们的存储过程在部署期间无法正确编译。
在“持续交付”一书中,作者 Dave Farley 强调,在真正的持续集成中,组装和运行项目所需的每一个资源都应该驻留在其存储库中。此外,他还指定每个环境都应该相同(凭据和连接字符串等配置除外)。我们的应用程序不满足这些原则,我什至不确定这样做是否可行。
我们的工具
感觉就像我在这里错过了一些核心架构原则。我们可以做些什么来缓解这些问题?也欢迎对相关文献提出建议。
sql-server best-practices development continuous-integration
在编写程序时,我偶尔会遇到我想中止程序的情况,即使这种情况不一定会触发错误。
比方说,如果我不希望 John 能够运行这个程序,我会做这样的事情:
IF @UserName = 'John'
BEGIN
RAISERROR('John, get out', 16, 1);
RETURN 1;
END
Run Code Online (Sandbox Code Playgroud)
我真的没有一个很好的理由返回 1,它主要是 shell 脚本的残余,我愿意接受更好的方法来做到这一点。
是否有更好的方法来返回错误消息并将控制权返回给调用者,以应对严格来说不是错误的不需要的情况?我对减少字符或代码行数不感兴趣。我只是有一种直觉说“这可能不是解决这个问题的最佳方法”,我很好奇是否有更聪明的方法来做到这一点。
一种替代方法是始终使用TRY/CATCH
,因为RAISERROR
严重性为 1-19 会将控制权交给 catch 子句。
例子:
BEGIN TRY
PRINT 'Before RAISERROR';
RAISERROR('Time for errors', 16, 1);
PRINT 'After RAISERROR'
END TRY
BEGIN CATCH
DECLARE @Msg NVARCHAR(255) = ERROR_MESSAGE()
PRINT 'Inside CATCH'
RAISERROR(@Msg, 16, 1)
END CATCH
Run Code Online (Sandbox Code Playgroud)
输出:
IF @UserName = 'John'
BEGIN
RAISERROR('John, get out', 16, 1);
RETURN 1;
END
Run Code Online (Sandbox Code Playgroud)
缺点:需要TRY/CATCH
块的存在。
我们有一个稍重的表,它半频繁地(每约 5 分钟)由程序重新创建。我想知道是否可以做些什么来最大限度地减少表重建期间的停机时间,并且到目前为止已经想到了两种可能性(让我们称表为“设备”):
选项 A
1) 在过程中创建新表,命名Device_new
2) 将旧表重命名Device
为Device_old
3) 将新表重命名Device_new
为Device
选项 B
与选项 A 相同,只是使用分区切换。
警告:分区切换的设置要复杂得多,并且对使用有相当严格的要求。
这些选项是否是糟糕的解决方案,如果是,您将如何解决此用例?谢谢你。