小编Eri*_*ing的帖子

后悔身份:有没有办法强制插入指定身份列?

为了防止XY 问题,这是我们要解决的实际问题:

问题:

不幸的是,我们有一堆查找表,它们是在主键上使用标识列创建的,这是一个int. 我们希望可以简单地删除身份,但是,我们有一些带有指向身份列的外键的大型表,我的理解是在这种情况下删除身份很困难。我们对身份感到遗憾的原因是因为这些表需要跨多个环境同步,而开发人员通过编写脚本将数据插入到这些表中,而我们在多个环境上运行这些脚本但不一定总是按照相同的顺序,所以我们问开发人员始终:

  1. 启用身份插入
  2. 插入具有硬编码整数 ID 的行
  3. 禁用身份插入

如果每个人都这样做,数据要么保持同步,要么脚本失败,我们可以立即采取纠正措施来解决冲突。当然,有时开发者忘记遵守规则,直接无标识地插入,不同环境下以不同顺序运行的不同脚本的自动增量导致它们不同步,从而出现问题。

一个想法:

我们可以强制开发人员始终指定标识列吗?我认为没有办法简单地禁用这些表上的身份。如果我们将身份重新播种到较低的数字会怎样?当种子值已经存在时,任何未指定所有列的插入都会失败,并且会继续失败,直到插入尝试的次数超过现有(连续)行的数量。但是,在一次正确的插入之后,就会重新为表设定种子,下一次不正确的插入将再次使用自动增量。因此,这个想法的推断是在每次插入后(也许使用触发器,这感觉很奇怪,但可能有效?),或者按计划,或者可能每次我们运行开发人员的脚本时,将表重新设置为一个较低的现有数字。

这是一个合理的想法,和/或有更好的解决方案吗?

旁注:我们确实有一些其他想法,我认为这些想法超出了这个问题的范围,例如:

  1. 门控签入将解析脚本以插入某些表而不指定标识列,如果我们检测到这一点,则会失败。
  2. 将所有这些数据存储在源中并在部署时更新整个表。(而不是使用运行一次插入脚本。)
  3. 不要运行在所有环境上更改这些表的数据脚本,而是使用复制或其他同步机制。

尽管从长远来看,这些其他想法可能会更好,但似乎最容易实现的目标只是重新播种这些表,因此不正确的插入将会失败。

sql-server identity sql-server-2017

6
推荐指数
2
解决办法
1420
查看次数

统计和行估计

希望有人可以帮助我了解 SQL Server 如何使用 stats 来估计记录数。

测试脚本

USE [tempdb]

GO

CREATE TABLE t1
(
a INT NOT NULL, 
b INT NOT NULL, 
c INT CHECK (c between 1 and 50), 
CONSTRAINT pk_a primary key(a)
);

GO

INSERT INTO t1(a,b,c) 
SELECT number, number%1000+1, number%50+1 
FROM master..spt_values 
WHERE type = 'P' AND number BETWEEN 1 and 1000;

GO

CREATE STATISTICS s_b ON t1(b);
CREATE STATISTICS s_c ON t1(c);

GO
Run Code Online (Sandbox Code Playgroud)

示例查询

DECLARE @c INT=300 
SELECT * FROM t1 WHERE b>@c 
SELECT * FROM …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2016 cardinality-estimates

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

SQL Server 2017:批处理模式自适应联接如何工作?

批处理模式自适应联接是2017 年查询处理器中一系列功能的一部分,其中包括:

那么自适应连接是如何工作的呢?

sql-server sql-server-2017 adaptive-joins

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

使用 Hallengren 脚本指定不同的日志文件位置

我很欣赏 Ola Hallengren 的剧本。作为 SQL Server 的新手,它们让我的生活变得更加轻松。谢谢哈伦格伦先生。

我有 5 个需要在不同时间备份的用户数据库,因此USER_DATABASES我没有使用,而是提供数据库名称。当我使用脚本创建存储过程时,我将输出文件目录指定为类似G:\Logs\Backups. 日志文件在那里,但最好在日志文件名中包含数据库名称,或者将日志文件路径作为参数传递。

我也在登录dbo.CommandLog。无需查看内部即可识别我正在查找的日志文件会很好。

有没有办法做到这一点,而不改变maintenance_solution.sql

我不喜欢修改的想法,因为当更新出来时,那些就会消失。对我来说,脚本非常复杂,因为我正在跟上 MS SQL 和 T-SQL 的步伐。

任何见解表示赞赏。

雪莉

sql-server ola-hallengren

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

在同一个查询中使用 WITH 和 IF

我正在尝试使用WITH子句和IF语句,但它似乎不起作用,我找不到任何原因。语法应该是正确的,但它仍然在抱怨语法。

我收到的错误是“';'附近的语法不正确。我尝试删除;字符,但后来显示“关键字'IF'附近的语法不正确。

甚至可以像这样使用 WITH 和 IF 语法吗?该查询在没有IF语句的情况下也能工作(只有一个选择查询)。

With measurements as 
        (
        (SELECT * from measurement_database1)
        UNION ALL
        (SELECT * from measurement_database2)
        UNION ALL
        (SELECT * from measurement_database3)
        );

    IF @device= 'en1' AND @other_parameter= 'yes'
        (
        select * from measurements where device like 'en1' and op like 'yes'
            );
    IF @device= 'en2' AND @other_parameter= 'no'
        (
        select * from measurements where device like 'en2' and op like 'no'
            );
    IF @device= 'en3' AND …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2012

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

SQL Server 2017 Linux CU1 - 修改文件遇到操作系统错误 31

