我想根据其 Unicode 代码点将 Unicode 字符串变量设置为特定字符。
我想使用 65535 以外的代码点,但 SQL Server 2008 R2 数据库的排序规则为SQL_Latin1_General_CP1_CI_AS
.
根据Microsoft 的 NCHAR 文档,该NCHAR
函数采用如下整数:
整数表达式
当数据库的排序规则不包含补充字符 (SC) 标志时,这是一个从 0 到 65535(0 到 0xFFFF)的正整数。如果指定了超出此范围的值,则返回 NULL。有关补充字符的更多信息,请参阅排序规则和 Unicode 支持。
当数据库的排序规则支持补充字符 (SC) 标志时,这是一个从 0 到 1114111(0 到 0x10FFFF)的正整数。如果指定了超出此范围的值,则返回 NULL。
所以这段代码:
SELECT NCHAR(128512);
Run Code Online (Sandbox Code Playgroud)
NULL
在此数据库中返回。
我希望它返回与此相同的:
SELECT N'';
Run Code Online (Sandbox Code Playgroud)
如何在排序规则“不包含补充字符 (SC) 标志”的数据库中使用代码(不使用实际表情符号字符)将 Unicode 字符串变量(例如 nvarchar)设置为表情符号?
(最终我希望任何角色都能工作。我只是为了便于参考而选择了表情符号。)
(虽然服务器是SQL Server 2008 R2,但我也很好奇以后版本有什么解决方案。)
假设没有办法,我可以在另一个具有适当排序规则的数据库中引用内联用户定义函数吗?
如何找到具有“补充字符”标志的归类?
这在我们的服务器上不返回任何记录:
SELECT * FROM sys.fn_helpcollations()
WHERE name LIKE 'SQL%[_]SC';
Run Code Online (Sandbox Code Playgroud)
似乎引入了 SQL Server …
如果在事件会话中向事件添加“太多”操作,您将收到此错误:
消息 25639,级别 16,状态 23,第 1 行 事件“[事件名称]”超出了允许的绑定操作数。
允许多少动作?它是否因事件而异?
根据实验,答案似乎是 27 sqlserver.rpc_completed
。但我没有在任何Microsoft 文档中找到该数字。它似乎因事件而异,因为我能够为sqlserver.sql_batch_completed
.
失败的示例代码:
CREATE EVENT SESSION [Test] ON SERVER
ADD EVENT sqlserver.rpc_completed(
ACTION(
package0.callstack,
package0.collect_cpu_cycle_time,
package0.collect_current_thread_id,
package0.collect_system_time,
package0.event_sequence,
package0.last_error,
package0.process_id,
sqlos.cpu_id,
sqlos.numa_node_id,
sqlos.scheduler_address,
sqlos.scheduler_id,
sqlos.system_thread_id,
sqlos.task_address,
sqlos.task_elapsed_quantum,
sqlos.task_resource_group_id,
sqlos.task_resource_pool_id,
sqlos.task_time,
sqlos.worker_address,
sqlserver.client_app_name,
sqlserver.client_connection_id,
sqlserver.client_hostname,
sqlserver.client_pid,
sqlserver.context_info,
sqlserver.database_id,
sqlserver.database_name,
sqlserver.is_system,
sqlserver.nt_username,
sqlserver.plan_handle))
GO
DROP EVENT SESSION [Test] ON SERVER
GO
Run Code Online (Sandbox Code Playgroud)
成功的示例代码(相同但不包括最后一项):
CREATE EVENT SESSION [Test] ON SERVER
ADD EVENT sqlserver.rpc_completed(
ACTION(
package0.callstack,
package0.collect_cpu_cycle_time,
package0.collect_current_thread_id,
package0.collect_system_time, …
Run Code Online (Sandbox Code Playgroud) 我们有一个带有 Key Lookup 的查询,它估计每次执行有数千行。据我了解,每次执行应该只有一行。我知道统计数据可能会产生误导,但优化器不明白主键是唯一的吗?
此查询中涉及的表具有以下形式的聚集主键:
/****** Object: Index [PK_Table_Name] Script Date: 6/16/2021 9:52:12 AM ******/
ALTER TABLE [dbo].[Table_Name] ADD CONSTRAINT [PK_Table_Name] PRIMARY KEY CLUSTERED
(
[Table_Name_ID] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
据我了解,主键提供了对表中单行的唯一引用。
因此,对于它在非聚集索引中找到的每一行,它应该能够使用该索引对聚集索引的引用来检索它所需的单行,以满足其正在处理的行的其余查询过滤。(这是一个嵌套循环连接运算符。)
那么为什么它估计将近 4000 行将作为 Key Lookup 的一部分返回?(不是“对于所有执行”,大约 36,000,000 是 4000 和它期望从非聚集索引查找中得到的 9000 行的乘积。)
运行时统计数据显示该聚集索引查找有 2851 行和 2851 次执行,这正是我所期望的。
如果有帮助,这是在 Azure SQL 数据库中,带有@@version
:
Microsoft SQL Azure (RTM) - 12.0.2000.8
Apr 29 2021 13:52:20 …
Run Code Online (Sandbox Code Playgroud) sql-server execution-plan azure-sql-database query-performance
或者,微软是如何让时间旅行成为可能的?
考虑这个代码:
DECLARE @Offset datetimeoffset = sysdatetimeoffset();
DECLARE @UTC datetime = getUTCdate();
DECLARE @UTCFromOffset datetime = CONVERT(datetime,SWITCHOFFSET(@Offset,0));
SELECT
Offset = @Offset,
UTC = @UTC,
UTCFromOffset = @UTCFromOffset,
TimeTravelPossible = CASE WHEN @UTC < @UTCFromOffset THEN 1 ELSE 0 END;
Run Code Online (Sandbox Code Playgroud)
@Offset
设置在 之前 @UTC
,但它有时具有较晚的值。(我已经在 SQL Server 2008 R2 和 SQL Server 2016 上尝试过这个。你必须运行几次才能捕捉到可疑的事件。)
这似乎不仅仅是四舍五入或缺乏精度的问题。(事实上,我认为舍入是偶尔“修复”问题的原因。)示例运行的值如下:
因此日期时间精度允许 .880 作为有效值。
甚至Microsoft 的 GETUTCDATE 示例也显示 SYS* 值 …
我们正在尝试查看客户端是否能够访问数据库服务器,因为它收到错误:
[DBNETLIB][ConnectionOpen (Connect()).]SQL Server 不存在或访问被拒绝。
该错误在一段时间内不会发生,这通常是客户端无法访问目标服务器的结果(例如,数据库服务器名称不正确)。该错误发生在 Web 应用程序中以及使用 Windows Server 2003 Web Edition 操作系统工具测试 ODBC 连接时。
为了尝试确定导致问题的原因,我们想查看连接尝试是否到达数据库服务器。我们认为我们可以使用扩展事件来监控登录尝试。
sqlserver.process_login_finish
是 SQL Server 2016 中的一个新事件,它“在服务器完成登录处理(成功或失败)时生成”。
我们使用以下代码创建了一个事件会话:
CREATE EVENT SESSION [Test Login Audit] ON SERVER
ADD EVENT
sqlserver.process_login_finish
(
ACTION
(
package0.collect_system_time,
sqlserver.client_app_name,
sqlserver.client_hostname,
sqlserver.nt_username
)
)
ADD TARGET package0.ring_buffer;
GO
ALTER EVENT SESSION [Test Login Audit] ON SERVER
STATE = START;
GO
Run Code Online (Sandbox Code Playgroud)
然后我们多次连接到服务器,使用 Windows 和 SQL 身份验证,包括故意为 SQL 用户输入错误的密码。
然后我们查询扩展事件数据如下:
SELECT name, target_name, CAST(xet.target_data AS xml)
FROM sys.dm_xe_session_targets AS xet
JOIN …
Run Code Online (Sandbox Code Playgroud) 我们有内联函数,可以将数据收集到 XML 中,将派生的 XML 传递给其他函数,然后将其切碎并将其重组为字符串。
(你的“你不应该在 T-SQL 中做那种事情”是另一天的讨论。)
多年来,这在 2005 和 2008 R2 中一直运行良好。我们现在正在升级到 2016 SP1。使用这些函数在我们的生产服务器上运行不到一秒的查询现在在 2016 SP1 中运行得更快。那太好了,但是在 2016 SP1 上编译需要一个小时。严重地:
生产环境:
(它们都来自 SQL Sentry Plan Explorer。)
我们已经在 2008 (100) 和 2016 (130) 兼容性级别尝试了数据库(但我们还没有使用“传统基数估计”和“查询优化器修复”设置,目前这两个设置都为“关闭”)。我们尝试过使用QUERYTRACEON 9481
,似乎没有效果。
同样,这与最终的计划无关,因为它们都在很短的时间内运行。这是制定计划所需的时间。
我们已经设法用一组简化的代码在一定程度上重现了这个问题。调用以下示例中的顶级函数的语句在 SQL Server 2016 (SP1-CU5) 上编译需要 30-60 秒,但在 SQL Server 2008 R2 (SP3) 上编译和运行只需不到 1 秒。
/*
Create and populate table...
*/
CREATE TABLE TestXMLStuff (OrderID int, ProdLength int, ProdWidth int, ProdHeight int);
INSERT INTO TestXMLStuff (OrderID, ProdLength, ProdWidth, ProdHeight) …
Run Code Online (Sandbox Code Playgroud) 正如预期的那样,在“测试”中运行此结果:
SELECT
REPLACE(NCHAR(1234), NCHAR(1234), N'test');
Run Code Online (Sandbox Code Playgroud)
但是,运行此结果会生成“a?a”,其中没有“test”:
SELECT
REPLACE(N'a' + NCHAR(1234) + N'a', NCHAR(1234), N'test');
Run Code Online (Sandbox Code Playgroud)
我认为这可能与 haystack 而不是针的字符串连接有关,但是当我尝试这样做时,它仍然没有“工作”:
SELECT
REPLACE(N'a' + NCHAR(1234) + N'a', N'' + NCHAR(1234) + N'', N'test');
Run Code Online (Sandbox Code Playgroud)
结果:“a?a”
我怀疑这可能与它如何解释字符有关,所以我尝试指定一个二进制排序规则......并“修复”了这个问题:
SELECT
REPLACE(N'a' + NCHAR(1234) + N'a' COLLATE Latin1_General_100_BIN2, NCHAR(1234), N'test');
Run Code Online (Sandbox Code Playgroud)
结果:“atesta”。
为什么?
这种行为似乎对某些角色存在,但对其他角色不存在。
SELECT
REPLACE(N'a' + NCHAR(23423) + N'a', NCHAR(23423), N'test');
Run Code Online (Sandbox Code Playgroud)
结果:“atesta”(“作品”)
SELECT
REPLACE(N'a' + NCHAR(5342) + N'a', NCHAR(5342), N'test');
Run Code Online (Sandbox Code Playgroud)
结果:“a?a”(不“工作”)
为什么?
当我们在 SQL Server 2008 R2 实例上运行它时,它每次都会导致严重性为 20 的错误。它在我们的 SQL Server 2016 实例上没有这个问题。
询问:
DECLARE @v varchar(MAX) = REPLICATE(CONVERT(varchar(max),'a'),524289);
SELECT @v = @v FROM(SELECT 1 AS a) AS b;
Run Code Online (Sandbox Code Playgroud)
结果:
Location: tmpilb.cpp:3256
Expression: fNoReaderWriterConflict
SPID: 90
Process ID: 1576
Location: tmpilb.cpp:3306
Expression: fNoReaderWriterConflict
SPID: 90
Process ID: 1576
Msg 3624, Level 20, State 1, Line 4
A system assertion check has failed. Check the SQL Server error log for details. Typically, an assertion failure is caused by a software bug or …
Run Code Online (Sandbox Code Playgroud) 数据库连接字符串中的 MultiSubnetFailover 选项控制客户端尝试连接到数据库服务器的方式,尤其是当多个 IP 可用时。
关于正确的连接字符串语法是否为以下内容存在冲突的文档:
MultiSubnetFailover=Yes
Run Code Online (Sandbox Code Playgroud)
或者:
MultiSubnetFailover=True
Run Code Online (Sandbox Code Playgroud)
是否同时支持“Yes”和“True”?还是因驾驶员而异?如果是后者,是否有哪些驱动程序支持哪些语法的列表?
2023年3月30日更新:
此 Microsoft 文档暗示“True”或“Yes”适用于另一个选项:
Persist Security Info 关键字的默认设置为 false。将其设置为true 或 yes允许在连接打开后从连接获取安全敏感信息,包括用户 ID 和密码。将持久安全信息设置为 false 以确保不受信任的源无法访问敏感的连接字符串信息。
https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax
(强调已添加)
sql-server high-availability disaster-recovery connection-string
sql-server ×7
collation ×2
t-sql ×2
unicode ×2
datetime ×1
encoding ×1
errors ×1
functions ×1
optimization ×1
xml ×1