标签: sql-server-2016

在 sys.databases 上游标会跳过数据库

我知道这个问题已经被问过好几次了,我知道解决方案,但我试图了解问题的根本原因:

我有以下代码来执行数据库备份。

DECLARE @Filename   VARCHAR(256)
DECLARE @FileDate   VARCHAR(15) 
DECLARE @Path       VARCHAR(50) 
DECLARE @Name       VARCHAR(50) 

-- specify database backup directory
SET @Path = '\MyPath'

-- specify filename date
SELECT @FileDate = CONVERT(VARCHAR(20), GETDATE(), 112) + '_' + REPLACE(CONVERT(VARCHAR(20), GETDATE(), 108),':','')

DECLARE db_cursor CURSOR FOR
    SELECT [name]
        FROM master.sys.databases
        WHERE [name] NOT IN ('master', 'msdb', 'model', 'tempdb')
            AND [state_desc] = 'ONLINE'

OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @Name

WHILE @@FETCH_STATUS = 0
BEGIN

    SET @Filename = @Path + @Name + '_Full_Backup_' …
Run Code Online (Sandbox Code Playgroud)

dmv cursors sql-server-2016

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

为什么视图中选择查询中完全确定性和包罗万象的“案例”的结果可以为空?

我有一张桌子,Id作为主键。

create table Anything
(
    Id bigint not null primary key identity(1, 1)
)
Run Code Online (Sandbox Code Playgroud)

当我查看 中的这张表时Object Explorer,我当然会看到这张图片:

在此处输入图片说明

正如你所看到的,列Id不为空

然后我在这个虚拟表上创建一个虚拟视图:

create view IdIsTwoView
as

select
    Id,
    (
        case
        when Id = 2
        then cast(1 as bit)
        else cast(0 as bit)
        end
    ) as IdIsTwo
from Anything
Run Code Online (Sandbox Code Playgroud)

但这一次,在对象资源管理器中,我看到了这个结果:

在此处输入图片说明

如您所见,尽管我的case子句包罗万象,涵盖了所有记录的 100%,并且对所有记录都有答案,但它可以为空。

为什么 SQL Server 有这种奇怪的行为?我如何强制它不为 null

PS我们有一个动态生成代码的基础设施,这种行为给我们带来了麻烦,我们必须手动将bool?C# 中的所有类型更改为bool.

null sql-server view sql-server-2016 computed-column

4
推荐指数
2
解决办法
285
查看次数

我可以采取哪些步骤来确定我的服务器的内存配置是否不足?

我的服务器正在运行 SQL Server 2016。该环境的工作负载相当高,全天有大量写入事务和读取数据。我有一种预感,服务器没有配备足够的内存,我想深入了解是否是这样。确定服务器上的可用内存量是否以及产生了多少争用的最佳方法是什么?

我确实查看了 DMV sys.dm_os_wait_stats,当按 waiting_tasks_count desc 排序时,前两个等待类型是“MEMORY_ALLOCATION_EXT”和“RESERVED_MEMORY_ALLOCATION_EXT”,其数量级比任何其他等待类型任务计数都大。还有其他地方可以检查内存压力或争用吗?

编辑:此服务器上所有数据库的总大小为 3 TB,事务最多的主数据库为 2 TB,服务器上的 RAM 总量为 32 GB

编辑 2:这里是一天中的懒惰写入/第二个 perfmon 计数器结果: 每秒延迟写入 - PerfMon 计数器

sql-server memory wait-types sql-server-2016 waits

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

当每次迭代都有自己的显式事务时,SQL 回滚 while 循环的所有迭代

在过去的几天里,我一直在尝试编写一个自动过程的查询,该过程将在指定的日期范围(一个月)内将日志表中的记录删除到另一个表中,然后可以将它们转储到磁盘和记录从数据库中删除。第一种,天真的方法,ala

DELETE FROM <sometable>
OUTPUT DELETED.* INTO [<sometable>_{year}_{month}]
WHERE DATEPART(YEAR, [DateTime]) = {year} AND DATEPART(MONTH, [DateTime]) = {month}
Run Code Online (Sandbox Code Playgroud)

当然炸毁了交易日志。然后我尝试做同样的事情,但现在批量为 1m 行,如下所示

