-1
SELECT LAST_NAME FROM Employees
WHERE last_name < 'King';

在“SQL Fundamentals I Exam Guide”一书中,它说在比较LAST_NAME < 'King'中发生了 NLS 设置中的以下转换,假设使用 AMERICAN NLS 设置的 US7ASCII 数据库字符集:

K + i + n + g = 75 + 105 + 110 + 103 = 393.

然后对于表 EMPLOYEES 表中的每一行,LAST_NAME 列类似地转换为数值。如果该值小于 393,则选择该行。但是当我在 SQL*PLUS 上执行上面的 SELECT 命令时,它返回的行(例如'Greenberg'、'Bernestein')不符合书中提到的规则。是否需要进行任何设置才能获得满足该规则的行?

在此处输入图像描述

4

2 回答 2

4

如果这确实是这本书所说的,那么这本书是非常不正确的,而且非常可怕。如果我们谈论的是 Oracle Press 的书,我强烈怀疑你误解了解释,因为我很难想象这个错误是如何在不被作者、编辑或审稿人发现的情况下完成的.

要比较两个字符串,您所做的操作与手动按字母顺序排列字符串时所做的完全相同。字符串“B”出现在字符串“All My Data”之后,字符串“Changes Constantly”之前。您获取字符串的第一个字符并查看十进制表示('A' 是 65,'B' 是 66,'C' 是 67)并根据它进行排序。如果存在平局,例如“所有数据”和“所有索引”,则继续到第二个字符并进行比较,直到您可以打破平局 'D' 是 68 小于 'I' 是 73 所以“所有数据" < "所有索引"。

于 2015-12-17T23:59:56.437 回答
4

这个规则肯定是无效的。如果是,那么你可以交换字符,你仍然会得到相同的结果393。但是在比较单词时,字符顺序很重要。

要获得适合比较的值,您必须像这样计算:

K + i + n + g = ((75 × 256 + 105) × 256 + 110) × 256 + 103

但是您会超出长字的有效数值范围。对于 7 位 ASCII 代码(严格在 0 ... 127 范围内),您还可以乘以 128 而不是 256。

--

实际上,这些值是一一比较的,即(在伪代码中):

valueOf(last_name[0]) < 75 OR
valueOf(last_name[1]) < 105 OR
valueOf(last_name[2]) < 110 OR
valueOf(last_name[3]) < 103

...如果比较在遇到的第一个不等式处停止,或者如果到达一个单词的结尾,则比较单词的长度。

也就是说,2个单词的字符逐个字符进行比较,直到遇到两个不同的字符。然后比较这两个字符产生最终结果。

'Kelvin' < 'King'个例子:

'K' < 'K' ==> false
'e' < 'i' ==> true
final result = true

其他示例'King' < 'Kelvin' (单词交换):

'K' < 'K' ==> false
'i' < 'e' ==> false, the characters are not equal, therefore stop
final result = false

其他例子'be' < 'begin'

'b' < 'b' ==> false
'e' < 'e' ==> false
end of first word reached, length('be') < length('begin') ==> true
final result = true

正如您已经提到的,两个字符的实际比较是通过比较它们的数值来执行的。

于 2015-12-18T00:10:15.567 回答