标签: sql-server

DELETE 查询后数据库大小增加

我在 SQL Server 2019 的一个表中有一个数据库,其中包含大量 varbinary(MAX) 重复记录。我们需要删除重复项,因此我运行了删除查询来删除重复项。数据库大小在删除语句之前没有保持不变,而是在查询完成后增加。我即将应用 DBCC SHRINKFILE(N'myDatabase', 0),但我真的很好奇为什么数据库大小会增加。附件是我的删除查询。

DELETE from Document WHERE DocumentId in 
(
    SELECT t.DocumentId
    FROM (
        SELECT s.*,
          ROW_NUMBER() OVER (PARTITION BY s.DocumentName, s.SubmitDateTime, s.DocumentType ORDER BY s.DocumentName, s.SubmitDateTime, s.DocumentType) AS [RowCount]
        FROM Document s
        LEFT OUTER JOIN Staging b ON s.DocumentId = b.DocumentId
        LEFT OUTER JOIN RejectTable r ON  s.DocumentId = r.DocID
        WHERE b.DocumentId IS NULL
          AND r.DocID IS NULL
          AND s.SubmitDateTime IS NOT NULL
          AND s.InsertDateTime IS NOT NULL
          AND s.DocumentName IS NOT …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2019

2
推荐指数
1
解决办法
1017
查看次数

SQL Server 存储过程是否默认备份?

我们有两台运行 SQL Server 2019 (15.0.x) 的服务器。

当我们进行完整数据库备份(通过右键单击数据库,然后单击“任务”,然后单击“备份”)时,是否包括备份所有项目,然后Programmability将其还原到其他服务器?

sql-server backup stored-procedures restore

2
推荐指数
1
解决办法
112
查看次数

为什么 SQL Server 只有一个默认实例?

为什么 SQL Server 只有一个默认实例?这个问题是在一次采访中问我的。

sql-server

2
推荐指数
1
解决办法
660
查看次数

查找“裸”varchar

很明显,省略 varchar 的长度是一件坏事。不幸的是,我现在正在使用发生这种情况的代码库。广泛地。我想纠正这一点。第一步是查找出现的情况。这就是我需要帮助的地方。

使用我能想到的所有同义词在各种网络引擎上进行搜索都没有返回权威答案。我要问的是

  • 我错过的其他测试用例
  • 一种全面、规范的查找无长度声明的方法

通常在 Windows 开发环境(SSMS、Powershell、.Net 等)上可用的任何技术都是好的。采用更多利基技术的答案对于更广泛的社区来说会很有趣,但对我个人来说就不那么有趣了。

测试

由于所讨论的四种数据类型 - char、nchar、varchar 和 nvarchar - 都以字符 CHAR 结尾,因此我在下面的测试中单独使用它。这可以避免列表变得臃肿,并使添加更多测试变得更简单。如果需要的话,复制-粘贴-替换会很容易。

-- These are all legal; the regex must not return these
char(9)
char (9)            -- with a space
char    (9)         -- with a tab
char         (9)    -- tab space tab space
char(max)
char
(9)                 -- a new line between type and length

character(9)
CAST(999 AS character(9))

char varying(9)
character varying(9)
CAST(999 AS char varying(9))
CAST(999 AS character varying(9)) …
Run Code Online (Sandbox Code Playgroud)

sql-server varchar ssms regex

2
推荐指数
1
解决办法
131
查看次数

我们可以用 UNION ALL 来交换逻辑或吗?

我看到有人交换了下面的代码:

SELECT
    PK1
    , PK2
    , PK3
    , PK4
    , C
    , B
    , SUM(NUMERIC_1)
    , SUM(NUMERIC_2)
    , MAX(NUMERIC_3)
    , SUM(NUMERIC_4)
FROM MATDOC_EXTRACT
WHERE A = ''
      AND (
          (
              (
              B = ''
              OR B = 'K'
          )
              AND (
                  C = '01'
                  OR C = '02'
                  OR C = '07'
                  OR C = '08'
              )
          )
          OR (
              B = ''
              AND (
                  C = '03'
                  OR C = '04'
              )
          )
      )
GROUP BY PK1
         , PK2 …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql union

2
推荐指数
1
解决办法
261
查看次数

如果列存在则条件 WHERE

我有几个表,通常具有可为空的“CreatedDate”和/或“ModifiedDate”日期时间列。我想要一个查询,可以从任何单个表中进行选择,其中一个、两个或都不存在日期时间列,并且每列都BETWEEN提供(单独的)范围。

这是一个粗略的(非工作的)示例。这尝试用来COL_LENGTH确定列是否存在。但是,如果一列不存在,则会引发错误,我相信是因为WHERE仍在评估整个列。

SELECT * FROM tableName
WHERE 1=1 AND
(COL_LENGTH(tableName, 'CreatedDate') IS NULL OR CreatedDate BETWEEN @CreatedFrom AND @CreatedTo) AND
(COL_LENGTH(tableName, 'ModifiedDate') IS NULL OR ModifiedDate BETWEEN @ModifiedFrom AND @ModifiedTo)
Run Code Online (Sandbox Code Playgroud)

这可以通过动态 SQL 来解决。但是,在这种情况下,我仅限于以读取为中心的权限。所以没有 EXEC、CREATE 或 INSERT。

这可以用静态 SQL 实现吗?

示例表

两列:

DECLARE @Table1 table
(
    Id int NOT NULL,
    CreatedDate datetime NULL,
    ModifiedDate datetime NULL
);

INSERT @Table1
    (Id, CreatedDate, ModifiedDate)
VALUES
    (1, NULL, NULL),
    (2, NULL, '20230101 01:23:45.678'),
    (3, '20230101 02:34:56.789', NULL),
    (4, …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql

2
推荐指数
1
解决办法
1121
查看次数

如果数据库恢复,数据库连接是否会自动重新连接?

我不是 DBA/SQL 专家,所以如果这是发帖的论坛,请原谅。

我们的生产数据库存在一个问题,日志文件没有以 LDF 格式存储。DBA 希望删除我们的生产数据库并恢复完整备份来解决问题,这是最佳实践吗?应用程序有多个到该数据库的活动连接,当数据库恢复时这些连接是否会自动重新连接?

在此输入图像描述

sql-server

2
推荐指数
1
解决办法
830
查看次数

为什么这些列在索引的 include 子句中指定而不是作为键列

对于下面的查询,我试图弄清楚为什么 SQL Server 在 sysjobhistory 表上建议的索引(也是导致查找的索引)是在 Job_Id 列上创建的,其中包括其他列:

Job_Id 包括(Run_date、Run_time、Instance_id)

据我了解,where 子句中的列应该出现在索引键中,以便可以进行搜索。Run_date 和 Run_time 出现在下面查询的 where 子句中,那么我们为什么可以将它们包含在索引中而不是将它们作为键列呢?

查询:

SELECT TOP 10000 run_date
     FROM msdb.dbo.sysjobhistory sh
     WHERE EXISTS (SELECT 1 FROM msdb.dbo.sysjobs sj WHERE sh.job_id = sj.job_id
     AND EXISTS (SELECT 1 FROM msdb.dbo.sysjobschedules sjs WHERE sjs.job_id = sj.job_id
     AND EXISTS (SELECT 1 FROM msdb.dbo.sysschedules ss WHERE ss.schedule_id = sjs.schedule_id 
     AND ss.freq_subday_type = 2
     AND ss.freq_subday_interval = 10 ))) 
     AND CAST(CAST([run_date] AS CHAR(8)) + ' ' + STUFF(STUFF(RIGHT('000000' + CAST([run_time] AS VARCHAR(6)), …
Run Code Online (Sandbox Code Playgroud)

index sql-server t-sql index-tuning

2
推荐指数
1
解决办法
685
查看次数

为什么 Varchar 的数据类型优先级低于 INT?

给出下表:

CREATE TABLE #a
(
    MyInt INT
)

INSERT INTO #a VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)

CREATE TABLE #b
(
    MyVarchar VARCHAR(10)
)

INSERT INTO #b VALUES('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('ten')
Run Code Online (Sandbox Code Playgroud)

如果我运行以下查询;

SELECT  *
FROM    #a
        LEFT JOIN #b
            ON #a.MyInt = #b.MyVarchar
Run Code Online (Sandbox Code Playgroud)

SQL Server 必须执行隐式转换,因为#a.MyInt#b.MyVarchar是不匹配的数据类型。由于数据类型优先级,具有最低类型优先级 (#b.MyVarchar) 的列将转换为较高优先级 (INT) 的类型

这意味着上面的查询等效于

SELECT  *
FROM    #a
        LEFT JOIN #b
            ON #a.MyInt = CONVERT(INT,#b.MyVarchar)
Run Code Online (Sandbox Code Playgroud)

两者都失败,因为其中某个值#b.MyVarchar对于列来说是无效值INT

我的问题是为什么 的VARCHAR优先级低于INT?如果是相反的情况,隐式转换将会成功,但我们会得到一个错误的查询。为什么错误比成功执行更可取?我的猜测是,这对于 SQL Server 来说更像是一种“防御”机制 - 它更喜欢错误,因此需要用户明确决定他们想要做什么,而不是在用户不知情的情况下给出可能意外的查询结果。意识到?

sql-server datatypes errors implicit-conversions

2
推荐指数
1
解决办法
101
查看次数

执行计划 - 由于 ISNULL 而不使用索引查找

我有一个我想要改进的程序,它使用这个 where 子句:

WHERE   p.PlatformId = ISNULL(@PlatformId, p.PlatformId)
and p.PayeeStsId     = 1
and p.PlatformPayeeId   = ISNULL(@platformPayeeId, p.PlatformPayeeId)
and pba.PayeeBankStsId=1
and a.Gcid = ISNULL(@Gcid, a.Gcid)
Run Code Online (Sandbox Code Playgroud)

ISNULL给我使用索引带来了问题,我怎样才能避免使用这种格式ISNULL

p.PlatformId = ISNULL(@PlatformAccountId, p.PlatformId)
Run Code Online (Sandbox Code Playgroud)

这种格式导致执行计划进行索引扫描。

sql-server performance-tuning

2
推荐指数
1
解决办法
300
查看次数