WHILE @@ROWCOUNT > 0
BEGIN
    DELETE TOP (1000000) FROM <sometable>
    OUTPUT DELETED.* INTO [<sometable>_{year}_{month}]
    WHERE DATEPART(YEAR, [DateTime]) = {year} AND DATEPART(MONTH, [DateTime]) = {month}
END
Run Code Online (Sandbox Code Playgroud)

但这并没有改变事务日志的增长。接下来,我尝试在循环中使用显式事务。

WHILE @@ROWCOUNT > 0
BEGIN
    BEGIN TRAN

    DELETE TOP (1000000) FROM <sometable>
    OUTPUT DELETED.* INTO [<sometable>_{year}_{month}]
    WHERE DATEPART(YEAR, [DateTime]) = {year} AND DATEPART(MONTH, [DateTime]) = {month}

    COMMIT
END
Run Code Online (Sandbox Code Playgroud)

再次。没有不同。更糟糕的是,如果我取消此查询并执行 ROLLBACK 以释放表,它会回滚所有内容。正如人们所期望的那样,不仅仅是最后一次迭代,而是整个过程。为什么循环中的各个事务没有被这样对待?当然,必须有一种方法可以在数据库中移动大量行,而 …

sql-server sql-server-2016

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

如何防止我的 Windows Server 被 SQL Server 更新自动重新启动?

某些 SQL Server 更新发生在维护时段之外,这导致服务器重新启动。我怎样才能阻止这种情况在未来再次发生?

以下是我在查看 Windows 更新设置时可以看到的内容:

在此处输入图片说明

sql-server windows windows-server sql-server-2016 patching

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

带有 French_CI_AS 排序规则日期转换的 SQL Server

我有一个使用French_CI_AS排序规则的 SQL Server 法语安装。出于遗留原因,表列将数据存储VARCHAR为稍后转换为正确类型的数据,类似于 C++ 中的变体。

此列中的两行数据如下:

2020-10-12 22:54:40

2020-10-13 04:42:10
Run Code Online (Sandbox Code Playgroud)

DATETIME使用默认选项转换为时,第二个日期失败。该应用程序使用 ODBC 转义序列。SQL 等COLMVALUE >= {ts'2020-01-01 00:00:00'}失败并显示错误:

La Conversion d'un type de données nvarchar en type de données datetime a créé une valeur hors limites

我做了一个DBCC useroptions ,服务器的日期格式设置为dmy. 为什么第 2 行失败?看起来它试图将“13”解释为月份。如果格式是dmy,两个日期不应该都失败吗?

此外,有趣的是,在此服务器上,以下失败:

2020-10-12 22:54:40

2020-10-13 04:42:10
Run Code Online (Sandbox Code Playgroud)

但这有效:

DECLARE @datevar DATETIME = '2020-10-13 04:42:10';    
SELECT @datevar;  
Run Code Online (Sandbox Code Playgroud)

我知道这DATETIME2DATETIME. 但是,这里的两者似乎连解析都不一样。

collation type-conversion datetime localization sql-server-2016

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

为什么更改窗口函数“MAX() OVER()”的ORDER BY部分中的列会影响最终结果?

我有一个具有以下结构的表,它是数据:

create table test_table
(
Item_index   int,
Item_name    varchar(50)
)

insert into test_table (Item_index,Item_name) values (0,'A')
insert into test_table (Item_index,Item_name) values (1,'B')
insert into test_table (Item_index,Item_name) values (0,'C')
insert into test_table (Item_index,Item_name) values (1,'D')
insert into test_table (Item_index,Item_name) values (0,'E')
Run Code Online (Sandbox Code Playgroud)

我想知道为什么更改order by查询部分中的列会更改结果?在QUERY-1, I useditem_indexQUERY-2I useditem_name列中按部分顺序排列。我认为这两个查询必须生成相同的结果because I used item_index in both queries for partitioning!我现在完全困惑了!为什么按列排序会影响最终结果?

查询-1:

select t.*,
       max(t.Item_name)over(partition by t.item_index order by item_index) new_column
from test_table t;
Run Code Online (Sandbox Code Playgroud)

结果:

Item_index …
Run Code Online (Sandbox Code Playgroud)

