标签: sql-server

SQL Server - 为什么更新语句中不允许使用窗口函数?

运行更新语句时,例如下面的语句,我收到一条错误消息,告诉我

窗口函数只能出现在 SELECT 或 ORDER BY 子句中。

UPDATE dbo.Dim_Chart_of_Account
SET Account_Order = LAG([Account_Order]) OVER (ORDER BY [Account_SKey])
Run Code Online (Sandbox Code Playgroud)

我知道这可以使用可更新的 cte 轻松解决,如下所示

 WITH my_cte AS (
     SELECT [Account_Order], LAG([Account_Order]) OVER (ORDER BY [Account_SKey]) AS acc_order_lag
     FROM Dim_Chart_of_Account
)
UPDATE my_cte
SET [Account_Order] = acc_order_lag
Run Code Online (Sandbox Code Playgroud)

我的问题是,是否有任何原因在更新语句中不允许这样做,我是否应该避免使用可更新的 cte 作为解决方法?

我担心的是在使用带有更新语句的窗口函数时会出现问题,因此我想了解这是一种可接受的方法还是应该避免的方法。

sql-server sql-server-2014

10
推荐指数
1
解决办法
4412
查看次数

SQL Server 2016 高空闲 CPU 和查询速度极慢

我有一个大约 10 天的 WinServer2012R2 和 SQL Server Express 2016 安装用于测试。我是这台机器上唯一的用户。SQL Server 2005 中的 .bak 大约为 250MB 的数据库已恢复,没有任何问题。机器重新启动后,进程“SQL Server NT - 64 位”使用 0% CPU。

几分钟或几小时后,来自“SQL Server NT - 64 位”的 SSMS CPU 使用率的一些简单查询(没有更新/插入!)突然跃升至约 15% 并保持在那里,即使在空闲时也是如此。从那时起,通常需要不到一秒钟的查询突然需要 2 分钟。在实际查询期间,CPU 使用率不会增加。在这种状态下,服务器几乎无法使用。

仅连接 SQL Server Profiler 需要 30 秒以上的时间。除了我自己的查询之外,我只看到来自 SQLServerCEIP / SQLTELEMETRY 的非常少的查询,大约每分钟 3 次。

重新启动 SQL-Server 并不能解决它。CPU 使用率立即回升至约 15%。即使在数小时后 SQL-Server 也不会恢复。只有重新启动整个机器才能解决问题。

由于这是一个“开箱即用”的安装,只有一个小数据库,几乎没有查询,只有我作为用户并且可能没有锁,关于常规 SQL-Server 性能问题的许多文章谈论了很多事情真的不适用这里。这似乎为SQL-服务器专用希望专注于一些内部的任务。

这是一个具有 2GB RAM 和 2GHz 双 Xeon 的虚拟机。我也有 VS2016,它真的很快。没有防病毒软件,甚至没有 Windows Defender。这里已经晚了。明天我将尝试 sp_whoisactive。我真的很想知道 SQL-Server 在那里做什么......在以前的机器上有 1 GB 相同的数据库在 …

performance sql-server sql-server-express sql-server-2014

10
推荐指数
1
解决办法
1万
查看次数

我可能会遇到未被发现的死锁吗?

sp_whoisactive第一次在服务器上运行时,我遇到了一些意想不到的事情:

在此输入图像描述

两场比赛已经持续了13天,但两场比赛似乎都在互相阻碍。看看sys.dm_tran_locks

在此输入图像描述

阻止进程阈值设置的配置值为 10 秒。其他死锁正在通过死锁监视器在服务器上成功解决。

来自参数的信息@get_locks

<Database name="DB1">
  <Locks>
    <Lock request_mode="S" request_status="GRANT" request_count="1" />
  </Locks>
  <Objects>
    <Object name="TBL1" schema_name="dbo">
      <Locks>
        <Lock resource_type="OBJECT" request_mode="IX" request_status="GRANT" request_count="1" />
        <Lock resource_type="PAGE" page_type="*" index_name="PK__TBL1__3214EC27326C5B6A" request_mode="U" request_status="GRANT" request_count="1" />
        <Lock resource_type="PAGE" page_type="*" index_name="PK__TBL1__3214EC27326C5B6A" request_mode="U" request_status="WAIT" request_count="1" />
      </Locks>
    </Object>
  </Objects>
</Database>


<Database name="DB1">
    <Locks>
        <Lock request_mode="S" request_status="GRANT" request_count="1" />
    </Locks>
    <Objects>
        <Object name="TBL2" schema_name="dbo">
            <Locks>
                <Lock resource_type="OBJECT" request_mode="Sch-S" request_status="GRANT" request_count="2" />
            </Locks>
        </Object>
        <Object name="TBL1" schema_name="dbo">
            <Locks>
                <Lock resource_type="OBJECT" request_mode="IX" …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock sql-server-2017

10
推荐指数
1
解决办法
237
查看次数

SQL Server 没有消除死锁吗?

我遇到过一种情况,用户在我们的一个运行存储过程的应用程序中运行了某些内容。存储过程执行一些日志记录(INSERT记录到日志表),然后以以下格式执行简单的删除

DELETE FROM MyTable WHERE Id = 1

从具有数百万行的表中删除DELETE数万条记录(存储过程对多个表执行此操作)并生成并行执行计划。Id 列是复合主键中的第二列,但该表没有任何以该列开头的索引。

删除计划可在此处获取

表的匿名 DDL 如下

CREATE TABLE [dbo].MyTable
(
    [Column15] [varchar](50) NULL,
    [Column16] [int] NULL,
    [Column2] [datetime] NULL,
    [Column3] [datetime] NULL,
    [Column4] [varchar](50) NOT NULL,
    [Column5] [datetime] NULL,
    [Column17] [varchar](8) NULL,
    [Column18] [varchar](50) NULL,
    [Column6] [int] NULL,
    [Column7] [int] NULL,
    [Column9] [int] NULL,
    [Column8] [int] NULL,
    [Column19] [varchar](50) NULL,
    [Column20] [varchar](50) NULL,
    [Column21] [varchar](50) NULL,
    [Column22] [varchar](50) NULL,
    [Column23] [varchar](50) NULL,
    [Column24] [varchar](50) NULL,
    [Column25] [varchar](50) …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock blocking sql-server-2016

10
推荐指数
0
解决办法
362
查看次数

AT TIME ZONE 能否返回 2004 年之前的数据的不准确结果?

SQL Server 2016添加了AT TIME ZONE运算符。从文档中:

\n
\n

AT TIME ZONE 实现依赖于 Windows 机制来跨时区转换日期时间值。

\n
\n

AT TIME ZONEmscorlib.ni!TimeZoneInfo.ConvertTime根据针对简单查询的 ETW 跟踪调用该方法。乔纳森·凯哈亚斯 (Jonathan Kehayias) 发表了一篇博文,其中他从课堂上提取了所有时区规则System.TimeZoneInfo。我只能在输出中找到于 01/01/2004 或更高版本生效的规则:

\n

兹规则

\n

Rob Farley 在一篇博客文章中提到,2000 年时区规则的更改似乎并未得到遵守AT TIME ZONE

\n
\n

它通过使用 Windows 注册表来工作,其中包含所有这些信息,但遗憾的是,当回顾过去时,它\xe2\x80\x99 并不完美。澳大利亚于 2008 年更改了日期,美国于 2005 年更改了日期 \xe2\x80\x93 两国都在一年中的大部分时间实行夏令时。AT TIME ZONE 明白这一点。但它似乎并没有意识到,2000年的澳大利亚,由于悉尼奥运会,澳大利亚提前了大约两个月开始实行夏令时。

\n
\n

我觉得有大量间接证据表明,AT TIME ZONE对于早于 2004 年的日期,操作员可能会返回不准确的结果。但是,我找不到任何AT TIME ZONE使用该类的文档System.TimeZoneInfo,这些文档AT TIME ZONE对于较旧的日期可能不准确,或者 …

sql-server timezone

10
推荐指数
1
解决办法
1078
查看次数

SQL Server 是否可以为查询授予比实例可用的内存更多的内存

前几天有人问我,如果 SQL Server 想要运行一个查询,而该查询被授予的内存多于实例可用的内存,会发生什么情况。我最初的想法是我可能会看到RESOURCE_SEMAPHORE等待并且查询永远不会开始。

我做了一些测试来试图找出答案。

我的实例以 4000MB RAM 启动:

EXEC sys.sp_configure N'max server memory (MB)', N'4000'
GO
RECONFIGURE WITH OVERRIDE
GO
Run Code Online (Sandbox Code Playgroud)

如果我然后运行我的(故意可怕的)查询:

USE StackOverflow
SELECT      CONVERT(NVARCHAR(4000), u.DisplayName) AS DisplayName,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp2,
            CONVERT(NVARCHAR(MAX), u.DisplayName) AS Disp3
FROM        dbo.Users AS u
            JOIN dbo.Posts p
                ON LTRIM(u.DisplayName) = LTRIM(p.Tags)
WHERE       u.CreationDate >= '2008-12-25'
            AND u.CreationDate < '2010-12-26'
ORDER BY    u.CreationDate;
Run Code Online (Sandbox Code Playgroud)

执行计划显示授予的内存为 732,008KB。

然后,我将实例可用的内存设置为低于此数字,然后重新启动实例:

EXEC sys.sp_configure N'max server memory (MB)', N'500' /* a value lower than the previous memory …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals sql-server-2019 memory-grant

10
推荐指数
1
解决办法
2326
查看次数

如何构造谓词以触发具有组合键的特定记录搜索的聚集索引?

我有一个包含 4 部分复合聚集主键(A、B、C、D)的表,按 A、B、C、D 排序。

我必须通过获取 N 条记录来批量遍历整个表,然后检查的最后一个键(K1、K2、K3、K4)之后的任何值开始获取接下来的 N 条记录。键值不连续。

我正在尝试构造谓词来寻找下一批记录,给定带有复合键(K1,K2,K3,K4)的最后读取记录。

如果 ID 不是复合的,我只需运行一个 select 语句,例如“从表中选择前 N 个,其中 ID > K1”。然而,因为它是一个由 4 部分组成的复合键,所以我必须构造一个特殊的谓词来处理 D 可以小于 K4 的事实,只要 A、B 和 C 中的任何一个或全部大于 K1、K2和K3。

在某些数据库引擎中,我知道可以使用如下设置语法进行此类复合键比较:

where (A,B,C,D) > (K1,K2,K3,K4)

问题1: SQL Server支持上述集合比较语法吗?

如果没有,那么我怀疑我必须像这样构造谓词:

一把钥匙 两把钥匙 三把钥匙 四把钥匙
其中 (A > K1)
按 A 排序
其中 (A = K1 且 B > K2)
OR (A > K1)
按 A、B 排序
其中 (A = K1 且 B = K2 且 C > …

sql-server

10
推荐指数
2
解决办法
626
查看次数

列列表中带有 , * 的 SELECT 语句比不带 * 的相同语句更快

情况

\n

当使用具有定义的列集的 SELECT 语句查询数据库时,大约 21 秒内就会收到结果。

\n

, *如果定义的列集列表末尾有一个附加星号 ( ),则查询将在 2 秒内返回结果。

\n

查询执行计划

\n

执行计划差异很大。

\n

您可以通过 PasteThePlan 中的链接找到良好的实际查询执行计划不良的实际查询执行计划。

\n

列列表中包含 , * 的语句(在末尾)

\n
\n            SELECT    -- DISTINCT -- 27.04.2020\n                \'SchuelerKlasse\' AS EcoQuery,\n                VX_PERSON.PER_MAN_ID, VX_PERSON.PER_ID, VX_PERSON.PER_NAME, VX_PERSON.PER_VORNAME, VX_PERSON.PER_LB_PER_ID, \n                VX_PERSON.PER_GESCHLECHT, VX_PERSON.PER_GEBURTSDATUM, VX_PERSON.PER_TELP, VX_PERSON.PER_MAILP, VX_PERSON.PER_NATP, VX_PERSON.PER_VERSICHERTENNUMMER, VX_PERSON.PER_LAND,\n                VX_ADRESSE.ADR_STRASSE, VX_ADRESSE.ADR_PLZ, VX_ADRESSE.ADR_ORT,\n                VX_KLASSE.KL_CODE, VX_KLASSE.KL_BEZEICHNUNG,\n                VX_KLASSEABSCHNITTSCHUELER.KAS_ANMELDE_STATUS, \n                VX_KLASSEABSCHNITTSCHUELER.KAS_ANMELDETYP, VX_KLASSEABSCHNITTSCHUELER.KAS_ABSCHNITTSNR,\n                VX_KLASSE_ZEITRAUM.KLZ_IS_ABSCHLUSSKLASSE, VX_KLASSE_ZEITRAUM.KLZ_ZR_NR,\n                VX_ZEITRAUM.ZR_BEGINN, VX_ZEITRAUM.ZR_ENDE\n                ,\'\' AS FA_CODE\n                ,\'\' AS FA_BEZ_STP, \'\' AS FA_BEZ_STP_LANG\n                , \'\' AS EcoOrig_FA_CODE, …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan index-tuning sql-server-2014

10
推荐指数
1
解决办法
1371
查看次数

这个 SQL 过程是“防注入”吗?

大多数 SQL 注入的答案和示例都显示某种形式的动态 SQL 或将参数解释为 SQL。

我还没有找到“正确”方式的例子。Microsoft 和 Oracle 的文档仅显示了不应做什么的示例。

因此,我想我应该询问这个存储过程示例是否受到 SQL 注入攻击的保护。

CREATE PROCEDURE test
    @username = varchar(30)
    @password = varchar(30)
AS
BEGIN
    SELECT *
    FROM credentials
    WHERE username = @username
    AND password = @password;
END
GO
Run Code Online (Sandbox Code Playgroud)

这个特定的过程是否容易受到 SQL 注入的影响?我创建了该过程并通过各种尝试注入 SQL 来执行它,例如EXEC test @password = '0; drop table credentials;',但无法这样做。我想我可能没有正确地进行攻击。

security sql-server sql-injection t-sql

10
推荐指数
2
解决办法
2622
查看次数

哪个特定的 SQL Server 功能会安装 Microsoft.SqlServer.ManagedDTS.dll?

我有一个旧的第 3 方应用程序,当我卸载 SQL Server 时该应用程序停止工作。我发现此应用程序需要在服务器上安装 Microsoft.SqlServer.ManagedDTS.dll。

我不知道如何只安装这个 dll,因此我重新安装了 SQL Server 并检查了几个功能。

如何判断哪个功能实际安装了 Microsoft.SqlServer.ManagedDTS.dll?

在此输入图像描述

sql-server

10
推荐指数
1
解决办法
853
查看次数