Использование и преобразование типов данных SQL к типам языка программирования С/С++


 Вернуться в Доки-Токи

 

Автор: Andrey Rjavskov(Rzhavskov) as rjaan <rjaan@yandex.ru>


1. Введение

Мало написать базу данных и спроектировать её с учётом форм нормализаций, но так же необходимо обеспечить правильное преобразование данных из SQL к тому языку программирования на котором будет написан клиент СУБД PostgreSQL. В этой статье пойдет речь как преобразовывать типы данных СУБД PostgreSQL, далее по тексту SQL, к основным типам языка C/C++. А именно пойдет речь как преобразовывать основные типы данных SQL , к которым относятся целочисленные, бинарные, символьные(текстовые) и серийные типы. Так же здесь расскажу о том, как избегать использование монетарного типа, который был не так давно запрещён для использования. Типы времени достойны отдельного разговора, поэтому им будет посвящена отдельная статья.

Ниже в таблице представлены основные типы SQL c учетом их преобразования к основным языка программирования С для архитектуры процессора x86, которая имеется в виду в этой статье.

SQL-типС типРазмер в байтахДиапазон допустимых значений
smallintshort int2-32768 to +32767
integerlong int4-2147483648 to +2147483647
bigintlong long int8-9223372036854775808 to 9223372036854775807
bigintlong long int8-9223372036854775808 to 9223372036854775807
decimalнелимит. -10^38 + 1 -:- 10^38 - 1
numericнелимит. -10^38 + 1 -:- 10^38 - 1
realfloat4с точностью до 6 знака после запятой
double precisiondouble8с точностью до 15 знака после запятой
seriallong int4с 1 по 2147483647
bigseriallong long int8c 1 по 9223372036854775807
Serial(integer)long int4-2147483648 to +2147483647

2. Целочисленные типы

Эти типы представляют целые числа, которые не имеют фрактальную часть, но их допустимые значения будут находится в различных диапазонах этих значений. Попытка выхода за пределы такого диапазона будет сопровождаться ошибкой. К целочисленным типам относятся smallint,integer, bigint.

В документация к PostgreSQL сказано, что тип smallint рекомендуется использовать, когда нужно рационально использовать дисковое пространство, но надо помнить, что у этого диапазона слишком маленький размах в значениях(см. пред. табл.).

Тип integer обычно используется для представления целочисленных значений, а вот тип bigint следует использовать только тогда, когда есть в этом необходимость. Потому что тип integer намного быстрее.

Теперь, что касается экономии дискового пространства за счет использования типа smallint тут вопрос спорный и требует отдельного рассмотрения.

Давайте проиллюстрируем применение целочисленных типов с использованием API-функций библиотеки libpq, которая предоставляет собой C-клиент для PostgreSQL для использования в программах, написанных на C/C++.

Но сначала, разработчику в ОС Debian GNU/Linux нужно установить следующие пакеты:

  • libpq5, клиентская библиотека PostgreSQL, реализован на С, но так же может использоваться в программах написанных на C++;
  • libpq-dev, содержит заголовочные файлы для libpq5.

Сразу хочу сказать, что реализация API-функций на С, не запрещает их использовать при программировании на языка С++. Поэтому, примеры того как использовать libpq привожу на С, а вы в свою очередь, эти же примеры с успехом можете применять у себя в программах, написанных на C++.

Ещё несколько слов о используемой здесь аутентификации, которая предусматривается демоном PostgreSQL. Для авторизированного доступа пользователей к базам данных мной используется связывание пользователей ОС и ролей SQL, имеющие право создавать соединения с сервисом SQL. Как сделать такое связывание рекомендую почитать статью ОС Debian GNU/Linux: Разграничение прав доступа пользователей в СУБД PostgreSQL. Поэтому не удивляетесь, что при соединении с SQL-сервером автор не указывает имена ролей(пользователей) и их пароли.

Теперь через psql(1) создаем базу данных test_db, с которой и будем далее тестировать наши типы SQL c типами C.

root@engine:~# psql -U postgres -c 'CREATE DATABASE test_db;'
CREATE DATABASE

Далее, пишем клиент, который добавляет записи в таблицу substances:

