简体   繁体   English

Oracle 中 N'String' 与 U'String' 文字的区别

[英]Difference between N'String' vs U'String' literals in Oracle

What is the meaning and difference between these queries?这些查询之间的含义和区别是什么?

SELECT U'String' FROM dual;

and

SELECT N'String' FROM dual;

In this answer i will try to provide informations from official resources在这个答案中,我将尝试提供来自官方资源的信息

(1) The N'' text Literal (1) N''文本字面量

N'' is used to convert a string to NCHAR or NVARCHAR2 datatype N''用于将字符串转换为NCHARNVARCHAR2数据类型

According to this Oracle documentation Oracle - Literals根据这个 Oracle 文档Oracle - Literals

The syntax of text literals is as follows:文本文字的语法如下:

在此处输入图片说明

where N or n specifies the literal using the national character set ( NCHAR or NVARCHAR2 data).其中Nn使用国家字符集( NCHARNVARCHAR2数据)指定文字。

Also in this second article Oracle - Datatypes同样在第二篇文章Oracle - 数据类型中

The N'String' is used to convert a string to NCHAR datatype N'String'用于将字符串转换为NCHAR数据类型

From the article listed above:从上面列出的文章:

The following example compares the translated_description column of the pm.product_descriptions table with a national character set string :以下示例将pm.product_descriptions表的translated_description列与国家字符集字符串进行比较

 SELECT translated_description FROM product_descriptions WHERE translated_name = N'LCD Monitor 11/PM';

(2) The U'' Literal (2) U'' 字面量

U'' is used to handle the SQL NCHAR String Literals in Oracle Call Interface (OCI) U''用于处理 Oracle 调用接口 (OCI) 中的 SQL NCHAR 字符串文字

Based on this Oracle documentation Programming with Unicode基于此 Oracle 文档Programming with Unicode

The Oracle Call Interface (OCI) is the lowest level API that the rest of the client-side database access products use. Oracle 调用接口(OCI) 是其余客户端数据库访问产品使用的最低级别 API。 It provides a flexible way for C/C++ programs to access Unicode data stored in SQL CHAR and NCHAR datatypes.它为 C/C++ 程序提供了一种灵活的方式来访问存储在 SQL CHARNCHAR数据类型中的 Unicode 数据。 Using OCI, you can programmatically specify the character set (UTF-8, UTF-16, and others) for the data to be inserted or retrieved.使用 OCI,您可以以编程方式为要插入或检索的数据指定字符集(UTF-8、UTF-16 和其他)。 It accesses the database through Oracle Net.它通过 Oracle Net 访问数据库。

OCI is the lowest-level API for accessing a database, so it offers the best possible performance. OCI 是用于访问数据库的最低级别的 API,因此它提供了可能的最佳性能。

Handling SQL NCHAR String Literals in OCI在 OCI 中处理 SQL NCHAR 字符串文字

You can switch it on by setting the environment variable ORA_NCHAR_LITERAL_REPLACE to TRUE .您可以通过将环境变量ORA_NCHAR_LITERAL_REPLACE设置为TRUE来打开它。 You can also achieve this behavior programmatically by using the OCI_NCHAR_LITERAL_REPLACE_ON and OCI_NCHAR_LITERAL_REPLACE_OFF modes in OCIEnvCreate() and OCIEnvNlsCreate() .您也可以通过编程方式使用实现这种行为OCI_NCHAR_LITERAL_REPLACE_ONOCI_NCHAR_LITERAL_REPLACE_OFF在模式OCIEnvCreate()OCIEnvNlsCreate() So, for example, OCIEnvCreate(OCI_NCHAR_LITERAL_REPLACE_ON) turns on NCHAR literal replacement, while OCIEnvCreate(OCI_NCHAR_LITERAL_REPLACE_OFF) turns it off.因此,例如, OCIEnvCreate(OCI_NCHAR_LITERAL_REPLACE_ON)打开NCHAR文字替换,而OCIEnvCreate(OCI_NCHAR_LITERAL_REPLACE_OFF)关闭它。

