我试图从表中返回一组不同的部门名称 - 没什么特别的。但是,使用以下查询时会显示重复项:
select distinct department_name
from dbo.departments;
Run Code Online (Sandbox Code Playgroud)
我也试过:
select distinct department_name
from dbo.departments
group by department_name;
Run Code Online (Sandbox Code Playgroud)
所以这让我相信我可能在值中隐藏了字符,果然,当我检查字符串的长度时,它们返回了不同的值。所以,我决定使用堆栈溢出这个问题中的函数来定位隐藏字符。奇怪的是,这只返回 SPACE。然后我尝试了以下查询,它根本没有区别:
select distinct ltrim(rtrim(department_name)) as department_name
from dbo.departments;
Run Code Online (Sandbox Code Playgroud)
出于好奇,我将这些值转换为VARBINARY并注意到它们具有完全相同的二进制值,并且对二进制值执行 aDISTINCT确实会产生一个唯一的结果集。
我也尝试在VARCHAR和NVARCHAR和到不同的排序规则之间进行转换(值在同一列中,在使用 Latin1_General_CI_AI 的同一数据库中)。我真的需要能够从这张表中得到一个不同的集合。有谁知道可能导致这个问题的原因是什么?
更新
经过进一步调查,这个问题似乎只发生在以十六进制值结尾的字符串中0xA000。列中不以该字符结尾的任何值都可以。
更新 2
如果我0xA000从字符串中删除字符,我可以DISTINCT像这样正常应用:
DECLARE @binary VARBINARY(8) = 0xA000;
DECLARE @string VARCHAR(8) = CONVERT(VARCHAR(MAX), @binary);
UPDATE dbo.departments
SET department_name = REPLACE(department_name, @string, '');
Run Code Online (Sandbox Code Playgroud)
但这不会长期有效,因为用户可以更新此表,我需要调整每个查询以在WHERE子句中进行替换。我现在正在使用一种解决方法,它只不过是MIN用于返回长度最短的条目。这不太理想,因为 distinct 的问题也会影响大多数其他语言元素,例如GROUP BY …
我已经在“订单”表上实现了系统版本化临时表。应用程序使用不同的访问模式来修改此表中的数据。有来自应用程序的直接语句,或者应用程序在显式事务中运行长批处理,其中对多个表进行了多次更改。“订单”表上的更新不是那些长批次中的第一条语句!因此,有时我们会面临以下错误。
系统版本化表“Orders”上的数据修改失败,因为事务时间早于受影响记录的期间开始时间。
显然,这是系统版本化临时表的标准行为。https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-2017#how-does-temporal-work
这是总是需要在异常例程中处理的东西吗?还是微软正在考虑改变这种行为?
-- 模拟错误信息的脚本:
CREATE TABLE dbo.Orders
(
[OrderId] INT NOT NULL PRIMARY KEY CLUSTERED
, [OrderValue] DECIMAL(19,4)
, [ValidFrom] DATETIME2 (2) GENERATED ALWAYS AS ROW START
, [ValidTo] DATETIME2 (2) GENERATED ALWAYS AS ROW END
, PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.OrdersHistory));
GO
INSERT dbo.Orders ([OrderId], [OrderValue])
VALUES (1, 9.99), (2, 9.99);
GO
SELECT * FROM dbo.Orders;
GO
--Run first query
BEGIN TRAN
WAITFOR DELAY '00:00:15';
UPDATE dbo.Orders
SET …Run Code Online (Sandbox Code Playgroud) 我试图找到 MS SQL 2016 的合规性确认 - 如果它完全符合 ANSI SQL-92 标准。
我在Microsoft Docs上发现这篇文章指出它不是,但它指的是 ODBC 驱动程序和 Microsoft Jet 引擎 - 不确定这是否完全相同,它不应该也与 T-SQL 相关吗?
我有一个数据库,其中 DBCC CHECKTABLE 在许多小表或空表上运行需要超过 15 分钟。当它完成时,没有失败或错误。服务器上其他所有内容的性能都处于非常可接受的状态。同时没有其他东西在运行。
我还尝试了 DBCC CLEANTABLE 并使用全扫描更新了统计信息。
我使用的是 SQL Server 2016 企业版 (13.0.5201.2)
示例表:
CREATE TABLE [Schema1].[Table1](
[col1] [int] NOT NULL,
[col2] [nvarchar](100) NOT NULL,
[col3] [xml] NOT NULL,
CONSTRAINT [PK_1] PRIMARY KEY CLUSTERED
(
[col1] ASC,
[col2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud) 我有一个总是过滤状态的查询,这些方式中的一种是否比另一种方式有性能优势?
(这是在即席查询的上下文中。UserStatus 的数据类型是 int)
...
AND UserStatus = 1
...
Run Code Online (Sandbox Code Playgroud)
或者
DECLARE @userStatus int = 1
...
AND UserStatus = @userStatus
...
Run Code Online (Sandbox Code Playgroud)
(ps 请不要谈论参数和文字在值未知/变化时有何不同,这是一个不同的话题)
如果我在 master 数据库中创建了一个存储过程,并且我想从我的任何数据库中执行它,我只需点击以下链接:
这给了我这个代码示例:
只需按照上面的示例,我就可以从任何数据库调用我的过程。
如果我在 master 中创建一个表数据类型,我如何在我的任何数据库中使用它?
use master
IF NOT EXISTS (select * from sys.types where name = 'theReplicatedTables')
CREATE TYPE theReplicatedTables AS TABLE
( OBJ_ID INT NOT NULL,
PRIMARY KEY CLUSTERED (OBJ_ID)
);
use APIA_Repl_Sub
go
declare @the_tables [dbo].[theReplicatedTables]
Run Code Online (Sandbox Code Playgroud)
sql-server stored-procedures datatypes sql-server-2016 table-variable
我使用全局临时表来轻松集成测试我的 SQL Server 支持的应用程序。
但该函数min_active_rowversion似乎不包括全局临时表,如下所示:
using (var connection = new SqlConnection("data source=.;Integrated Security=True"))
{
connection.Open();
connection.Execute("create table ##mytable ( Id int, rv rowversion )");
var a = ToUInt64(connection.Query<byte[]>("select min_active_rowversion()").Single()); // => 20001
var x = ToUInt64(connection.Query<byte[]>("insert into ##mytable (Id) output Inserted.rv values (1)").Single()); // => 22647
var b = ToUInt64(connection.Query<byte[]>("select min_active_rowversion()").Single()); // => 20001
}
Run Code Online (Sandbox Code Playgroud)
我在任何地方都看不到此限制。这可以工作吗?如果是这样,如何?
我想创建一个带有NOT NULLbool 列的表。
我用TINYINT与CHECK约束BETWEEN 0 and 1。约束是新的,因此是可信的
现在我希望 SQL 优化器现在知道这个列只能是 0 和 1,所以当我写查询时,col >= 2我会在实际执行计划中看到常量扫描(就像我在检查NULL或SELECT TOP (0)
但事实并非如此,它选择了表扫描。我还需要在此列上建立索引吗?
在我下面的测试中,我使用TINYINT了CHECK约束。用户定义类型基于TINYINTwith boundRULE和 good old BIT。
GO
CREATE TYPE dbo.myBool
FROM [INT] NOT NULL
GO
CREATE RULE dbo.R_Bool AS @value BETWEEN 0 AND 1
go
EXEC sys.sp_bindrule @rulename = N'R_Bool'
, @objname = N'myBool'
GO
DROP TABLE IF EXISTS dbo.RuleTest
CREATE …Run Code Online (Sandbox Code Playgroud) 我有 SQL Server 2016 SP2 (13.0.5237.0)。这是我最近在系统中注意到的死锁图。死锁优先级高的进程被选为牺牲品(可能是因为与其他进程相比日志使用率高)。但这不应该发生。这是 SQL 中引入的缺陷吗?有没有办法防止死锁优先级高的进程成为受害者?这是死锁xml:
<deadlock>
<victim-list>
<victimProcess id="process1d3ea515848" />
</victim-list>
<process-list>
<process id="process1d3ea515848" taskpriority="10" logused="5800" waitresource="OBJECT: 9:290100074:0 " waittime="4711" ownerId="359850034" transactionname="user_transaction" lasttranstarted="2019-07-31T08:12:25.267" XDES="0x1d2f62d1840" lockMode="Sch-M" schedulerid="3" kpid="10320" status="suspended" spid="52" sbid="0" ecid="0" priority="5" trancount="4" lastbatchstarted="2019-07-31T08:13:30.990" lastbatchcompleted="2019-07-31T08:13:29.427" lastattention="1900-01-01T00:00:00.427" clientapp=".Net SqlClient Data Provider" hostname="XXX" hostpid="14944" loginname="NT AUTHORITY\SYSTEM" isolationlevel="read committed (2)" xactid="359850034" currentdb="9" currentdbname="XXX" lockTimeout="4294967295" clientoption1="673415200" clientoption2="128056">
<executionStack>
<frame procname="CreatePartition" line="30" stmtstart="2052" stmtend="2218" sqlhandle="0x03000900d670d75323ec7f0094aa000001000000000000000000000000000000000000000000000000000000">
ALTER PARTITION FUNCTION... </frame>
<frame procname="CreatePartitions" line="26" stmtstart="1618" stmtend="1788" sqlhandle="0x030009000f95cb5424ec7f0094aa000001000000000000000000000000000000000000000000000000000000">
EXEC CreatePartition </frame>
</executionStack>
<inputbuf>
Proc [Database …Run Code Online (Sandbox Code Playgroud) 我有很多大表(大约 1000 万行宽)需要定期加载到 SQL Server 2016 中以进行只读报告。我希望这些表在磁盘上尽可能小,这比加载或查询的性能改进更重要。
这是我对不需要进一步索引的表所做的工作:
DATA_COMPRESSION=PAGE. 表中的列类型是 varchar(不超过 512,不是最大值)、float、tinyint 或日期(不是日期时间)。所有列都创建为可为空的,并且没有定义主键或外键——它们与查询无关,表永远不会直接更新。一切的默认排序规则是SQL_Latin1_General_CP1_CI_AS.
当我这样做时,我可以看到sys.allocation_units该页面数据压缩已应用于堆,并且我可以看到sys.partitions填充因子正确为 0 (100%)。由于表比未压缩的表小得多,我认为压缩已完成。
但是,如果我然后使用相同的选项重建DATA_COMPRESSION=PAGE,则假定已经压缩的表会缩小大约 30%!看起来它从每个数据页大约 17 行到每页 25 行。(虽然只有一次。在那之后再次重建不会使它比第一次重建更小。)
问题
所以我的问题是:(a)这里发生了什么?(b) 有没有办法在加载表时直接获得这个超小的压缩大小,而无需在加载数据后重建?
sql-server-2016 ×10
sql-server ×9
bcp ×1
collation ×1
compression ×1
datatypes ×1
dbcc ×1
deadlock ×1
distinct ×1
performance ×1
sql-standard ×1
t-sql ×1