小编fin*_*nal的帖子

防止 SSMS 看到服务器的文件系统

我有几个用户在我的管理下共享 MS SQL Server 2017。他们不应该看到(甚至不知道)该服务器上的其他用户及其数据。每个用户都有自己的数据库。他们可以对他们的数据库做任何他们想做的事情。

我正在使用 SQL Server 的Partial Containment功能将用户锁定到位。登录名是在数据库中创建的。这很有效,因为他们不会以这种方式看到其他用户帐户或数据库。数据库登录名被添加到我使用以下命令创建的数据库角色中:

USE dbname
CREATE ROLE dbrole
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, CREATE VIEW, ALTER ANY SCHEMA TO dbrole
DENY EXECUTE TO dbrole
Run Code Online (Sandbox Code Playgroud)

我刚刚创建了一个 db 登录帐户,并将其添加到所述角色中。用户没有其他权限(我知道)。

剩下的唯一问题是 SSMS 仍然能够浏览服务器的文件系统。如果我右键单击数据库并选择Tasks -> Restore -> Database,然后选择Device: -> [...]并添加文件。这允许 SSMS 浏览服务器的文件系统,我想否认这一点。用户实际上不能恢复数据库,但他可以浏览文件系统。

这里的这个问题表明 SSMS 正在使用存储过程xp_fixeddrivesxp_dirtree并且xp_fileexist. 但是,当以具有该组权限的用户身份执行时,这些存储过程返回空结果。我读过这是当用户不是 sysadmin 角色的成员时的行为。这已经让我有点困惑,因为我明确拒绝对 dbrole 执行 EXECUTE,但用户仍然可以执行存储过程。但是,通过 SSMS 浏览文件系统时,它仍然不是空的。

SSMS 从哪里获取文件系统信息,如何防止这种情况发生?

编辑:我也刚刚注意到 SSMS 能够检索所有数据库的服务器上存在的所有数据库备份的列表。同样,我不知道它如何获取这些信息以及如何防止它。

sql-server ssms sql-server-2017

11
推荐指数
1
解决办法
683
查看次数

SQL Server 死锁在一张表上的两次选择和一次更新之间

我们的应用程序时不时地(大约每周一次)遇到死锁。

罪魁祸首似乎是带有两个选择的查询。其中之一是出于性能原因填充临时表,另一个是具有许多连接的相对复杂的选择,以返回具有许多详细信息的所有约会的列表。我看到的关于第二个选择的唯一可能特别的地方是它包含一个自连接。二选查询始终是 SQL Server 死锁事件报告的一部分。

另一个查询是对同一个表的简单 DML 查询(插入或更新),尽管这并不总是相同的 DML 查询。这两个查询都以标准READ COMMITTED隔离方式运行,而不是在显式事务中运行。

这两个查询大致如下(我已缩短它们以进行澄清)

DECLARE @futureAppointments TABLE(clientId int, StartDate date)
INSERT INTO @futureAppointments SELECT clientId, StartDate FROM Appointments where StartDate >= @startDate

SELECT *, (SELECT COUNT(*) FROM @futureAppointments fa WHERE fa.clientId = a.clientId AND fa.StartDate > a.StartDate)
FROM Appointments a
join b on a.fk_b = b.id
join c on a.fk_c = c.id
join Appointments d on c.somefield = d.anotherfield
WHERE a.StartDate >= @startDate AND a.StartDate <= @endDate
Run Code Online (Sandbox Code Playgroud)
UPDATE Appointments SET …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock deadlock-graph

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

Linux 上的 MSSQL Server 2022:sys.* 表对于非 db_owner 用户来说非常慢

对于非sys.columns.​​sys.indexessys.tablesdb_owner

要重现,请在 Linux 上使用 SQL Server 2022(我使用的是 16.0.4035,这是撰写本文时的最新版本)并执行以下命令。它创建一个虚拟数据库,其中包含 500 个表,每个表有 10 列,这样sys.columns该数据库就会获取大约 5000 条记录。如果您手头的数据库总数超过 1000 列,则可以跳过创建虚拟数据库。

CREATE DATABASE SLOWSYSTABLES
GO

USE SLOWSYSTABLES

DECLARE @i int
DECLARE @createTable nvarchar(max)
SET @i = 0
WHILE (@i < 500)
BEGIN
    SET @createTable = 'CREATE TABLE dummy_' + CAST(@i as nvarchar) + '(Col1 int not null identity(1,1) primary key, Col2 int, Col3 int, Col4 int, Col5 int, Col6 int, Col7 int, Col8 int, Col9 int, Col10 int)' …
Run Code Online (Sandbox Code Playgroud)

sql-server linux sql-server-2022

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