小编you*_*gme的帖子

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

我有一个存储过程,它首先声明一些变量,然后包含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
查看次数

解释 OVER 子句

我看到了一个简洁的 TSQL 语句,它有效地将字符串拆分为其组成字符,每行一个,目的是评估ascii每个字符的值。

如果我正确地、有效地阅读了查询,将使用 3 个 CTE 来准备一个包含 10,000 行的 1 列表,每行的值为“0”。

第四个 CTE 定义如下:

cteTally(n) AS(
    SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n 
    FROM E4
)
Run Code Online (Sandbox Code Playgroud)

随后,这个 CTE 被连接到一个包含感兴趣字符串列的表中,如下所示select

SELECT n, SUBSTRING(LastName, n, 1), ASCII( SUBSTRING(LastName, n, 1))
Run Code Online (Sandbox Code Playgroud)

也就是说,行号 n,然后是 LastName 中的第 n 个字符,然后是该字符的 ascii 值。

我的问题与over上述 CTE 中的条款有关。

本质上,它到底在做什么?

如果我们从 10,000 个相同的行中查询 row_number,为什么我们根本需要一个order by子句?为什么order by放入over条款,而不是作为一个order by在子句select声明-尤其是在over条款甚至没有指定任何分区?(我认为这意味着操作的窗口row_number是完整的 …

sql-server t-sql window-functions

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

必须引用数字 JSON 键吗?

我已经注意到,当 TSQL JSON 字符串中的数字时,键值值可能不加引号,但似乎必须始终引用关键组件。

select 1, isjson(''), 'empty string' union
select 2, isjson('{}'), 'empty braces' union
select 3, isjson('{1:2}'), 'unquoted both, numerals both' union
select 4, isjson('{1:"2"}'), 'unquoted key, numerals both' union
select 5, isjson('{"1":2}'), 'unquoted value, numerals both' union
select 6, isjson('{"1":"2"}'), 'quoted both, numerals both' union
select 7, isjson('{a:b}'), 'unquoted both, alpha both' union
select 8, isjson('{a:"b"}'), 'unquoted key, alpha both' union
select 9, isjson('{"a":b}'), 'unquoted value, alpha both' union
select 10, isjson('{"a":"b"}'), 'quoted both, alpha …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql json

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

sp_send_dbmail 返回值是什么?

我有一封电子邮件失败,函数返回值为“101”,@@error 值为“0”(没有添加行sysmail_allitems)。

在哪里可以找到有关此函数返回代码的文档?

显示我如何获得上述值的示例代码:

exec @result = msdb.dbo.sp_send_dbmail
    @profile_name = 'OBFUSCATED',  
    @recipients = @DL,  
    @subject = 'OBFUSCATED',
    @body = @emailBody,
    @body_format='html',
    @query = @reportQuery,
    @exclude_query_output = 1,
    @attach_query_result_as_file = 1,
    @query_attachment_filename = @filename,
    @query_result_separator = @temp,
    @query_result_header = 1,
    @mailitem_id = @mailitem_id
    ;

    set @temp = @@ERROR;
Run Code Online (Sandbox Code Playgroud)

sql-server database-mail

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

为什么 CASE 语句中的 JSON_QUERY 无法删除转义字符?

json_query如果在case语句中应用该函数,则似乎无法删除双引号字符 (") 的转义字符。

下面的示例代码。

declare @data nvarchar(max);
declare @debug int = 0;

set @data = '{"id":10}';

set @debug = 0;
select
    isjson(@data) as 'validateData',
    @data as 'unprocessedSourceData',
    json_query(@data) as 'processedSourceData',
    case when @debug = 1 then json_query(@data) else null end as 'conditionallyProcessedSourceData'
    for json path, without_array_wrapper ;

set @debug = 1;
select
    isjson(@data) as 'validateData',
    @data as 'unprocessedSourceData',
    json_query(@data) as 'processedSourceData',
    case when @debug = 1 then json_query(@data) else null end as 'conditionallyProcessedSourceData'
    for json path, without_array_wrapper …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql json sql-server-2016

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

正确转义 JSON 字符串中的字符

在下面的示例中,如何转义 @data 变量中的双引号字符?

declare @data nvarchar(max) = N'"TEST"';
declare @jsonFragment nvarchar(max);
declare @id int = 999;

set @jsonFragment = ',"' + cast(@id as nvarchar(16)) + '":"' + @data + '"';

select @jsonFragment;
Run Code Online (Sandbox Code Playgroud)

结果是:

 ,"999":""TEST""
Run Code Online (Sandbox Code Playgroud)

我需要它是:

 ,"999":"\"TEST\""
Run Code Online (Sandbox Code Playgroud)

据我了解,选择for json path要求我定义一个静态键名称 - 但可以看出,我有一个场景,其中键名称是动态定义的。

在我的实际用例中,此字符串构造发生在一个stuff语句内,该语句本身是利用 CTE 的较大列定义的一部分select- 这意味着很难创建要使用sp_executeSQL.

t-sql json sql-server-2016

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

解释 SSMS 对象资源管理器图标的参考在哪里?

(这与询问带有白色问号的蓝色圆圈的两个问题不同)

SQL Server Management Studio 中的对象资源管理器可以显示许多不同类型的图标。解释它们的文档到底在哪里?(即使这里关于蓝色圆圈和白色问号的其他问题也没有指向微软的任何参考,各种答案只是给出了“摆脱”图标的各种方法,解释其含义的唯一答案是“我认为这意味着......”这对微软来说非常糟糕。为什么当您将鼠标悬停在图标上时不在弹出窗口中提供上下文帮助?)

下面是我无需费力就能找到的各种图标。

SQL Server Management Studio SSMS 节点图标

将图像单词放入可解析文本中:

  • 带有向右的白色三角形的绿色圆圈(例如数据库引擎)
  • 绿色圆圈,带有朝右的白色三角形,前面有一个黑色 x(例如 sql server 代理)
  • 绿色圆圈,带有一个朝右的白色三角形,前面有一个指向右侧的黑色箭头(例如,分布式事务协调器,受管理)
  • 右上角红x(数据收集,管理中)
  • 红色 x 前面有一个黑色立方体(资源调控器,受管理)
  • 黑色方块,下半部黑色,上半部白色(策略管理,管理下)
  • 两个蓝色箭头,一个朝左,另一个朝右(可用性组)
  • 两个蓝色箭头形成一个圆圈(可用性组副本)
  • 带有白色方块的红色圆圈,前面有一个黑色 x(sql server 代理,已禁用服务)
  • 红色 x(代理工作,已禁用)

我的意思是我可以猜到其中一些 - 但到底在哪里记录了可能的图标的完整列表?

(正是可用性组副本上形成圆圈的两个蓝色箭头让我刚才进行了搜索)。

ssms

5
推荐指数
0
解决办法
1579
查看次数

将 json 值更新为 null

据我了解,如果您选择json_valuejson_query指定 json 文档中不存在的键或对象,那么在严格模式下,您将收到错误。例如,这使您可以确认文档中是否指定了该密钥。

如果文档中包含示例键值对:

"Test":null
Run Code Online (Sandbox Code Playgroud)

...在严格模式下,这将返回“NULL”。换句话说,您现在知道该键已在文档中定义,并且其值为 null。

现在想象您的文档包含:

 "Test":"Some string"
Run Code Online (Sandbox Code Playgroud)

而你查询:

 select json_modify(@json, '$.Test', null);
Run Code Online (Sandbox Code Playgroud)

这将返回一个缺少“Test”键的 json 字符串。

如何正确地将键值设置为 null,而不是将其从 json 文档中删除?

(上面的示例可能看起来很荒谬,但我可以想象在将 json 文档传递到下一个查询或系统之前将值设置为 null,并要求文档中存在“Test”键。)

sql-server t-sql json

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

如何用多行数据替换字符串的多个部分?

给定一个包含两列的表 - 一个整数 ID 和一个基于文本的字符串 - 我想从一个字符串值开始,该字符串值对用大括号括起来的任意数量的整数进行编码,并与任何其他有效文本字符混合。

例子:'{1} / {9} ... {12}'

通过一条SELECT语句,我想返回一个字符串,其中所有整数(及其大括号)都已替换为从我的表派生的值;具体来说,行的文本值的 ID 与源字符串中找到的数字相匹配......并且大括号之外的任何字符保持不变。

这是一个未能完成任务的示例:

select
  replace('{13} {15}','{'+cast(id as varchar)+'}',isNull(display,''))
from testing;
Run Code Online (Sandbox Code Playgroud)

这将在表中每行返回 1 行testing。对于值 = 13 的行id,字符串的“{13}”部分已成功替换,但“{15}”部分未成功替换(第 15 行反之亦然)。

我想创建一个循环所有testing行并重复尝试替换的函数可以解决问题。尽管如此,直接的 SQL 语句比循环语句更好。

示例数据

+----+-------------------+
| id |  display          |
+----+-------------------+
|  1 |  Apple            |
|  2 |  Banana           |
|  3 |  Celery           |
|  4 |  Dragonfruit      |
|  5 |  Eggplant         |
| …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2016 string-manipulation

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

是否可以在 SSMS 中单步执行使用变量的 TSQL?

如果我在 SSMS 查询编辑器中输入 TSQL,我知道我可以通过突出显示一条语句并按键盘上的 F5 来“单步执行”这些语句(即一次执行一个语句)。

但默认情况下,该会话似乎没有打开的事务。每次执行都已提交。

我可以编写 TSQL,使其以or开头BEGIN TRAN和结尾- 这确保了当我逐步执行时,我可以选择退出更改。COMMITROLLBACK

然而,我遇到的问题是当我声明变量时。考虑:

declare @flag bit = 0;

select case when @flag = 0 then 'off' when @flag = 1 then 'on' end as FlagCheck;
Run Code Online (Sandbox Code Playgroud)

无论上面的内容是否包含在事务中,如果我单独运行第一个语句,然后单独运行下一个语句,则第二个语句将失败,因为尚未声明变量。

是否可以单步执行这样的代码,并让 SSMS 了解先前语句(声明变量并赋值)的效果应该延续到下一步?(同样,即使包装在事务中,这种变量的持久性也会失败 - 即使数据更新的持久性取决于事务解析 - 提交或回滚)。

sql-server ssms t-sql transaction

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

数据库的逻辑名称如何与 SSMS 中显示的名称不同?

我发现在生产服务器上有一个名为 MYOBInterim 的数据库。在其他环境(开发、测试)上,有一个名为 MYOBTraining 的数据库。(别问我为什么——我还在努力得到那个答案……)

我从开发实例创建了其中一个 MYOBTraining 数据库的备份,然后尝试将其恢复到另一个没有此类数据库的开发实例。

我的 SQL 大致如下。

use master;
go


If(db_id(N'MYOBTraining') IS NULL) 
   create database MYOBTraining
   on
   (name = MYOBTraining,
    filename = 'D:\Database\Dev4\MYOBTraining.mdf' )
   log on
   (name = MYOBTraining_log,
    filename = 'E:\Logs\Dev4\MYOBTraining_1.ldf' )
   ;
go

-- BIG NOTE:
-- Note we are moving 'MYOBInterim' (and not 'MYOBTraining')! 
-- Prod calls this DB MYOBInterim. Even though we obtain the backup for use with this restore from DEV - where the DB is called MYOBTraining,
-- It seems …
Run Code Online (Sandbox Code Playgroud)

sql-server backup restore sql-server-2016

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

不同服务器上的两个数据库之间是否可以部分同步?

想象一个场景,您有一个数据库的主实例和一个自动同步的辅助实例 - 与可用性组非常相似。

我的问题是我是否可以向辅助实例添加其他对象 - 特别是物化(索引)视图 - 而不需要该视图同步回主实例。

这可能吗?

(“为什么?”,我听到你问?因为我不希望维护视图的性能影响影响主实例。如果需要,可以找到辅助实例使用异步提交模式。)

data-synchronization sql-server-2016

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

在子查询中生成随机行顺序

我知道这里(和这里)的其他答案说要订购newid()。但是,如果我top 1在子查询中进行选择- 以便在外部查询中的每行生成随机选择 - 每次使用都会newid()产生相同的结果。

那是:

select *,
    (select top 1 [value] from lookupTable where [code] = 'TEST' order by newid())
from myTable
Run Code Online (Sandbox Code Playgroud)

...lookupTable.value在从 返回的每一行上产生相同的值myTable

我正在尝试从lookupTable. 那个表只有几行。在现实世界中,我想要update myTable set someColumn = ......一个随机lookupTable.value值,这样每一行都myTable设置了一个随机值,而不是生成一个随机值并将其分配给所有行。

sql-server random sql-server-2016

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