test_db=# CREATE TABLE substances(
test_db(# kind SMALLINT NOT NULL,
test_db(# class INTEGER NOT NULL,
test_db(# id BIGINT UNIQUE
test_db(# );
NOTICE: CREATE TABLE / UNIQUE создаст подразумеваемый индекс "substances_id_key" для таблицы "substances"
CREATE TABLE

SQL-таблица substances состоит из атрибутов, т.е. из столбцов, имеющие только целочисленные типы и хранит по-мимо идентификатора сущности(id), еще класс(class) и вид(kind). Мало того, контрольное ограничение UNIQUE атрибута id, снимает необходимость вручную создавать индексы, которые нужны будут во-время операций выброк с 1000000 сущностей, которые будем делать с помощью SQL-запроса SELECT через psql(1).А добавлять эти сущности будем с помощью теста test-substance. Наклонять типы в сторону переполнения целого будем позже, а сейчас просто протестистируем каждый на своем PC, сколько займет времени, чтобы записать 1000000 записей в таблицу substances.

Запускаем тест test-substance, который добавляет 1000000 сущностей в SQL-таблицу substances. После выполнения теста, делаем выборку через SELECT для последних десяти сущностей из 1000000 добавленных. Время выполнения теста test-substance достаточно велико, что свидетельствуют цифры дампа test-substance.

Файлы исходного кода и данных test-substance

Makefile
test-config.h
test-common.h
test-common.c
test-substance.c

Дамп выполнения test-substance

my_user@engine:~/tests_pqlib$ ./test-substance begin test-substance.done in 01 min 32.091 sec

Дамп psql(1). Выполнение SELECT(выборка последних 10 записей из SQL-таблицы substance)

test_db=# SELECT * FROM substances ORDER BY id DESC LIMIT 10;
kind   |    class   | id
-------+------------+--------
23830  |   46420486 | 999999
32510  |  136535666 | 999998
3247   |   76511857 | 999997
9813   | 1599514869 | 999996
23886  | 1399426980 | 999995
18155  |  951378965 | 999994
8779   | 1069523785 | 999993
8293   |  491629357 | 999992
14762  |  162075398 | 999991
12012  |   30975882 | 999990
(10 rows)

Во время тестирования добавления 1000000 записей в таблицу substances, у меня родилась идея наклонить SQL-тип smallint в сторону переполнения целого(Integer Underflow). Для чего написал тест, который добавляет в таблицу substances записи со значениеми атрибута kind, удовлетворяющие условию переполнения целого(Integer Underflow). В id будут записываться итерации выполнения теста. По ним мы сможем судить на какой итерации произошло это переполнение.

Как мы можем увидеть из дампа ниже, SQL-тип smallint соответствует С-типу signed short int, а С-тип usigned short int не может быть использован, т.к. неизбежно приведет к переполнению целого. Поэтому С-тип usigned short лучше не использовать, чтобы не обременять себя лишними проверками. Так же по аналогии с SQL-типом smallint, с SQL-типами integer и bigint не стоит использовать C-типы unsigned long int и соответственно unsigned long long int.

Файлы исходного кода и данных test- substance

Makefile
test-config.h
test-common.h
test-common.c
test-overtype.c

Дамп psql(1). Выполнение test-substance

my_user@engine:~/testdb/tests_pqlib$ ./test-overtype
begin test-overtype
test at Integer Underflow for unsigned short int!
10 step: test 32762 value
9 step: test 32763 value
8 step: test 32764 value
7 step: test 32765 value
6 step: test 32766 value
5 step: test 32767 value
4 step: test 32768 value
to cause Integer Underflow(for short)!
PQexecParams(): ERROR: smallint вне диапазона
test at Integer Underflow for short int!
110 step: test 65530 value
PQexecParams(): ERROR: smallint вне диапазона
done in 000 min 0.190 sec

Дамп psql(1). Выполнение SELECT(все записи таблицы substance)

test_db=# SELECT * FROM substances;
   kind | class | id
--------+-------+----
  32762 |   0   | 10
  32763 |   0   | 9
  32764 |   0   | 8
  32765 |   0   | 7
  32766 |   0   | 6
  32767 |   0   | 5
(6 rows)

3. Типы с произвольным количеством разрядов

К таким SQL-типам относятся decimal и numеric. SQL-тип numеric позволяет масштабировать значения десятичных чисел до 1^1000 и производить c ними точные вычисления. Этот тип является полностью эквивалентным к decimal.

Тип numеric рекомендуется использовать для хранения денежно-финансовых сумм, где требуется точность вычислений с ними. Этот тип должен применяться взамен монетарного типа.

Декларация типа numеric состоит из двух частей: дробной части и целой. Дробная часть определяет количество разрядов после запятой в правой части. Целая часть определяет количество разрядов(имеется в виду в десятичном исчислении) до запятой в левой части числа. Принято следующее представление SQL-типа:

NUMERIC(precision, scale)

где precision — задает масштаб целой части. Масштаб применяется для ограничения ее размерности. Значение precision должно быть в диапазоне 1 от 1000. Значение precision равное 1,2 запрещают использование целой части, потому что значение атрибута типа numeric должено быть меньше единицы. Соответственно, значение precision равное 3 устанавливает лимит значений атрибута типа numeric меньше 10, 4 — меньше 100, 5 — меньше 1000 и т.д.

scale задет количество разрядов в правой части, т.е. задает количество знаков после запятой. Так scale равное 2 установит соответственно два знака после запятой, поэтому число 0.239 будет округлено по правилам математического округления до 0.24 и записано в таблицу.

Дамп psql(1). Выполнение INSERT(вставка записи в таблицу price_list)

test_db=# INSERT INTO price_list(product,price) VALUES('Какой-то продукт', 0.239);
INSERT 0 1
test_db=# SELECT * from price_list WHERE product='Какой-то продукт';
  product         | price
------------------+-------
Какой-то продукт  | 0.24
(1 запись)

Рассмотрим следующий пример. Создадим таблицу price_list с двумя атрибутами текстовым product и числовым price. Соответственно, назначим атрибуту price тип TEXT, а атрибуту product тип NUMERIC(10,2), что нам позволит существенно сэкономить память, которая будет выделяться для каждой записи. Таким образом, мы устанавливаем максимальное число 9 999 999 999 для значения атрибута NUMERIC, что будет вряд ли превышено в средних компаниях чьи финансовые операции вряд перевалят за 1 трлн. рублей за одну операцию, что не во всех финансовых институтах и организациях это мы сможем наблюдать. В то же время, например для розничной торговли можно использовать ограничение в 1 млрд. рублей.

Дамп psql(1). Cоздание SQL-таблицы price_list

test_db=# CREATE TABLE price_list ( product text, price numeric ( 10, 2 ) );

Теперь напишем небольшой тест test-numeric, который будет вносить записи в таблицу price_list . А именно цены на овощи:
Наименование продукцииЦена
Champignon3,10$
Garlic2,60$
Zucchini2,00$
Fennel1,80$
Tomato2,58$
Apium3,00$
Salad3,00$
Beet root0,15$
Radish0,95$
Garden radish2,05$
Punch6,00$
Brazilian Pepper Tree7,12$
Red pepper7,00$
Capsicum annuum6,50$
Cucumber2,30$
Daucus carota1,10$
Wild carrot0,91$
Allium porrum2,45$
Allium6,00$
Red onion1,00$
Cilantro10,10$
Celeriac1,76$
Potatoes0,60$
Cauliflower2,10$
Borecole boot1,46$
White cabbage1,00$
Chinese cabbage2,61$
Squash3,50$

Исходный код программы test-numeric

Makefile
test-config.h
test-common.h
test-common.c
test-numeric.c

Дамп выполнения test-numeric

my_user@engine:~/Work/learned_database/testdb/tests_pqlib$ ./test-numeric begin test-numeric done in 000 min 0.475 sec

Дамп psql(1). Выполнение SELECT(выборка всех записей из таблицы price_list)

test_db=# SELECT product, to_char(price,'9999999990D99"р."') AS price FROM price_list; SELECT product, to_char(price,'9999999990D99"р."') FROM price_list;
product                | price
-----------------------+-----------------
Champignon             | 3,10$
Garlic                 | 2,60$
Zucchini               | 2,00$
Fennel                 | 1,80$
Tomato                 | 2,58$
Apium                  | 3,00$
Salad                  | 3,00$
Beet root              | 0,15$
Radish                 | 0,95$
Garden radish          | 2,05$
Punch                  | 6,00$
Brazilian Pepper Tree  | 7,12$
Red pepper             | 7,00$
Capsicum annuum        | 6,50$
Cucumber               | 2,30$
Daucus carota          | 1,10$
Wild carrot            | 0,91$
Allium porrum          | 2,45$
Allium                 | 6,00$
Red onion              | 1,00$
Cilantro               | 10,10$
Celeriac               | 1,76$
Potatoes               | 0,60$
Cauliflower            | 2,10$
Borecole boot          | 1,46$
White cabbage          | 1,00$
Chinese cabbage        | 2,61$
Squash                 | 3,50$
(28 rows)

4. Типы чисел с плавающей точкой

Типы real и double относятся к неточным числовым типам. Под неточностью тут понимается то, что некоторые значения не могут быть непосредственно конвертированы к внутреннему формату и сохраняются приближено. Поэтому в результате сохранения и перевода этих значений этого типа могут иметь некоторые отличные значения.

Если есть необходимость в соблюдении точности вычислений, например в денежно-финансовых суммах, рекомендуется использовать NUMERIC. В то же время, если Вы хотите использовать типы с плавающей точкой в каких-либо важных вычислениях, особенно, где возможно возникновение пограничных случаев( бесконечности и переполнения), Вам необходимо использовать их очень осторожно. Ещё нужно помнить, что сравнение двух чисел с плавающей точкой может приводить к их эквивалентности или не приводить.

При использовании на сборках ядра для 32-х разрядной архитектуре x86, точность составляет диапазон значений 1E-37 – 1E+37 для одиночной точности с количеством знаков после запятой не менее 6-ти и диапазона значений 1E-307 – E+308 для двойной точности с кол-вом знаков не менее 15-ти после запятой.

5. Серийные типы

Эти типы позволяют индексировать записи по уникальным числовым значениям в таблицах вместо использования специальных последовательностей, как показано ниже в примере.

Следующая запись:

CREATE TABLE tablename (
       colname SERIAL
     );

будет эквивалентна:

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
       colname integer DEFAULT nextval('tablename_colname_seq') NOT NULL
     );

В этой таблице создаётся целочисленный столбец, который по-умолчанию увеличивает на одно значение каждую запись, используя для этого генератор последовательности. В следующем примере мы увидим, что после создания таблицы tablename вместе с ней была создана последовательность.

Дамп psql(1). Выполнение CREATE TABLE(создание sql-таблицы tablename)

postgres=# CREATE TABLE tablename (
postgres(# colname SERIAL
postgres(# );
postgres=# \d
public | tablename | таблица | postgres
public | tablename_colname_seq | последовательность | postgres
postgres=# \d+ tablename
colname | integer | not null default nextval('tablename_colname_seq'::regclass) |

Как видно из дампа psql(1), после того как мы создали таблицу tablename с единственным атрибутом colname, по-мимо таблицы ещё была создана последовательность tablename_colname_seq. Поэтому утверждать, что данный тип позволяет избежать использование последовательностей не совсем верно.

Если мы взглянем на таблицу tablename более внимательнее то увидим, что кроме контрольного ограничения NOT NULL ещё используется DEFAULT, который с помощью встроенной функции nextval() вызывает последовательность, в результате обращения к которой возвращается следующее значение colname и которое будет затем, записано в только что созданную запись(new) таблицы.

Чтобы пощупать это на практике предлагаю добавить в таблицу tablename текстовый столбец dsc и затем добавить в неё несколько записей, а потом посмотреть её содержимое через SELECT.

Дамп psql(1). Выполнение INSERT(вставка записей в таблицу tablename)

postgres=# INSERT INTO tablename(dsc) VALUES('one');
postgres=# INSERT INTO tablename(dsc) VALUES('two');
postgres=# INSERT INTO tablename(dsc) VALUES('three');
postgres=# SELECT * FROM tablename;
colname | dsc
--------+-----------
  1     | one
  2     | two
  3     | three

При использовании типа SERIAL в атрибуте colname автоматически создается ограничение NOT NULL, которое вводит запрет на ввод нулевых значений. Но, так как вам скорее всего захочется использовать ограничение UNIQUE или PRIMARY KEY, чтобы исключить вероятность появления дублирующих значений, то вам нужно будет устанавливать эти контрольные ограничения самим, так как они не создаются автоматически. Ниже показано как добавлять в таблицу контрольное ограничение для исключения дублирующих значений атрибута colname в записях таблицы tablename.

Дамп psql(1). Выполнение ALTER TABLE(добавление контрольных ограничений)

postgres=# ALTER TABLE tablename ADD CONSTRAINT colname_id_key UNIQUE(colname);
NOTICE: ALTER TABLE / ADD UNIQUE создаст подразумеваемый индекс "colname_id_key" для таблицы "tablename"
ALTER TABLE

6. Символьные типы

SQL определяет два основных типа character varying(n) и character(n), где n принимает только положительные значения. Эти типы предназначены для хранения строк длинной в n-символов . При попытке сохранить в ячейки строку больше чем n-символов приведет к ошибке или в некоторых случаях просто она будет обрезана по максимальной длине ячейки, указанной при определении типа. При помещении строки меньше чем n, все остальные ячейки будут заполонены пробелами автоматически.

SQL-типС типРазмер в байтах
varchar(n)char[n]n
char(n)char[n]n
varying characterchar[1...∞]1...∞
textchar[1...∞]1...∞

Так же нужно помнить, что varchar(n) и char(n) являются псевдонимами SQL-типа character varying(n) и, соответственно, character(n) . SQL-тип character без объявление его длинны будет эквивалентен character(1) . Для указание длинны размера строки так же используется character varying.

СУБД PostgreSQL имеет тип text, который позволяет хранить строки любой длинны. Будьте осторожны при использовании SQL-типа text, т.к. он не включен в стандрат SQL, и соответсвенно может не поддерживаться другими СУБД.

Ниже приводится примеры использования символьных типов. Создаем таблицу test_chars с единственным атрибутом colchars и добавляем запись из четырех символов. После чего проверяем через SELECT, что запись добавлена в таблицу вместе с выводом длинны записанных символьных данных с помощью символьную SQL-функции char_length.

Дамп psql(1). Примеры использования символьных типов

postgres=# CREATE TABLE test_characters (colchars character(4));
postgres=# INSERT INTO test_characters VALUES ('ok');
INSERT 0 1
postgres=# SELECT colchars, char_length(colchars) FROM test1;
colchars   | char_length
-----------+-------------
ok   1     | 2
(1 запись)

Ниже мы записываем ещё несколько записей разной длины до тех пор пока не сталкнемся с ошибкой. Она выделена жирным курсивом, и следующим за ней предупреждение при выполнении INSERT, что произошло неявное обрезание до 5 символов. Но, мы так же видим, что ошибка не была обнаружена при записи good с некоторым количеством пробелов, которая превышает размер в 5-ть символов.

Дамп psql(1). Примеры использования символьных типов. Исключительные ситуации

postgres=#CREATE TABLE test2 (b varchar(5));
postgres=#INSERT INTO test2 VALUES ('ok');
postgres=#INSERT INTO test2 VALUES ('good ');
postgres=#INSERT INTO test2 VALUES ('too long');
ERROR: value too long for type character varying(5)
postgres=#INSERT INTO test2 VALUES ('too long'::varchar(5)); -- explicit truncation
postgres=#SELECT b, char_length(b) FROM test2;
  b     | char_length
--------+-------------
  ok    |    2
  good  |    5
  too l |    5

После выполнения проверочного SELECT мы выясняем, что too long был оберзан доtoo l, до длинны, которая составляет 5-ть символов.

Тип bytea позволяет хранить бинарные строки, являющейся последовательностью чисел в восьмеричной системе отсчета.

Отличие данного типа от символьных, состоит в том, что он хранит числа в восьмеричной системе отсчёта отличных от нуля и диапазона «не печатаемых» символов, кроме чисел находящихся вне диапазона значений от 32 до 127. Так же не зависит от того, сколько байт требуется для поддержки локали.

При вводе чисел в восьмеричной системе, их необходимо экранировать, когда они используются как часть SQL-выражения. В общем, нужно конвертировать десятичное значение в трех-значащее число и присоединить его к двум обратным слэшам, которые должны быть вначале. В следующей таблице отображены символы, которые должны быть экранированы. В табл. 3, даны примеры того как экранируются числа в восьмеричной системе исчисления.

Число в Десятичном исчисленииОписаниеЭкранированиеВвод числаВывод числа
0Ноль'\\000'SELECT '\\000'::bytea;\000
39Одинарная ковычка'\'' или '\\047'SELECT '\\047'::bytea;'
92Обратная косая черта'\\\\' или '\\134'SELECT '\\134'::bytea;\\
с 0 по 31 и с 127 по 255Не-печатываемые символы**'\\xxx'SELECT '\\001'::bytea;\001
c 32 to 126печатываемые символыОтображение клиентского набора символовSELECT E'\\176'::bytea; 
Примечание. ** - к перепечатываемым символам относятся служебные символы ESC-последовательности.

Как мне удалось вычитать из документации RedHat к базам данных, этот тип рекомендуется использовать для хранения данных больших размеров. Столбец с типом bytea может содержать свыше 1 гигабайт бинарных данных, которые содержаться в таблицы и отправляются к клиентским программам по запросам. Для обработки таких запросов клиент должен иметь большое количество оперативной памяти для работы с этими данными.

Дамп psql(1). Выполнение CREATE TABLE(создание таблицы images)

postgres=# CREATE TABLE images( dsc TEXT,img BYTEA );
CREATE TABLE

Теперь остается написать нам небольшой тест test-bytea чей код будет написан на С, который будет добавлять тестовое изображение в SQL-таблицу images через API библиотеки libpq-5.0, которая входит в состав дистрибутива Debian GNU/Linux.

Она будет делать:

  1. Читать поток в бинарном виде из файла, представлять в восьмеричный вид с экранированием каждого байта как следует из условия представления значений в типе bytea, что будем делать через функцию PqescapeBytea().
  2. Добавляем название файла и его размер через запятую в поле dsc SQL-таблицы images, а представленный к восьмиричному и экранированному виду поток бинарного файла в поле этой же таблицы images.

Файлы исходного кода и данных test-bytea

Makefile
test-config.h
bytea-common.h
bytea-common.c
test-bytea.c
tux.png

Дамп выполнения test-bytea

begin test-bytea
File 'tux.png' added!
done in 000 min 0.097 sec

Дамп psql(1). Выполнение SELECT(Выборка всех записей из таблицы images)

test_db=# SELECT * FROM images; dsc|img
tux.png, 37 Kbytes | \\211PNG\\015\\012\\032\\012\\000\\000\\000\\015IHDR\\000\\000\\000\\200
\\000\\000\\000\\200\\010\\002\\000\\000\\000L\\\\\\366\\234\\000\\000\\000\\001s
RGB\\000\\256\\316\\034\\351\\000\\000\\000\\006bKGD\\000\\377
\\000\\377\\000\\377\\240\\275\\2 ...

Некоторые замечания к test-bytea

В процессе написания теста test-bytea выяснилось, что SQL-тип bytea не такой простой как кажется на первый взгляд.

Во-первых, с ним нельзя использовать PQexec(), которая заставляет оперировать с текстовыми массивами фиксированной длинны. Поэтому автор выбрал для выполнения SQL-выражения, добавляющий массив типа bytea API-функцию PQexecParams(), которая позволяет передавать текстовые массивы переменной длинны.

Во-вторых, для добавление в PostgreSQL данных с типом bytea мне пришлось изменить параметр client_encoding() в файле postgresql.conf, который устанавливает кодировку, используемую по-умолчанию SQL_ASCII. Но это не очень хороший подход , поэтому лучше для этого использовать в SQL-запросе INSERT INTO images ( dsc, img ) VALUES ( $1::text, $2::bytea ); функцию convert_to( $2, 'SQL_ASCII')::bytea со значением в втором параметре SQL_ASCII', задающую кодировку ASCII. Иначе, если используется UTF-8 или какая-нибудь другая кодировка выполнение SQL-команды INSERT может завершится сбоем из-за неправильной интерпретации символов. Тогда SQL-выражение примет вид: INSERT INTO images(dsc,img) VALUES($1::text,convert_to($2,'SQL_ASCII')::bytea);", 2, NULL, q, NULL, NULL, 0 );.

9. Булевский Тип

СУБД PostgreSQL обеспечивает поддержку стандартом SQL тип boolean. Этот тип может иметь только два состояние: "true" или "false". Третье состояние "unknown" представлено в SQL нулевым значением.

Размерность этого типа 1 байт. Для его хранение в С рекомендуется использовать тип char. Значение "true" может принимать следующие значения:

TRUE
't'
'true'
'y'
'yes'
'1'

Значение "false" может принимать следующие значения:

FALSE
'f'
'false'
'n'
'no'
'0'

Использование TRUE и FALSE является предпочтительным в SQL-выражении. Следующий пример иллюстрирует использование этого типа.

Дамп psql(1). Пример использование булевского типа

CREATE TABLE test1 (a boolean, b text);
INSERT INTO test1 VALUES (TRUE, 'sic est');
INSERT INTO test1 VALUES (FALSE, 'non est');
SELECT * FROM test1;
a  | b
---+---------
t  | sic est
f  | non est

SELECT * FROM test1 WHERE a;
a  | b
---+---------
t  | sic est

 

Вернуться в Доки-Токи


Copyright © 2010 rjaan as Andrey Rjavskov(Rzhavskov) <rjaan@yandex.ru> <arjavskov@gmail.com>



Сайт создан в системе uCoz