如果我在 NVARCHAR(max) 列上调用 Left([col], x),将输出保存在 NVARCHAR(x) 列中是否始终安全?

If I call Left([col], x) on an NVARCHAR(max) column, is it always safe to save the output in an NVARCHAR(x) column?

提问人:J. Mini 提问时间:10/24/2023 最后编辑:J. Mini 更新时间:10/31/2023 访问量:189

问:

一个常见的误解是,争论的是一个字符数,今天已经多次困扰着我。我问这个问题是为了进一步探讨这个话题。NVARCHAR(x)

考虑一列。从表中调用它。以下代码会失败吗?NVARCHAR(max)FOO_PERM_COLFOO_PERM_TABLE

CREATE TABLE #FOO_TEMP_TABLE
(
   FOO_TEMP_COL NVARCHAR(1000) NOT NULL
)

INSERT INTO #FOO_TEMP_TABLE
SELECT Left(FOO_PERM_COL, 1000)
FROM FOO_PERM_TABLE

如果代码可能失败(即抛出异常),我希望看到一些使其失败的例子。如果排序规则很重要,那么请说出来。如果代码不能失败,那么我希望通过参考文档来支持支持这一点的参数。

我希望的文档并不能说明全部情况。文档说它会将您的列修剪到指定的字符数,但这个 dbfiddle 让我怀疑它的作用不止于此。如果只减少到指定的字符数,那么我希望返回您输入的 unicode 字符。Dbfiddle 说它没有。我认为文档中的以下几行与这一点最相关LEFTLEFTSELECT LEFT(N'🙏', 1)

integer_expression 参数将 UTF-16 代理项字符计为一个字符。

sql-server 字符串 t-sql nvarchar

评论

0赞 jarlh 10/24/2023
定义失败。(异常,还是无效/损坏的数据?
0赞 J. Mini 10/24/2023
@jarlh例外。我会编辑。
0赞 Dale K 10/24/2023
您确实应该考虑使用 dba.stackexchange.com 来解决您的技术数据库问题
2赞 AlwaysLearning 10/24/2023
该函数对字符进行操作,但构成字符的内容取决于所使用的排序规则。db<>fiddle 没有执行您期望的操作,因为它不使用 *_SC(增补字符)默认数据库排序规则,因此它将数据类型视为具有 UCS-2 编码。比较 和 的输出。LEFTNCHARNVARCHARSELECT LEFT(N'🙏' COLLATE Latin1_General_100_CI_AS, 1)SELECT LEFT(N'🙏' COLLATE Latin1_General_100_CI_AS_SC, 1)
1赞 Charlieface 10/24/2023
@AlwaysLearning,是的,这看起来很糟糕 dbfiddle.uk/lZymXg40

答:

0赞 SQLpro 10/31/2023 #1

当您创建包含具有 �数组数据类型(CHAR、NCHAR、VARCHAR、NVARCHAR)的列的表时,数据库排序规则用于强制执行 colum 数据类型。

您可以在以下位置看到:

SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS

默认情况下,SQL Server 使用没有 emitcon 的 UTF16 编码,但只有在使用 SC(补充字符)排序规则时才能添加表情符号。

SC 排序规则列表可在以下位置找到:

SELECT *
FROM   sys.fn_helpcollations() 
WHERE  description LIKE '%supplementary characters%'

作为测试:

CREATE DATABASE DB_TEST_COLLATION COLLATE SQL_EBCDIC277_2_CP1_CS_AS
GO
USE DB_TEST_COLLATION 
GO
SELECT LEFT(N'🙏', 1 )

将返回:

CREATE DATABASE DB_TEST_COLLATION2 COLLATE Albanian_100_CI_AS_SC
GO
USE DB_TEST_COLLATION2
GO
SELECT LEFT(N'🙏', 1 )

会回来 🙏

CQFD系列

评论

0赞 J. Mini 11/1/2023
这并不能清楚地回答给定代码是否会失败的问题。
0赞 SQLpro 11/2/2023
正如 ISO 标准 SQL 所说,当作为参数传递的字符串超出定义的字符集或排序规则的范围时,返回值将始终为“?”,但不会出现错误消息。