选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.3 已于 2018 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

F.19. isn #

isn模块为以下国际产品编号标准提供数据类型:EAN13、UPC、ISBN(图书)、ISMN(音乐)和 ISSN(连续出版物)。输入这些编号时,会依据一份硬编码的前缀列表进行校验;输出时,这份前缀列表也会用于给编号加上连字符。由于新的前缀会不时被分配,这份前缀列表可能已经过时。希望该模块未来版本能从一个或多个表中获取前缀列表,以便用户按需更新;但目前,这份列表只能通过修改源代码并重新编译来更新。或者,该模块未来版本也可能取消前缀校验和连字符支持。

F.19.1. 数据类型

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

表 F.12. isn 数据类型

数据类型 描述
EAN13 欧洲商品编号,始终以 EAN13 显示格式显示
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 位整数),并且彼此可以互换。之所以提供多种类型,是为了控制显示格式,并对原本应表示某一特定类型编号的输入执行更严格的有效性检查。

只要可能,ISBNISMNISSN 类型都会显示编号的短版本(ISxN 10);对于不能用短版本表示的编号,则显示为 ISxN 13 格式。EAN13ISBN13ISMN13ISSN13 类型则始终显示 ISxN 的长版本(EAN13)。

F.19.2. 类型转换

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

  • ISBN13 <=> EAN13

  • ISMN13 <=> EAN13

  • ISSN13 <=> EAN13

  • ISBN <=> EAN13

  • ISMN <=> EAN13

  • ISSN <=> EAN13

  • UPC <=> EAN13

  • ISBN <=> ISBN13

  • ISMN <=> ISMN13

  • ISSN <=> ISSN13

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

F.19.3. 函数和操作符

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

表 F.13. 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.19.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.19.5. 参考文献

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

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

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

F.19.6. 作者

Germ[aacute]n M[eacute]ndez Bravo (Kronuz), 2004 - 2006

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

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。