AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-76596

Lukas.Navratil's questions

Martin Hope
Lukas.Navratil
Asked: 2022-10-08 01:20:08 +0800 CST

比较 sql_variant 与 varchar 文字时的排序规则冲突

  • 6

我发现下面的查询在运行相同兼容性级别、相同设置选项等的两个 Azure 超大规模数据库上返回不同的结果。

IF CAST(ServerProperty('Edition') AS nvarchar(128)) = 'SQL Azure' BEGIN
    SELECT 1
END
IF ServerProperty('Edition') = 'SQL Azure' BEGIN
    SELECT 2
END
IF 'SQL Azure' = ServerProperty('Edition') BEGIN
    SELECT 3
END

在一个数据库上,它只返回 1,在另一个数据库上它返回 1,2 和 3。

我调查了根本原因,它似乎是由数据库的不同排序规则引起的。

对于以下查询:

SELECT SQL_VARIANT_PROPERTY(ServerProperty('Edition'), 'Collation')
SELECT name, collation_name, compatibility_level FROM sys.databases

只返回一行的数据库,结果是:

-----------------------------
SQL_Latin1_General_CP1_CI_AS

name         collation_name                   compatibility_level
------------ -------------------------------- -------------------
master       SQL_Latin1_General_CP1_CI_AS     140
my_database  SQL_Latin1_General_CP850_CI_AS   150

数据库返回 1,2,3 的结果是:

-----------------------------
SQL_Latin1_General_CP1_CI_AS

name         collation_name                   compatibility_level
------------ -------------------------------- -------------------
master       SQL_Latin1_General_CP1_CI_AS     140
my_database  SQL_Latin1_General_CP1_CI_AS     150

因此,没有强制转换的简单比较是sql_variant与varchar(当我使用时没有区别N'SQL Azure')比较,其中底层nvarchar的sql_variant排序规则在一种情况下与我查询的数据库不同,在另一种情况下它是匹配的。

首先,我假设比较具有不同排序规则的两个字符串会失败,就像当您尝试加入具有不同排序规则的两列时它会失败一样,但这里显然不是这种情况。

无论如何,安全比较可能sql_variant与 a的函数的输出的最佳方法是varchar什么?

sql-server collation
  • 2 个回答
  • 213 Views
Martin Hope
Lukas.Navratil
Asked: 2022-03-01 03:39:30 +0800 CST

仅在使用 SESSION_CONTEXT 时在 Azure 中进行非并行计划

  • 6

我正在观察本地计算机和 Azure SQL 上的查询计划之间的奇怪差异。我正在尝试实现行级安全性,我从 SESSION_CONTEXT 读取用户标识符,然后在 TVF 中检查用户是否具有访问权限。

在我的本地机器上 - SQL Server 2019 Developer edition,兼容级别为 150 的数据库,查询计划符合预期。但是,当我在也是 150 兼容级别的 Azure DB 上运行它时,我只能获得带有NonParallelPlanReason="NonParallelizableIntrinsicFunction". 我尝试了一个超大规模数据库以及弹性池中的一个数据库,结果在两个数据库上都是相同的。

您可以使用以下代码重现它:

CREATE TABLE Users (
    UserIdentifier nvarchar(100) PRIMARY KEY CLUSTERED
)

INSERT INTO Users (UserIdentifier) VALUES ('MyUserIdentifier')

CREATE TABLE TableWithRLS (
    Id int NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    DataColumn nvarchar(100) NULL
)

INSERT INTO TableWithRLS (DataColumn) 
SELECT TOP 10000000 A.[name] FROM sys.all_columns  AS A
CROSS JOIN sys.all_columns  AS B
CROSS JOIN sys.all_columns  AS C


CREATE OR ALTER FUNCTION CheckAccess (@userIdentifier varchar(100))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
    SELECT TOP 1 1 AS HasAccess FROM dbo.Users WHERE UserIdentifier = @userIdentifier

EXEC sp_set_session_context N'UserIdentifier', N'MyUserIdentifier', 1

-- This query gets always non-parallel query plan on Azure
SELECT MAX(DataColumn) FROM TableWithRLS AS X
CROSS APPLY CheckAccess(CAST(SESSION_CONTEXT(N'UserIdentifier') AS nvarchar(100)))

当我首先将会话上下文中的值选择到变量中时,即使在 Azure 中它也会生成可并行化的查询计划。

DECLARE @userIdentifier AS nvarchar(100) = CAST(SESSION_CONTEXT(N'UserIdentifier') AS nvarchar(100))
SELECT MAX(DataColumn) FROM TableWithRLS AS X
CROSS APPLY CheckAccess(@userIdentifier)

不幸的是,我不能这样做(或者至少我不知道该怎么做),因为我需要一个内联 TVF。

Azure 的查询计划:https ://www.brentozar.com/pastetheplan/?id=ByxZm45e9

本地查询计划:https ://www.brentozar.com/pastetheplan/?id=BylHXV9lc

Azure 中的 SESSION_CONTEXT 实现有什么不同可能导致这种情况吗?或者有没有人有任何其他想法可能是什么问题?

sql-server performance
  • 2 个回答
  • 575 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve