↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3
历史版本。 PostgreSQL 9.0 已结束支持。 2015-10-08. 请参阅 当前版本手册.

F.16. isn #

isn 模块为以下国际产品编号标准提供数据类型:EAN13、UPC、ISBN(图书)、ISMN(音乐)和 ISSN(连续出版物)。输入时会验证这些编号,输出时会正确地加上连字符。

F.16.1. 数据类型

表 F.10显示了 isn 模块提供的数据类型。

表 F.10. isn 数据类型

数据类型描述
EAN13 European Article Numbers, always displayed in the EAN13 display format
ISBN13 以新的 EAN13 显示格式显示的国际标准图书编号
ISMN13 以新的 EAN13 显示格式显示的国际标准音乐编号
ISSN13 以新的 EAN13 显示格式显示的国际标准连续出版物编号
ISBN 以旧的短显示格式显示的国际标准图书编号
ISMN 以旧的短显示格式显示的国际标准音乐编号
ISSN 以旧的短显示格式显示的国际标准连续出版物编号
UPC 通用产品代码

几点说明:

  1. ISBN13、ISMN13 和 ISSN13 编号都是 EAN13 编号。

  2. EAN13 编号并不总是 ISBN13、ISMN13 或 ISSN13(不过其中有些确实是)。

  3. 某些 ISBN13 编号可以显示为 ISBN。

  4. 某些 ISMN13 编号可以显示为 ISMN。

  5. 某些 ISSN13 编号可以显示为 ISSN。

  6. UPC 编号是 EAN13 编号的一个子集(它们基本上就是去掉首位 0 数字的 EAN13 编号)。

  7. 所有 UPC、ISBN、ISMN 和 ISSN 编号都可以表示为 EAN13 编号。

在内部,所有这些类型都使用同一种表示形式(一个 64 位整数),并且彼此可以互换。之所以提供多种类型,是为了控制显示格式,并对原本应表示某一特定类型编号的输入执行更严格的有效性检查。

只要可能,ISBN、ISMN 和 ISSN 类型都会显示编号的短版本(ISxN 10);对于不能用短版本表示的编号,则显示为 ISxN 13 格式。EAN13、ISBN13、ISMN13 和 ISSN13 类型则始终显示 ISxN 的长版本(EAN13)。

F.16.2. 类型转换

isn 模块提供以下几对类型转换:

  • ISBN13 <=> EAN13

  • ISMN13 <=> EAN13

  • ISSN13 <=> EAN13

  • ISBN <=> EAN13

  • ISMN <=> EAN13

  • ISSN <=> EAN13

  • UPC <=> EAN13

  • ISBN <=> ISBN13

  • ISMN <=> ISMN13

  • ISSN <=> ISSN13

当从 EAN13 转换到其他类型时,会在运行时检查该值是否落在另一类型的取值范围内;如果不在,就会抛出错误。其他类型转换都只是简单地重新标记,因此总会成功。

F.16.3. 函数和操作符

isn 模块提供标准比较操作符,以及对所有这些数据类型的 B-tree 和哈希索引支持。此外,它还提供了一些专用函数,如表 F.11所示。在该表中,isn 表示该模块提供的任意一种数据类型。

表 F.11. isn 函数

函数返回值描述
isn_weak(boolean)boolean设置弱输入模式(返回新的设置值)
isn_weak()boolean获取弱模式的当前状态
make_valid(isn)isn使无效编号变为有效(清除无效标记)
is_valid(isn)boolean检查是否存在无效标记

弱模式用于允许向表中插入无效数据。这里的无效指的是校验位错误,而不是缺少数字。

为什么会需要使用弱模式呢?例如,手头可能有一大批 ISBN 编号,数量多到难免会有一些编号因为某些奇怪的原因而带有错误的校验位(也许这些编号是从印刷清单扫描得到的,而 OCR 把数字识别错了;也许这些编号是人工录入的……谁知道呢)。总之,可能想把这些混乱情况清理干净,但同时仍希望先把所有编号都装入数据库,并借助外部工具在数据库中定位无效编号,以便核对信息并更容易完成校验;例如,可能会想把表中所有无效编号都查询出来。

当在弱模式下向表中插入无效编号时,实际插入的是校验位已更正的编号,但显示时会在末尾附加一个感叹号(!),例如 0-11-000322-5!。可以用 is_valid 函数检查这个无效标记,并用 make_valid 函数清除它。

即使未启用弱模式,也可以通过在编号末尾附加 ! 字符来强制插入无效编号。

另一个特殊功能是,在输入时可以用 ? 代替校验位,系统会自动插入正确的校验位。

F.16.4. 示例

--Using the types directly:
SELECT isbn('978-0-393-04002-9');
SELECT isbn13('0901690546');
SELECT issn('1436-4522');

--Casting types:
-- note that you can only cast from ean13 to another type when the
-- number would be valid in the realm of the target type;
-- thus, the following will NOT work: select isbn(ean13('0220356483481'));
-- but these will:
SELECT upc(ean13('0220356483481'));
SELECT ean13(upc('220356483481'));

--Create a table with a single column to hold ISBN numbers:
CREATE TABLE test (id isbn);
INSERT INTO test VALUES('9780393040029');

--Automatically calculate check digits (observe the '?'):
INSERT INTO test VALUES('220500896?');
INSERT INTO test VALUES('978055215372?');

SELECT issn('3251231?');
SELECT ismn('979047213542?');

--Using the weak mode:
SELECT isn_weak(true);
INSERT INTO test VALUES('978-0-11-000533-4');
INSERT INTO test VALUES('9780141219307');
INSERT INTO test VALUES('2-205-00876-X');
SELECT isn_weak(false);

SELECT id FROM test WHERE NOT is_valid(id);
UPDATE test SET id = make_valid(id) WHERE id = '2-205-00876-X!';

SELECT * FROM test;

SELECT isbn13(id) FROM test;

F.16.5. 参考文献

实现该模块所需的信息收集自若干网站,包括:

用于进行连字符分隔的前缀还整理自:

在创建这些算法时已十分谨慎,并依据官方 ISBN、ISMN、ISSN 用户手册中建议的算法进行了细致核验。

F.16.6. 作者

Germán Méndez Bravo (Kronuz), 2004 - 2006

该模块受到了 Garrett A. Wollman 的 isbn_issn 代码的启发。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.