我最近被指派管理 SQL Server 2016 中的数据库,我发现数据库中有许多表具有非唯一聚集索引,导致非聚集主键索引。
我知道上述显然是允许的,但并不理想(特别是对于大表),也许在某些情况下,这是有道理的,但此类表的数量告诉我,这更像是粗心的表定义的结果。
例如,一个名为的表Transaction将有一个带有以下键的聚集索引:date, is_deleted. 此外,该表将在名为 的列上有一个非聚集主键id。
现在,其中一些表非常大,并且上面有许多外键引用,所以我想出了以下步骤,在 Aaron 在此线程中的回答的帮助下更改所有这些表无法删除非 PK 索引,因为它是在外键约束中引用:
id列创建主键集群约束我知道对于大表,我需要找到一个维护窗口来执行更改,但是您是否发现上述解决方案有任何我没有想到的问题或陷阱?这种方法会导致非聚集索引的其余部分出现碎片吗?
涉及很多表,我想确保我不会触发任何副作用。
我在我们的应用程序中有三种不同的产品,即车辆、黄金和财产。每个产品都有近 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) 如何在此 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)
结果
任何想法,为什么以下查询中的第一个返回带有 -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 用户配置为无权访问 DDL 语句但有权访问运行TRUNCATE TABLE命令。我知道在幕后它是一个 DDL。
我在搜索引擎上找不到这个。
我正在尝试提出一个数据库脚本,用于将应用程序数据库的早期版本迁移到更高版本。差异相当大,完成迁移将涉及创建新表、重命名表、添加函数、添加具有依赖于这些函数的计算列的视图等。脚本完成后,我将其交给其他人在目标环境上运行。
我希望能够在单个事务中运行整个迁移,这样如果出现问题,回滚就很容易了。
我遇到的问题是,当脚本尝试时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) 我正在使用 SentryOne,并且我认为这是一个死锁过程。它显示的数据库 ID 为 32767,对象 ID 为 -710746692。我查看了 sys.databases 和 sys.objects 并没有找到任何关于这些的东西。我搜索了数据库 ID,并认为它是 sql server 拥有的隐藏资源数据库。但是,谷歌搜索没有返回任何对对象 id 有意义的内容。
什么是对象 ID -710746692?
最近,当我不得不将大量内部应用程序迁移到新的 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 会成为问题吗?
提前致谢
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
我知道之前已经问过同样的问题,但情况略有不同,我想更多地解释为什么它在我的上下文中失败,当(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 ×10
sql-server-2016 ×10
t-sql ×2
dns ×1
index ×1
json ×1
kerberos ×1
performance ×1
permissions ×1
ssms ×1
transparent-data-encryption ×1
truncate ×1