sql-server query t-sql window-functions sql-server-2016

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

为什么我的 CASE 语句中的后续未满足条件会影响我的返回数据类型?

我有以下变量和 CASE 语句:

DECLARE @DATE_VALUE VARCHAR(20) = '4/29/2021'
DECLARE @CONVERT_CODE VARCHAR(1) = 'I'

SELECT CASE @CONVERT_CODE WHEN 'I' THEN DATEDIFF(day, '04/21/2021', @DATE_VALUE)
       END AS ConvertedValue
Run Code Online (Sandbox Code Playgroud)

它没有什么特别之处。正如我所期望的那样,它返回 8 (int)。

但是,一旦我将返回日期时间数据类型的条件添加到我的 CASE 语句中,我就不再得到 8 (int),尽管继续使用“I”作为 @CONVERT_CODE 值。

DECLARE @DATE_VALUE VARCHAR(20) = '4/29/2021'
DECLARE @CONVERT_CODE VARCHAR(1) = 'I'

SELECT CASE @CONVERT_CODE WHEN 'I' THEN DATEDIFF(day, '04/21/2021', @DATE_VALUE)
                          WHEN 'D' THEN GETDATE()
       END AS ConvertedValue
Run Code Online (Sandbox Code Playgroud)

相反,我得到“1900-01-09 00:00:00.000”的日期时间值

我认为“D”根本不应该被评估,因为在 SQL Server 中,一旦条件评估为真(在这种情况下为“I”),它应该脱离 CASE 语句——所以我不确定为什么“D”的数据类型会影响整体返回数据类型。另外,如果我颠倒条件的顺序并仍然使用“I”也没关系:

DECLARE @DATE_VALUE VARCHAR(20) = '4/29/2021'
DECLARE @CONVERT_CODE VARCHAR(1) = 'I'

SELECT …
Run Code Online (Sandbox Code Playgroud)

sql-server datatypes case sql-server-2016

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

我们如何限制 SQL Server 上特定用户或查询的 tempdb 使用?

在我们的 SQL Server 生产环境中,一些用户运行临时查询,将大量数据提取到 tempdb 中并将其填满,从而导致生产服务器出现问题。当这些报告/查询从前端运行时,它们有时会弄乱将数百万行拉到临时表的日期范围。是的,用户需要接受教育,也需要调整,我们已经这样做了,但他们仍然偶尔会产生问题。

现在他们说在 SAP ASE (Sybase) 中有一个功能可以创建多个 tempdb 和重定向用户并限制使用,通过不膨胀单个 tempdb(就像在 SQL Server 中一样)并使服务器停机。

我们在 SQL Server 中有这样的东西吗?

sql-server sybase tempdb sql-server-2016

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

SQL Server 2016 突然产生 Error:402,State:1,Class:16 用 DATETIME/DATE/TIME 算法更新 sproc,这在之前很好

在其中一个存储过程中,我需要捕获实时事件的持续时间。保证永远不会超过 24 小时,因此结果列的数据类型选择为TIME(3)(映射到TimeSpan应用程序端)。计算过程如下:

update tbEvent set tWait= @dtEvent - dEvent - tEvent [where idEvent = @idEvent]
Run Code Online (Sandbox Code Playgroud)

此处dEventtEvent先前设置为dtEvent(原始事件@dtEvent的时刻)的日期和时间部分,并且是后续关闭事件的时刻。因此,我从 DATETIME 变量中减去 DATE 和 TIME 列值,并将结果填充到 TIME 列中。

[合理吗?] 预期行为: SQL 将每个表达式项隐式转换为 DATETIME,执行减法,然后通过简单地删除 DATE 部分将结果隐式转换为 TIME这一直有效! 嗯, - 到目前为止..


一个更新脚本突然在 SQL 2016 (13.0.1742.0) 上产生了一个错误

System.Data.SqlClient.SqlException (0x80131904):
    The data types datetime and date are incompatible in the subtract operator.
    Error Number:402,State:1,Class:16
Run Code Online (Sandbox Code Playgroud)

但是相同的脚本在 2008 R2 (10.50.2500.0) 和 2019 (15.0.2080.9) 上运行良好! …

sql-server t-sql datetime date sql-server-2016

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