小编AMt*_*two的帖子

存储过程出错时为什么会提交部分事务?

我有一个存储过程,它首先声明一些变量,然后包含begin tran;在此之后它对提供的参数执行一些验证(并且每次提供的参数验证失败时都会增加错误计数)。如果没有错误计数,则继续执行 7 次插入。在此之后,它有commit tran;

最近我在列表中添加了第 8 个插入。隐式类型转换意味着某些插入的数据在插入时会被截断。这向 SSMS 屏幕抛出了一个错误,但我发现前 7 个插入已提交,而第 8 个显然没有完成。

我很欣赏我可以包含一个try ... catch块来处理错误,但如果一个显式begin tran;不能使整个工作块自主到commit,那么有什么意义呢?我错过了什么?

我知道我也许可以将我的程序调用包装在那个级别的事务中 - 但是有人可以解释发生了什么以及为什么begin tran当包含在程序主体中时似乎不受尊重吗?如果调用该过程开始一个隐式事务,那么 proc 中的错误步骤不应该回滚受 proc 影响的所有更改 - 即使没有明确包含begin tran在 proc 主体中?

sql-server stored-procedures transaction

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

sp_send_dbmail 导致会话挂起

昨天我们在生产 (2008R2 SP3) 中遇到了一个问题,开发人员在 SSMS 中运行一段代码,该代码在sp_send_dbmail事务内执行,并包含来自另一台服务器上的网络共享的附件。

开发人员报告代码“似乎比预期花费的时间更长”并试图停止查询。当查询未能停止时,他让我终止他的查询。

使用sp_WhoIsActive,我收集了有关会话的以下信息:

  • PREEMPTIVE_OS_GETPROCADRESS 等待继续上升
  • 极低的 CPU、内存、IO 使用率
    • 几乎所有的时间都花在等待上
  • KILLED/ROLLBACK 状态
  • 有 1 个未结交易
  • 持有架构修改锁,导致严重阻塞
  • 当前语句正在执行 xp_sysmail_attachment_load
    • 调用堆栈是sp_send_dbmail--> sp_GetAttachmentData-->xp_sysmail_attachment_load

由于 PREEMPTIVE_OS 等待,在操作系统产生/返回之前,无法从 SQL Server 终止会话。使用 TCPView,我确认没有从 SQL Server 到带有附件的文件服务器的活动网络连接。我不知道是否有一个连接已经断开连接,或者它是否从未建立连接。

根据数据,我的假设是访问附件时存在一些问题,导致会话挂起,并且操作系统进程永远不会产生/返回。

由于这会导致阻塞而影响生产,因此我们最终将 FCI 故障转移到另一个节点,因此实例重启将迫使会话终止。

我的问题是:

  • 有什么方法可以可靠地识别 SQL 正在等待的操作系统进程吗?(因此尝试“帮助”该过程返回 - 杀死它等)
  • 来自另一个方向:有没有办法强制会话停止等待具有 PREEMPTIVE_OS 等待的操作系统,以便我们可以在不重新启动 SQL 的情况下杀死它?
  • 在这种情况下是否有一些因素使会话xp_sysmail_attachment_load更有可能挂起?(我正在处理一个重现案例,但还不能可靠地重现这个。)
  • 如果此问题再次发生,我可以/应该在其他地方查找其他信息吗?

sql-server sql-server-2008-r2 database-mail

6
推荐指数
0
解决办法
1030
查看次数

如何在给定的 SPID 中获取查询的完整 SQL 文本运行

任何人都可以帮助我吗,要么给我查询,要么给我指出一篇文章,因为我似乎找不到一篇文章。

我有一个引发错误的会话的 SPID,我们需要知道该 SPID 运行的查询的完整 SQL 文本。

有人可以帮忙吗?

请注意,我已尝试以下操作,但没有一个给我完整的 SQL 文本:

DECLARE @sqltext VARBINARY(128)
SELECT @sqltext = sql_handle
FROM sys.sysprocesses
WHERE spid = 174
SELECT TEXT
FROM sys.dm_exec_sql_text(@sqltext)
GO

SELECT
sysprc.spid,sysprc.waittime,sysprc.lastwaittype,DB_NAME(sysprc.dbid) AS database_name,
sysprc.cpu,sysprc.physical_io,sysprc.login_time,sysprc.last_batch,sysprc.status,
sysprc.hostname,sysprc.[program_name],sysprc.cmd,sysprc.loginame,
OBJECT_NAME(sqltxt.objectid) AS [object_name],sqltxt.text
FROM sys.sysprocesses sysprc 
OUTER APPLY sys.dm_exec_sql_text(sysprc.sql_handle) sqltxt
where spid = 174


DBCC INPUTBUFFER(174)
go

Run Code Online (Sandbox Code Playgroud)

sql-server

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

.bacpak 文件中的 .BCP 文件是什么?

在 dba.stackexchange.com 上潜水我找到了一个很好的答案,教我如何.bacpac使用文件资源管理器打开文件。

我用数据库试了一下,AdventureWorks2008R2我所做的就是:

  1. 将数据库保存为.bacpac文件
  2. 将文件扩展名重命名为 .zip
  3. 解压

好了,您可以将数据库的表作为文件夹查看,并且在每个文件夹中您可以查看原始数据。

在此处输入图片说明

但是当我打开文件夹时,Person.Address我看到里面有 38 个扩展名为.BCP.

在此处输入图片说明

一开始我教他们是数据被分割的页面。但那些不能是页面,因为它们的重量约为67KB. 页面应该权重8KB

所以我用这个查询检查了页数:

-- Total # of pages, used_pages, and data_pages for a given heap/clustered index
SELECT 
    t.NAME AS TableName,
    p.rows AS RowCounts,
    SUM(a.total_pages) AS TotalPages, 
    SUM(a.used_pages) AS UsedPages, 
    (SUM(a.total_pages) - SUM(a.used_pages)) AS UnusedPages
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql bacpac

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

为什么 SQL Server 中没有“夏令时”时区?

我正在将一些 datetimeoffset 列的时间从 UTC 转换为东部时间。我通过命令执行此操作

UPDATE MyTable SET MyColumn = MyColumn AT TIME ZONE 'Eastern Standard Time'
Run Code Online (Sandbox Code Playgroud)

这似乎工作正常(时间提前了 4 小时,现在有 -04:00 偏移量,正是我想要的),但后来我意识到这不是 EST,现在是 EDT。

SELECT * FROM sys.time_zone_info 
Run Code Online (Sandbox Code Playgroud)

给我一个时区列表,但没有“东部夏令时间”,只有“东部标准时间”。有一个“is_current_dst”列似乎是正确的。但据我所知,谈论时区“东部标准时间”是否处于 DST 是没有任何意义的。东部标准时间意味着它不是夏令时。“东部夏令时”的意思是夏令时。对我来说,这似乎是获得一个动物列表,列表中没有“Dog”和“Cat”,只有“Dog”,带有“isCat”标志!

我很困惑为什么时区被称为“东部标准时间”(以及为什么我上面的更新语句将时间转换为东部夏令时间(又名 UTC -04:00)。

时区名称是否不正确,它实际上应该只是“东部时间”之类的内容,并带有标志告诉当前是 EST 还是 EDT?

或者我只是完全困惑?

sql-server timezone

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

如何由于连接 2 个良好估计的结果而更正行估计

以下查询在约 60 个数据库上并行运行。在没有提示的情况下,至少 10% 的数据库存在大量溢出和非最佳计划。

使用更大的数据库作为指导,查询被锁定并带有提示(1 个 CPU 上约 75 毫秒),以减少运行时的差异,因为 1 个错误的计划会导致整体运行时间终止。我们主要反对让每个DB自由调整其计划,因为从长远来看,某些DB可能会在生产平台上着火。我们对大型数据库的近乎最佳计划感到非常满意,但对于较小的数据库可能不是最佳的。

即使在添加带有完整扫描的统计信息后,一些(~5)较小的数据库仍然表现出小的 1 级溢出(参见计划)。运行时间仍然可以(125 毫秒),但希望消除溢出。

这是 Sql Server 2019。自适应授权功能 (2017) 是否应该因溢出而调整授权?在 SSMS 和查看计划中重复运行它似乎表明没有变化。

select top (@pMax)
           aig.ObjectId,  
           iif((@pA in (1, 2, 3, 4, 5, 6, 9, 11, 12) and ttm.ObjectId is not null) or
               (@pA in (7, 8, 10, 13, 14, 15)), 1.0, 0.0) as Rank
      from oav.value aig               
      inner merge join Pub.CachedObjectHierarchyAttributes coha
        on coha.ObjectId = aig.ObjectId
       and coha.IsActiveForPublisher = 1
       and coha.IsToolItem = 1
      inner merge …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan cardinality-estimates query-performance

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

保留每个表中每个值的完整历史记录

您将如何保留数据库中所有表的每个值的完整历史记录,可以使用特定日期(对于所有表的每一列)进行查询?我的意思是:人们只需要指定一个日期,该日期的值是“活动”或“有效”。

以一种愚蠢的方式,我会在每个表中添加一个“有效期开始日期”列。而不是复制每个值,我只会复制更改的值,并将所有其他列设置为 NULL。然而,这个解决方案真的很糟糕,因为它使查询复杂化,即使它占用的空间更少。

是否有一种特定的技术(我在 Microsoft 世界中)可以做到这一点,或者有一种特定的方法来为数据库建模来做到这一点(除了为每个表的每一列创建一个表)?

我想提一下,我不是 DBA 而是开发人员。赞!赞!

database-design sql-server t-sql

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

恢复两周前已更改的存储过程

我不小心更改了 Microsoft 2016 SQL 数据库上的存储过程。然后我注意到报告方投诉后的变化。做了一些更改并运行但没有工作。不是我需要恢复两周前存储的过程。谁能解释一下这个过程。

sql-server

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

如何保留 varchar 字段的前导零

将带有前导零的数字保存到字符串变量或列中时,前导零将被截断。

当我运行此查询时:

declare @varchar as nvarchar(50)
set @varchar = 011
print @varchar
Run Code Online (Sandbox Code Playgroud)

我得到的结果是 11。

有没有办法得到011?

sql-server ssms

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