我在 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 2019 (15.0.x) 的服务器。
当我们进行完整数据库备份(通过右键单击数据库,然后单击“任务”,然后单击“备份”)时,是否包括备份所有项目,然后Programmability将其还原到其他服务器?
很明显,省略 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) 我看到有人交换了下面的代码:
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) 我有几个表,通常具有可为空的“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) 我不是 DBA/SQL 专家,所以如果这是发帖的论坛,请原谅。
我们的生产数据库存在一个问题,日志文件没有以 LDF 格式存储。DBA 希望删除我们的生产数据库并恢复完整备份来解决问题,这是最佳实践吗?应用程序有多个到该数据库的活动连接,当数据库恢复时这些连接是否会自动重新连接?
对于下面的查询,我试图弄清楚为什么 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) 给出下表:
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 来说更像是一种“防御”机制 - 它更喜欢错误,因此需要用户明确决定他们想要做什么,而不是在用户不知情的情况下给出可能意外的查询结果。意识到?
我有一个我想要改进的程序,它使用这个 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)
这种格式导致执行计划进行索引扫描。