标签: sql-server-2016

非唯一聚集索引管理

我最近被指派管理 SQL Server 2016 中的数据库,我发现数据库中有许多表具有非唯一聚集索引,导致非聚集主键索引。

我知道上述显然是允许的,但并不理想(特别是对于大表),也许在某些情况下,这是有道理的,但此类表的数量告诉我,这更像是粗心的表定义的结果。

例如,一个名为的表Transaction将有一个带有以下键的聚集索引:date, is_deleted. 此外,该表将在名为 的列上有一个非聚集主键id

现在,其中一些表非常大,并且上面有许多外键引用,所以我想出了以下步骤,在 Aaron 在此线程中的回答的帮助下更改所有这些表无法删除非 PK 索引,因为它是在外键约束中引用

  1. 删除表的聚集索引
  2. 删除所有引用该表的外键约束
  3. 删除表的当前主键约束
  4. 使用id列创建主键集群约束
  5. 创建之前删除的所有外键约束
  6. 可选 - 创建以前的聚集索引作为非聚集索引

我知道对于大表,我需要找到一个维护窗口来执行更改,但是您是否发现上述解决方案有任何我没有想到的问题或陷阱?这种方法会导致非聚集索引的其余部分出现碎片吗?

涉及很多表,我想确保我不会触发任何副作用。

performance index sql-server fragmentation sql-server-2016

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

哪种表设计最适合 SQL Server 中的规范化?

我在我们的应用程序中有三种不同的产品,即车辆、黄金和财产。每个产品都有近 30 种不同的库存详细信息。我设计了我的表结构如下:-

标题表:-

 PkId ------ + ProductFkId------ + AssetId ------ + RegNo
  1          | 1                 | A00001         | R0001   
  2          | 2                 | A00002         | R0001
  3          | 3                 | A00003         | R0001
Run Code Online (Sandbox Code Playgroud)

车辆库存表:-

 PkId ---------------+ HeaderFkId -------- + Make ------- + Model  
  1                  | 1                   | Toyota       | Etios Cross Dieselvdsp
  2                  | 2                   | Toyoto       | Etios Dieselgd
  3                  | 3                   | Toyota       | Etios Dieseld-4d Gd
Run Code Online (Sandbox Code Playgroud)

黄金库存表:-

  PkId ------- + HeaderFkId ----- + Carat18 ----- + …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2016

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

如何使用 json sql server 获取此值?

如何在此 json 文件中获取question_id字段?我试过了,但它返回null

DECLARE @json NVARCHAR(MAX)
SET @json =   
  N'{ 
            "solution": "xxxxxxxxxxxxxxxxxxxxx",
            "options": [
                {
                    "choice_id": 205073,
                    "choice": "aaaa"
                },
                {
                    "choice_id": 205074,
                    "choice": "bbbb"
                },
                {
                    "choice_id": 205075,
                    "choice": "cccc"
                },
                {
                    "choice_id": 205076,
                    "choice": "dddd"
                }
            ],
            "question_id": 12345
        }'  

SELECT * FROM  
 OPENJSON ( @json, '$.options')
WITH (      
              choice_id varchar(8000) '$.choice_id',
              question_id int '$.question_id'
 ) 
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明

sql-server json sql-server-2016

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

WHERE 1 = 2 返回一行

任何想法,为什么以下查询中的第一个返回带有 -1,NULL 的行,尽管它有一个WHERE 1=2

只有当我将查询放入另一个子查询时,它才能正常工作(并返回一个空的结果集)。

在 Microsoft SQL Server 2014 和 2016 上测试

DECLARE @i INT = 1

SELECT @i i, MAX(sub.id) mid
  FROM (SELECT TOP(@i) x.id
          FROM (VALUES(1), (2), (3), (4)) x(id)
         WHERE x.id > 2 + @i
         ORDER BY x.id) sub
WHERE 1 = 2

SELECT s1.i, s1.mid
  FROM (
        SELECT @i i, MAX(sub.id) mid
          FROM (SELECT TOP(@i) x.id
                  FROM (VALUES(1), (2), (3), (4)) x(id)
                 WHERE x.id > 2 + @i
                 ORDER BY x.id) sub
       ) …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2014 sql-server-2016

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

SQL Server TRUNCATE TABLE 权限

是否可以将 SQL Server 用户配置为无权访问 DDL 语句但有权访问运行TRUNCATE TABLE命令。我知道在幕后它是一个 DDL。

我在搜索引擎上找不到这个。

sql-server permissions truncate sql-server-2016

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

SQL Server 迁移脚本中的多个批处理

我正在尝试提出一个数据库脚本,用于将应用程序数据库的早期版本迁移到更高版本。差异相当大,完成迁移将涉及创建新表、重命名表、添加函数、添加具有依赖于这些函数的计算列的视图等。脚本完成后,我将其交给其他人在目标环境上运行。

我希望能够在单个事务中运行整个迁移,这样如果出现问题,回滚就很容易了。

我遇到的问题是,当脚本尝试时CREATE FUNCTION,它会抱怨:

SQL80001:语法不正确:“CREATE FUNCTION”必须是批处理中的唯一语句。

我做了一些研究,发现 SSMS 允许使用GO关键字来分隔批次,但是每次我尝试将整个脚本包装在 a 中BEGIN TRANSACTION,然后包含 aGO以将 create 函数调用分离到自己的批次中时,我得到一个错误:

“GO”附近的语法不正确。

我不知道为什么,因为像这样的答案似乎适用于那里的 GO 语句。

我还假设(可能是错误的)我提供脚本的人将使用 SSMS。

我还发现了几篇提到 using 的文章,SET XACT_ABORT ON;我一开始就在交易之外尝试过。

所以我的脚本看起来像这样:

SET XACT_ABORT ON
GO
BEGIN TRY
BEGIN TRANSACTION
    -- Create some tables
    GO -- Error
    CREATE FUNCTION [...]
    GO -- Error
    -- Create some views that rely on the above function
    COMMIT TRANSACTION
END TRY -- With the GOs in there, …
Run Code Online (Sandbox Code Playgroud)

sql-server ssms sql-server-2016

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

什么是对象 ID -710746692?

我正在使用 SentryOne,并且我认为这是一个死锁过程。它显示的数据库 ID 为 32767,对象 ID 为 -710746692。我查看了 sys.databases 和 sys.objects 并没有找到任何关于这些的东西。我搜索了数据库 ID,并认为它是 sql server 拥有的隐藏资源数据库。但是,谷歌搜索没有返回任何对对象 id 有意义的内容。

什么是对象 ID -710746692?

sql-server sql-server-2016

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

在 ConnectionStrings 中为每个应用程序使用 DNS

最近,当我不得不将大量内部应用程序迁移到新的 SQL 服务器时,我遇到了一个想法。我看的越多,它听起来就越完美,但我想向社区征求反馈意见。它使用 SQL0216 和 AlwaysOn。

告诉我的开发人员使用 DNS 条目在他们的 ConnectionStrings 中指向他们各自的数据库有什么缺点?

示例:DNS:App1_SQL 指向 Servr1,DNS:App2_SQL 指向 Servr1。服务器=App1_SQL;数据库=App1;Trusted_Connection=True;服务器=App2_SQL;数据库=App2;Trusted_Connection=True;

这样,当我迁移数据库时,我可以一次完成一个应用程序,确保在继续之前一切正常。无需重新编译代码,也无需处理任何配置文件。我只需要复制数据库并更新应用程序的 DNS 条目。

如果特定应用程序使用外部数据库引用,我会训练我的开发人员始终使用同义词。这样,我为旧数据库创建了一个链接服务器,并在迁移时相应地更新同义词。

除了必须一个一个地管理大量 DNS 条目之外,我仍然认为这是一种减轻与数据库迁移相关的压力的方法,能够通过小块而不是整个服务器一次性完成。

现在,我看不到的警告是什么?因为这听起来太容易和有益,而不是一个非常标准化的做法,但我从来没有遇到过这个建议。Kerberos 会成为问题吗?

提前致谢

sql-server dns availability-groups kerberos sql-server-2016

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

Microsoft SQL Server 2016 Service Pack 1 (SP1) 支持 TDE(透明数据加密)

Microsoft SQL Server 2016 Service Pack 1 是否也向标准版添加了对 TDE(透明数据加密)的支持?

根据数据库引擎中的新增功能 - SQL Server 2016大事:SQL Server 2016 Service Pack 1,看起来许多企业级功能也添加到 SQL Server 2016 标准版中。

但是,关于 TDE 没有明确的答案,我知道 TDE 一直是企业功能,但只是想在提出 SQL Server 2016 SP1 之前确定一下。

任何人都可以参考一份书面/文件证明标准版的 SP1 是否会有 TDE?

非常感谢!

sql-server transparent-data-encryption standard-edition sql-server-2016

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

无法对“FunctionName”执行更改,因为它是不兼容的对象类型

我知道之前已经问过同样的问题,但情况略有不同,我想更多地解释为什么它在我的上下文中失败,当(AFAIK)返回类型相同时。

过去,在我的数据库中,我使用基于 CLR 的表值函数将逗号分隔值拆分为包含整数列的表。

因为 SQL2016 引入了STRING_SPLIT,我需要换掉这个函数的 CLR 部分,并替换为原生的 TSQL 函数(因为我有数百个依赖这个函数的存储过程)。

如果我在 SSMS 中修改这个函数,我会看到:

ALTER FUNCTION [dbo].[e4fn_CreateIdTable](
     @Ids [nvarchar](max), 
     @separator [nchar](1))
RETURNS TABLE (
    [IdVal] [int] NULL
) WITH EXECUTE AS CALLER
AS 
EXTERNAL NAME [ValueSplitter].[MyCompany.ValueSplitter].[SplitToIntegers]
Run Code Online (Sandbox Code Playgroud)

我希望我能够像这样改变它:

ALTER FUNCTION [dbo].[e4fn_CreateIdTable] (
    @Ids [nvarchar](max), 
    @separator [nchar](1)
)
RETURNS TABLE 
AS RETURN
(
    SELECT
        CAST(NULLIF(LTRIM(RTRIM(value)), '') AS int) AS IdVal
    FROM
        STRING_SPLIT(@Ids, @separator)
)
GO
Run Code Online (Sandbox Code Playgroud)

这返回了错误:

无法对“dbo.e4fn_CreateIdTable”执行更改,因为它是不兼容的对象类型。

我认为这是因为没有明确定义输出参数的表定义。所以,我这样重试:

ALTER FUNCTION [dbo].[e4fn_CreateIdTable] (
    @Ids [nvarchar](max), 
    @separator [nchar](1)
)
RETURNS …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2016

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