[...] Note that, when the NCHAR literal replacement is turned on, OCIStmtPrepare and OCIStmtPrepare2 will transform N' literals with U' literals in the SQL text and store the resulting SQL text in the statement handle . [...] 请注意,当NCHAR文字替换打开时, OCIStmtPrepareOCIStmtPrepare2会将 SQL 文本中的N'文字转换为U'文字,并将生成的 SQL 文本存储在语句句柄中 Thus, if the application uses OCI_ATTR_STATEMENT to retrieve the SQL text from the OCI statement handle, the SQL text will return U' instead of N' as specified in the original text .因此,如果应用程序使用OCI_ATTR_STATEMENTOCI语句句柄检索 SQL 文本,则 SQL 文本将返回U'而不是原始文本中指定的N'


(3) Answer for your question (3) 回答你的问题

From datatypes perspective, there is not difference between both queries provided从数据类型的角度来看,提供的两个查询之间没有区别

  • N' string ' just returns the string as NCHAR type. N' string '只返回NCHAR类型的string

  • U' string ' returns also NCHAR type, however it does additional processing to the string : it replaces \\\\ with \\ and \\ xxxx with Unicode code point U+ xxxx , where xxxx are 4 hexadecimal digits. U' string '也返回NCHAR类型,但它对string额外处理:它将\\\\替换为\\并将\\ xxxx替换为 Unicode 代码点U+ xxxx ,其中xxxx是 4 个十六进制数字。 This is similar to UNISTR(' string ') , the difference is that the latter returns NVARCHAR2 .这类似于UNISTR(' string ') ,不同之处在于后者返回NVARCHAR2

U' literals are useful when you want to have a Unicode string independent from encoding and NLS settings.当您想要独立于编码和 NLS 设置的 Unicode 字符串时, U'文字很有用。

Example:例子:

select n'\€', u'\\\20ac', n'\\\20ac' from dual;

N'\€' U'\\\20AC' N'\\\20AC'
----- ---------- ----------
\€    \€         \\\20ac

when using N' we denote that given datatype is NCHAR or NVARCHAR .当使用N'我们表示给定的数据类型是NCHARNVARCHAR

U' is used to denote unicode U'用于表示 unicode

The documented N'' literals are the same as standard character literals ( '' ) except that their data type is NVARCHAR2 and not VARCHAR2.记录的N''文字与标准字符文字 ( '' ) 相同,只是它们的数据类型是 NVARCHAR2 而不是 VARCHAR2。 It is important to note that the characters in these literals, together with the entire SQL statement, are converted from the client character set to the database character set when transmitted to the server.需要注意的是,这些文字中的字符连同整个 SQL 语句在传输到服务器时从客户端字符集转换为数据库字符集。 All characters from the literals that are not supported by the database character set are lost.数据库字符集不支持的文字中的所有字符都将丢失。

The data type of the undocumented U'' literals is also NVARCHAR2.未记录的U''文字的数据类型也是 NVARCHAR2。 The content of a U'' literal is interpreted like the input to the SQL UNISTR function. That is, each character sequence \xxxx , where each x is one hex digit, is interpreted as a UTF-16 code point U+xxxx. U''文字的内容被解释为 SQL UNISTR function 的输入。也就是说,每个字符序列\xxxx (其中每个x是一个十六进制数字)被解释为 UTF-16 代码点 U+xxxx。 I am not sure why the U'' literals are undocumented.我不确定为什么U''文字没有记录。 I can only guess.我只能猜测。 They are used internally by the NCHAR literal replacement feature, which, when enable on a client, automatically translates N'' literals to U'' literals.它们由 NCHAR 文字替换功能在内部使用,当在客户端上启用时,该功能会自动将N''文字转换为U''文字。 This prevents the mentioned data loss due to character set conversion and enables literal Unicode data to be provided for NVARCHAR2 columns even if the database character set is not Unicode.这可以防止上述由于字符集转换而导致的数据丢失,并允许为 NVARCHAR2 列提供文字 Unicode 数据,即使数据库字符集不是 Unicode 也是如此。

The two queries in this thread's question are generally not equivalent because the literal text would be interpreted differently.该线程问题中的两个查询通常等同,因为文字文本会被不同地解释。 However, if no backslash is present in the literals, no difference can be observed.但是,如果文字中不存在反斜杠,则不会观察到任何差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM