运行更新语句时,例如下面的语句,我收到一条错误消息,告诉我
窗口函数只能出现在 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 作为解决方法?
我担心的是在使用带有更新语句的窗口函数时会出现问题,因此我想了解这是一种可接受的方法还是应该避免的方法。
我有一个大约 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 相同的数据库在 …
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) 我遇到过一种情况,用户在我们的一个运行存储过程的应用程序中运行了某些内容。存储过程执行一些日志记录(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 2016添加了AT TIME ZONE运算符。从文档中:
\n\nAT TIME ZONE 实现依赖于 Windows 机制来跨时区转换日期时间值。
\n
AT TIME ZONEmscorlib.ni!TimeZoneInfo.ConvertTime根据针对简单查询的 ETW 跟踪调用该方法。乔纳森·凯哈亚斯 (Jonathan Kehayias) 发表了一篇博文,其中他从课堂上提取了所有时区规则System.TimeZoneInfo。我只能在输出中找到于 01/01/2004 或更高版本生效的规则:
Rob Farley 在一篇博客文章中提到,2000 年时区规则的更改似乎并未得到遵守AT TIME ZONE:
\n\n它通过使用 Windows 注册表来工作,其中包含所有这些信息,但遗憾的是,当回顾过去时,它\xe2\x80\x99 并不完美。澳大利亚于 2008 年更改了日期,美国于 2005 年更改了日期 \xe2\x80\x93 两国都在一年中的大部分时间实行夏令时。AT TIME ZONE 明白这一点。但它似乎并没有意识到,2000年的澳大利亚,由于悉尼奥运会,澳大利亚提前了大约两个月开始实行夏令时。
\n
我觉得有大量间接证据表明,AT TIME ZONE对于早于 2004 年的日期,操作员可能会返回不准确的结果。但是,我找不到任何AT TIME ZONE使用该类的文档System.TimeZoneInfo,这些文档AT TIME ZONE对于较旧的日期可能不准确,或者 …
前几天有人问我,如果 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) 我有一个包含 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 > … |
当使用具有定义的列集的 SELECT 语句查询数据库时,大约 21 秒内就会收到结果。
\n, *如果定义的列集列表末尾有一个附加星号 ( ),则查询将在 2 秒内返回结果。
执行计划差异很大。
\n您可以通过 PasteThePlan 中的链接找到良好的实际查询执行计划和不良的实际查询执行计划。
\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 注入的答案和示例都显示某种形式的动态 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;',但无法这样做。我想我可能没有正确地进行攻击。
我有一个旧的第 3 方应用程序,当我卸载 SQL Server 时该应用程序停止工作。我发现此应用程序需要在服务器上安装 Microsoft.SqlServer.ManagedDTS.dll。
我不知道如何只安装这个 dll,因此我重新安装了 SQL Server 并检查了几个功能。
如何判断哪个功能实际安装了 Microsoft.SqlServer.ManagedDTS.dll?
sql-server ×10
deadlock ×2
blocking ×1
index-tuning ×1
memory-grant ×1
performance ×1
security ×1
t-sql ×1
timezone ×1