我有一台“VMWare RHEL 7.4”机器,安装了“SQL Server 2017 Linux CU1”,并创建了一个“Linux 线性卷”,当我尝试恢复“线性卷”中的数据库备份时,请参阅底部的步骤我收到以下错误。

/* 消息 5149,级别 16,状态 3,第 6 行 MODIFY FILE 在尝试扩展物理文件 '/sqldata/mssql_data/defense/defense_Data_01.MDF 时遇到操作系统错误 31(连接到系统的设备无法正常工作。) '。消息 3013,级别 16,状态 1,第 6 行 RESTORE DATABASE 异常终止。*/

我能够毫无问题地恢复“/var/opt/mssql/data”上的数据库备份,然后我分离数据库并将其移动到“线性卷”,并且我能够很好地附加数据库,但是任何操作需要扩展数据文件失败并出现相同的错误消息。

我已经以与 Oracle 和 PostgreSQL 数据库相同的方式设置了“Linux 线性卷”,并且它始终与这些数据库配合良好。

你见过这个问题吗?这是“SQL Server 2017 Linux CU1”的错误吗?

创建 Linux 线性卷

  1. vmware 添加 /dev/sdc 磁盘 100GB
  2. 对 /dev/sdc 进行分区并创建 100gb fdisk /dev/sdc 的 /dev/sdc1 分区
  3. 创建卷组 vgcreate vgsqldata /dev/sdc1 vgscan vgdisplay vgsqldata
  4. 逻辑卷 lvcreate -l 25599 vgsqldata -n lvsqldata lvdisplay -v /dev/vgsqldata/lvsqldata
  5. 格式化卷 mkfs.ext3 /dev/vgsqldata/lvsqldata
  6. 挂载 …

sql-server linux sql-server-2017

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

创建聚集索引并希望添加日志文件

我们正在向一个 60 亿行的表添加一个聚集索引。这是一个在线操作(15 小时后)。

如果我们在此过程中添加另一个日志文件,是否会alter database add log file阻止命令应用程序?

sql-server sql-server-2014

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

SQL Server 2016 SQL 代理令牌不起作用

我在整个企业的许多 SQL 代理作业步骤中都有这个,并且它按预期工作:

sqlcmd -E -S $(ESCAPE_SQUOTE(SRVR)) -d master -Q "EXECUTE MyStoredProc etc..."
Run Code Online (Sandbox Code Playgroud)

但是在我的新 SQL Server 2016 实例上,它只会产生一个命名管道连接错误(这是一个完全的红鲱鱼)。

另一方面,这在我的新服务器上运行良好:

sqlcmd -E -S MyExplicitServerName -d master -Q "EXECUTE MyStoredProc etc..."
Run Code Online (Sandbox Code Playgroud)

为什么 SRVR 令牌不起作用?
如果我在命令提示符下启动 sqlcmd 并告诉它打印$(ESCAPE_SQUOTE(SRVR))它说:

'SRVR' scripting vaiable not defined.
Run Code Online (Sandbox Code Playgroud)

这是一个非常基本的、简单的安装,只有默认实例。

sql-server sqlcmd sql-server-agent sql-server-2016

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

在 SQL Server 的 CHECK 约束中使用 UDF 的当前状态(2022)是什么?

SQL Server 允许在约束中使用用户定义函数 (UDF) CHECK- 它有许多用例 - 我不会深入讨论 - 但我最近面临着实现一个经过验证的重要业务/域约束一个表中的数据基于另一表中的非唯一、非关键数据 - 这意味着该约束不能使用任何内置约束(FOREIGN KEYUNIQUE或基于普通行值的CHECK约束)来实现。

我立即选择的是TRIGGER,因为微软自己的文档指出TRIGGER对象是实现非平凡约束的预期方式:

当约束支持的功能无法满足应用程序的功能需求时,DML 触发器最有用。[...] 与CHECK约束不同,DML 触发器可以引用其他表中的列。例如,触发器可以使用SELECT另一个表中的数据来与插入或更新的数据进行比较,并执行其他操作,例如修改数据或显示用户定义的错误消息。

稍等一下:Microsoft 写道“与CHECK约束不同,DML 触发器可以引用其他表中的列” - 但这是误导性的!CHECK约束可以通过 UDF 间接引用其他表中的列。

...所以我认为那里有一些模糊和过时的信息 - 所以让我们做更多的研究来看看CHECKUDF 的约束是否是正确的方法...

...好吧,CHECK约束中的 UDF 似乎名声不好:有关于性能不佳和缺乏形式正确性的批评评论(一个获胜的组合......),但我注意到我读过的文章和帖子,包括实际上,所有有关 UDF 和CHECK约束的 Google 搜索结果都是旧的......

  • Google 搜索结果中排名第一的“sql server check constraint udf”是一篇可以追溯到2001 年 …

sql-server constraint check-constraints

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

用于在 SQL Server 中的聚集索引上生成页锁的示例查询/DDL(无提示)

我们目前有一些ALLOW_PAGELOCKS设置为关闭的索引。这样做大概是为了减少死锁。但是,我怀疑当时它真的会产生影响。

现在我试图了解 SQL Server 何时实际选择开始锁定页面而不是聚集索引中的键。我最近问过 Jonathan Keyhaisas,他告诉我如果我在多个后续页面上触摸行,就会发生这种情况。但是,我没有通过使用示例查询更新聚集索引中的行来获得任何独占页面锁。

你能通过示例查询和表帮助我更好地理解页锁吗?我正在运行 SQL Server 2008 SP4。

提前致谢

马丁

sql-server-2008 sql-server locking

4
推荐指数
1
解决办法
208
查看次数