Postgresql 简明教程

PostgreSQL - Quick Guide

PostgreSQL - Overview

PostgreSQL 是一个功能强大的开源对象关系数据库系统。它拥有超过 15 年的积极开发阶段,并拥有经过验证的架构,使其享有很高的可靠性、数据完整性和正确性声誉。

PostgreSQL is a powerful, open source object-relational database system. It has more than 15 years of active development phase and a proven architecture that has earned it a strong reputation for reliability, data integrity, and correctness.

本教程将帮助你快速上手 PostgreSQL,让你熟悉 PostgreSQL 编程。

This tutorial will give you a quick start with PostgreSQL and make you comfortable with PostgreSQL programming.

What is PostgreSQL?

PostgreSQL(发音为 post-gress-Q-L )是一个由全球志愿者团队开发的开源关系型数据库管理系统(DBMS)。PostgreSQL 不受任何公司或其他私有实体控制,并且源代码可以免费获取。

PostgreSQL (pronounced as post-gress-Q-L) is an open source relational database management system (DBMS) developed by a worldwide team of volunteers. PostgreSQL is not controlled by any corporation or other private entity and the source code is available free of charge.

A Brief History of PostgreSQL

PostgreSQL 最初称为 Postgres,由 UCB 一位名叫 Michael Stonebraker 的计算机科学教授创建。Stonebraker 在 1986 年启动 Postgres,作为其前身 Ingres 的后续项目(现由 Computer Associates 所有)。

PostgreSQL, originally called Postgres, was created at UCB by a computer science professor named Michael Stonebraker. Stonebraker started Postgres in 1986 as a follow-up project to its predecessor, Ingres, now owned by Computer Associates.

  1. 1977-1985 − A project called INGRES was developed. Proof-of-concept for relational databases Established the company Ingres in 1980 Bought by Computer Associates in 1994

  2. 1986-1994 − POSTGRES Development of the concepts in INGRES with a focus on object orientation and the query language - Quel The code base of INGRES was not used as a basis for POSTGRES Commercialized as Illustra (bought by Informix, bought by IBM)

  3. 1994-1995 − Postgres95 Support for SQL was added in 1994 Released as Postgres95 in 1995 Re-released as PostgreSQL 6.0 in 1996 Establishment of the PostgreSQL Global Development Team

Key Features of PostgreSQL

PostgreSQL 可以在所有主要操作系统上运行,包括 Linux、UNIX(AIX、BSD、HP-UX、SGI IRIX、Mac OS X、Solaris、Tru64)和 Windows。它支持文本、图像、声音和视频,并包括 C/C++、Java、Perl、Python、Ruby、Tcl 和开放式数据库连接 (ODBC) 的编程接口。

PostgreSQL runs on all major operating systems, including Linux, UNIX (AIX, BSD, HP-UX, SGI IRIX, Mac OS X, Solaris, Tru64), and Windows. It supports text, images, sounds, and video, and includes programming interfaces for C / C++, Java, Perl, Python, Ruby, Tcl and Open Database Connectivity (ODBC).

PostgreSQL 支持 SQL 标准的大部分内容,并提供许多现代功能,包括以下功能:

PostgreSQL supports a large part of the SQL standard and offers many modern features including the following −

  1. Complex SQL queries

  2. SQL Sub-selects

  3. Foreign keys

  4. Trigger

  5. Views

  6. Transactions

  7. Multiversion concurrency control (MVCC)

  8. Streaming Replication (as of 9.0)

  9. Hot Standby (as of 9.0)

您可以查看 PostgreSQL 的官方文档来理解上述功能。PostgreSQL 可以通过多种方式由用户扩展。例如,通过添加新的:

You can check official documentation of PostgreSQL to understand the above-mentioned features. PostgreSQL can be extended by the user in many ways. For example by adding new −

  1. Data types

  2. Functions

  3. Operators

  4. Aggregate functions

  5. Index methods

Procedural Languages Support

PostgreSQL 支持四种标准过程语言,允许用户使用任何语言编写自己的代码,并且可以由 PostgreSQL 数据库服务器执行。这些过程语言是 - PL/pgSQL、PL/Tcl、PL/Perl 和 PL/Python。此外,还支持其他非标准过程语言,如 PL/PHP、PL/V8、PL/Ruby、PL/Java 等。

PostgreSQL supports four standard procedural languages, which allows the users to write their own code in any of the languages and it can be executed by PostgreSQL database server. These procedural languages are - PL/pgSQL, PL/Tcl, PL/Perl and PL/Python. Besides, other non-standard procedural languages like PL/PHP, PL/V8, PL/Ruby, PL/Java, etc., are also supported.

PostgreSQL - Environment Setup

要开始理解 PostgreSQL 基础知识,首先让我们安装 PostgreSQL。本章解释了如何在 Linux、Windows 和 Mac OS 平台上安装 PostgreSQL。

To start understanding the PostgreSQL basics, first let us install the PostgreSQL. This chapter explains about installing the PostgreSQL on Linux, Windows and Mac OS platforms.

Installing PostgreSQL on Linux/Unix

按照给定的步骤在 Linux 机器上安装 PostgreSQL。请确保在进行安装时以 root 登录。

Follow the given steps to install PostgreSQL on your Linux machine. Make sure you are logged in as root before you proceed for the installation.

  1. Pick the version number of PostgreSQL you want and, as exactly as possible, the platform you want from EnterpriseDB

  2. I downloaded postgresql-9.2.4-1-linux-x64.run for my 64 bit CentOS-6 machine. Now, let us execute it as follows −

[root@host]# chmod +x postgresql-9.2.4-1-linux-x64.run
[root@host]# ./postgresql-9.2.4-1-linux-x64.run
------------------------------------------------------------------------
Welcome to the PostgreSQL Setup Wizard.

------------------------------------------------------------------------
Please specify the directory where PostgreSQL will be installed.

Installation Directory [/opt/PostgreSQL/9.2]:
  1. Once you launch the installer, it asks you a few basic questions like location of the installation, password of the user who will use database, port number, etc. So keep all of them at their default values except password, which you can provide password as per your choice. It will install PostgreSQL at your Linux machine and will display the following message −

Please wait while Setup installs PostgreSQL on your computer.

 Installing
 0% ______________ 50% ______________ 100%
 #########################################

-----------------------------------------------------------------------
Setup has finished installing PostgreSQL on your computer.
  1. Follow the following post-installation steps to create your database −

[root@host]# su - postgres
Password:
bash-4.1$ createdb testdb
bash-4.1$ psql testdb
psql (8.4.13, server 9.2.4)

test=#
  1. You can start/restart postgres server in case it is not running using the following command −

[root@host]# service postgresql restart
Stopping postgresql service:                               [  OK  ]
Starting postgresql service:                               [  OK  ]
  1. If your installation was correct, you will have PotsgreSQL prompt test=# as shown above.

Installing PostgreSQL on Windows

按照给定的步骤在 Windows 机器上安装 PostgreSQL。请确保在安装的同时关闭第三方防病毒软件。

Follow the given steps to install PostgreSQL on your Windows machine. Make sure you have turned Third Party Antivirus off while installing.

  1. Pick the version number of PostgreSQL you want and, as exactly as possible, the platform you want from EnterpriseDB

  2. I downloaded postgresql-9.2.4-1-windows.exe for my Windows PC running in 32bit mode, so let us run postgresql-9.2.4-1-windows.exe as administrator to install PostgreSQL. Select the location where you want to install it. By default, it is installed within Program Files folder.

postgresql install dir
  1. The next step of the installation process would be to select the directory where your data would be stored. By default, it is stored under the "data" directory.

postgresql install data
  1. Next, the setup asks for password, so you can use your favorite password.

postgresql install password
  1. The next step; keep the port as default.

postgresql install port
  1. In the next step, when asked for "Locale", I selected "English, United States".

  2. It takes a while to install PostgreSQL on your system. On completion of the installation process, you will get the following screen. Uncheck the checkbox and click the Finish button.

postgresql install finish

安装过程完成后,您可以从 PostgreSQL 9.2 下的程序菜单中访问 pgAdmin III、StackBuilder 和 PostgreSQL shell。

After the installation process is completed, you can access pgAdmin III, StackBuilder and PostgreSQL shell from your Program Menu under PostgreSQL 9.2.

Installing PostgreSQL on Mac

按照给定的步骤在 Mac 机器上安装 PostgreSQL。请确保在进行安装时以 administrator 登录。

Follow the given steps to install PostgreSQL on your Mac machine. Make sure you are logged in as administrator before you proceed for the installation.

  1. Pick the latest version number of PostgreSQL for Mac OS available at EnterpriseDB

  2. I downloaded postgresql-9.2.4-1-osx.dmg for my Mac OS running with OS X version 10.8.3. Now, let us open the dmg image in finder and just double click it which will give you PostgreSQL installer in the following window −

postgresql install mac
  1. Next, click the postgres-9.2.4-1-osx icon, which will give a warning message. Accept the warning and proceed for further installation. It will ask for the administrator password as seen in the following window −

postgresql password mac

输入密码,进行安装,在此步骤后,重新启动 Mac 机器。如果您看不到以下窗口,请重新启动安装。

Enter the password, proceed for the installation, and after this step, restart your Mac machine. If you do not see the following window, start your installation once again.

postgresql startinstall mac
  1. Once you launch the installer, it asks you a few basic questions like location of the installation, password of the user who will use database, port number etc. Therefore, keep all of them at their default values except the password, which you can provide as per your choice. It will install PostgreSQL in your Mac machine in the Application folder which you can check −

postgresql application mac
  1. Now, you can launch any of the program to start with. Let us start with SQL Shell. When you launch SQL Shell, just use all the default values it displays except, enter your password, which you had selected at the time of installation. If everything goes fine, then you will be inside postgres database and a postgress# prompt will be displayed as shown below −

postgresql sqlshell mac

恭喜!!!现在,您的环境已准备好开始使用 PostgreSQL 数据库编程。

Congratulations!!! Now you have your environment ready to start with PostgreSQL database programming.

PostgreSQL - Syntax

本章提供了 PostgreSQL SQL 命令的列表,后跟每个命令的精确语法规则。这组命令来自 psql 命令行工具。既然您已安装 Postgres,请以以下方式打开 psql:

This chapter provides a list of the PostgreSQL SQL commands, followed by the precise syntax rules for each of these commands. This set of commands is taken from the psql command-line tool. Now that you have Postgres installed, open the psql as −

Program Files → PostgreSQL 9.2 → SQL Shell(psql).

Program Files → PostgreSQL 9.2 → SQL Shell(psql).

使用 psql,您可以通过使用 \help 命令生成命令的完整列表。对于特定命令的语法,使用以下命令:

Using psql, you can generate a complete list of commands by using the \help command. For the syntax of a specific command, use the following command −

 postgres-# \help <command_name>

The SQL Statement

SQL 语句由标记组成,其中每个标记可以表示关键字、标识符、带引号的标识符、常量或特殊字符符号。下表使用一个简单的 SELECT 语句来说明一个基本但完整的 SQL 语句及其组成部分。

An SQL statement is comprised of tokens where each token can represent either a keyword, identifier, quoted identifier, constant, or special character symbol. The table given below uses a simple SELECT statement to illustrate a basic, but complete, SQL statement and its components.

SELECT

id, name

FROM

states

Token Type

Keyword

Identifiers

Keyword

Identifier

Description

Command

Id and name columns

Clause

Table name

PostgreSQL SQL commands

ABORT

中断当前事务。

Abort the current transaction.

ABORT [ WORK | TRANSACTION ]

ALTER AGGREGATE

更改聚合函数的定义。

Change the definition of an aggregate function.

ALTER AGGREGATE name ( type ) RENAME TO new_name
ALTER AGGREGATE name ( type ) OWNER TO new_owner

ALTER CONVERSION

更改转换的定义。

Change the definition of a conversion.

ALTER CONVERSION name RENAME TO new_name
ALTER CONVERSION name OWNER TO new_owner

ALTER DATABASE

更改特定于数据库的参数。

Change a database specific parameter.

ALTER DATABASE name SET parameter { TO | = } { value | DEFAULT }
ALTER DATABASE name RESET parameter
ALTER DATABASE name RENAME TO new_name
ALTER DATABASE name OWNER TO new_owner

ALTER DOMAIN

更改特定于域的参数的定义。

Change the definition of a domain specific parameter.

ALTER DOMAIN name { SET DEFAULT expression | DROP DEFAULT }
ALTER DOMAIN name { SET | DROP } NOT NULL
ALTER DOMAIN name ADD domain_constraint
ALTER DOMAIN name DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
ALTER DOMAIN name OWNER TO new_owner

ALTER FUNCTION

更改函数的定义。

Change the definition of a function.

ALTER FUNCTION name ( [ type [, ...] ] ) RENAME TO new_name
ALTER FUNCTION name ( [ type [, ...] ] ) OWNER TO new_owner

ALTER GROUP

更改用户组。

Change a user group.

ALTER GROUP groupname ADD USER username [, ... ]
ALTER GROUP groupname DROP USER username [, ... ]
ALTER GROUP groupname RENAME TO new_name

ALTER INDEX

更改索引的定义。

Change the definition of an index.

ALTER INDEX name OWNER TO new_owner
ALTER INDEX name SET TABLESPACE indexspace_name
ALTER INDEX name RENAME TO new_name

ALTER LANGUAGE

更改过程语言的定义。

Change the definition of a procedural language.

ALTER LANGUAGE name RENAME TO new_name

ALTER OPERATOR

更改运算符的定义。

Change the definition of an operator.

ALTER OPERATOR name ( { lefttype | NONE }, { righttype | NONE } )
OWNER TO new_owner

ALTER OPERATOR CLASS

更改操作员类的定义。

Change the definition of an operator class.

ALTER OPERATOR CLASS name USING index_method RENAME TO new_name
ALTER OPERATOR CLASS name USING index_method OWNER TO new_owner

ALTER SCHEMA

更改模式的定义。

Change the definition of a schema.

ALTER SCHEMA name RENAME TO new_name
ALTER SCHEMA name OWNER TO new_owner

ALTER SEQUENCE

更改序列发生器的定义。

Change the definition of a sequence generator.

ALTER SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ]
[ MAXVALUE maxvalue | NO MAXVALUE ]
[ RESTART [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]

ALTER TABLE

更改表定义。

Change the definition of a table.

ALTER TABLE [ ONLY ] name [ * ]
action [, ... ]
ALTER TABLE [ ONLY ] name [ * ]
RENAME [ COLUMN ] column TO new_column
ALTER TABLE name
RENAME TO new_name

其中操作是以下行之一 −

Where action is one of the following lines −

ADD [ COLUMN ] column_type [ column_constraint [ ... ] ]
DROP [ COLUMN ] column [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] column TYPE type [ USING expression ]
ALTER [ COLUMN ] column SET DEFAULT expression
ALTER [ COLUMN ] column DROP DEFAULT
ALTER [ COLUMN ] column { SET | DROP } NOT NULL
ALTER [ COLUMN ] column SET STATISTICS integer
ALTER [ COLUMN ] column SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ADD table_constraint
DROP CONSTRAINT constraint_name [ RESTRICT | CASCADE ]
CLUSTER ON index_name
SET WITHOUT CLUSTER
SET WITHOUT OIDS
OWNER TO new_owner
SET TABLESPACE tablespace_name

ALTER TABLESPACE

更改表空间的定义。

Change the definition of a tablespace.

ALTER TABLESPACE name RENAME TO new_name
ALTER TABLESPACE name OWNER TO new_owner

ALTER TRIGGER

更改触发器的定义。

Change the definition of a trigger.

ALTER TRIGGER name ON table RENAME TO new_name

ALTER TYPE

更改类型的定义。

Change the definition of a type.

ALTER TYPE name OWNER TO new_owner

ALTER USER

更改数据库用户帐户。

Change a database user account.

ALTER USER name [ [ WITH ] option [ ... ] ]
ALTER USER name RENAME TO new_name
ALTER USER name SET parameter { TO | = } { value | DEFAULT }
ALTER USER name RESET parameter

其中选项可以为 −

Where option can be −

[ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
| CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| VALID UNTIL 'abstime'

ANALYZE

收集有关数据库的统计信息。

Collect statistics about a database.

ANALYZE [ VERBOSE ] [ table [ (column [, ...] ) ] ]

BEGIN

启动事务块。

Start a transaction block.

BEGIN [ WORK | TRANSACTION ] [ transaction_mode [, ...] ]

其中事务模式是 − 中的一个

Where transaction_mode is one of −

ISOLATION LEVEL {
   SERIALIZABLE | REPEATABLE READ | READ COMMITTED
   | READ UNCOMMITTED
}
READ WRITE | READ ONLY

CHECKPOINT

强制事务日志检查点。

Force a transaction log checkpoint.

CHECKPOINT

CLOSE

关闭游标。

Close a cursor.

CLOSE name

CLUSTER

根据索引对表进行群集。

Cluster a table according to an index.

CLUSTER index_name ON table_name
CLUSTER table_name
CLUSTER

COMMENT

定义或更改对象的注释。

Define or change the comment of an object.

COMMENT ON {
   TABLE object_name |
   COLUMN table_name.column_name |
   AGGREGATE agg_name (agg_type) |
   CAST (source_type AS target_type) |
   CONSTRAINT constraint_name ON table_name |
   CONVERSION object_name |
   DATABASE object_name |
   DOMAIN object_name |
   FUNCTION func_name (arg1_type, arg2_type, ...) |
   INDEX object_name |
   LARGE OBJECT large_object_oid |
   OPERATOR op (left_operand_type, right_operand_type) |
   OPERATOR CLASS object_name USING index_method |
   [ PROCEDURAL ] LANGUAGE object_name |
   RULE rule_name ON table_name |
   SCHEMA object_name |
   SEQUENCE object_name |
   TRIGGER trigger_name ON table_name |
   TYPE object_name |
   VIEW object_name
}
IS 'text'

COMMIT

提交当前事务。

Commit the current transaction.

COMMIT [ WORK | TRANSACTION ]

COPY

在文件和表之间复制数据。

Copy data between a file and a table.

COPY table_name [ ( column [, ...] ) ]
FROM { 'filename' | STDIN }
[ WITH ]
[ BINARY ]
[ OIDS ]
[ DELIMITER [ AS ] 'delimiter' ]
[ NULL [ AS ] 'null string' ]
[ CSV [ QUOTE [ AS ] 'quote' ]
[ ESCAPE [ AS ] 'escape' ]
[ FORCE NOT NULL column [, ...] ]
COPY table_name [ ( column [, ...] ) ]
TO { 'filename' | STDOUT }
[ [ WITH ]
[ BINARY ]
[ OIDS ]
[ DELIMITER [ AS ] 'delimiter' ]
[ NULL [ AS ] 'null string' ]
[ CSV [ QUOTE [ AS ] 'quote' ]
[ ESCAPE [ AS ] 'escape' ]
[ FORCE QUOTE column [, ...] ]

CREATE AGGREGATE

定义一个新的聚合函数。

Define a new aggregate function.

CREATE AGGREGATE name (
   BASETYPE = input_data_type,
   SFUNC = sfunc,
   STYPE = state_data_type
   [, FINALFUNC = ffunc ]
   [, INITCOND = initial_condition ]
)

CREATE CAST

定义一个新的类型转换。

Define a new cast.

CREATE CAST (source_type AS target_type)
WITH FUNCTION func_name (arg_types)
[ AS ASSIGNMENT | AS IMPLICIT ]
CREATE CAST (source_type AS target_type)
WITHOUT FUNCTION
[ AS ASSIGNMENT | AS IMPLICIT ]

CREATE CONSTRAINT TRIGGER

定义一个新的约束触发器。

Define a new constraint trigger.

CREATE CONSTRAINT TRIGGER name
AFTER events ON
table_name constraint attributes
FOR EACH ROW EXECUTE PROCEDURE func_name ( args )

CREATE CONVERSION

定义一个新的转换。

Define a new conversion.

CREATE [DEFAULT] CONVERSION name
FOR source_encoding TO dest_encoding FROM func_name

CREATE DATABASE

创建一个新数据库。

Create a new database.

CREATE DATABASE name
[ [ WITH ] [ OWNER [=] db_owner ]
   [ TEMPLATE [=] template ]
   [ ENCODING [=] encoding ]
   [ TABLESPACE [=] tablespace ]
]

CREATE DOMAIN

定义一个新域。

Define a new domain.

CREATE DOMAIN name [AS] data_type
[ DEFAULT expression ]
[ constraint [ ... ] ]

其中约束为-

Where constraint is −

[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }

CREATE FUNCTION

定义一个新函数。

Define a new function.

CREATE [ OR REPLACE ] FUNCTION name ( [ [ arg_name ] arg_type [, ...] ] )
RETURNS ret_type
{ LANGUAGE lang_name
   | IMMUTABLE | STABLE | VOLATILE
   | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
   | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
   | AS 'definition'
   | AS 'obj_file', 'link_symbol'
} ...
[ WITH ( attribute [, ...] ) ]

CREATE GROUP

定义一个新用户组。

Define a new user group.

CREATE GROUP name [ [ WITH ] option [ ... ] ]
Where option can be:
SYSID gid
| USER username [, ...]

CREATE INDEX

定义一个新索引。

Define a new index.

CREATE [ UNIQUE ] INDEX name ON table [ USING method ]
( { column | ( expression ) } [ opclass ] [, ...] )
[ TABLESPACE tablespace ]
[ WHERE predicate ]

CREATE LANGUAGE

定义一个新的过程语言。

Define a new procedural language.

CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE name
HANDLER call_handler [ VALIDATOR val_function ]

CREATE OPERATOR

定义一个新运算符。

Define a new operator.

CREATE OPERATOR name (
   PROCEDURE = func_name
   [, LEFTARG = left_type ] [, RIGHTARG = right_type ]
   [, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
   [, RESTRICT = res_proc ] [, JOIN = join_proc ]
   [, HASHES ] [, MERGES ]
   [, SORT1 = left_sort_op ] [, SORT2 = right_sort_op ]
   [, LTCMP = less_than_op ] [, GTCMP = greater_than_op ]
)

CREATE OPERATOR CLASS

定义一个新的运算符类。

Define a new operator class.

CREATE OPERATOR CLASS name [ DEFAULT ] FOR TYPE data_type
USING index_method AS
{ OPERATOR strategy_number operator_name [ ( op_type, op_type ) ] [ RECHECK ]
   | FUNCTION support_number func_name ( argument_type [, ...] )
   | STORAGE storage_type
} [, ... ]

CREATE RULE

定义一个新的重写规则。

Define a new rewrite rule.

CREATE [ OR REPLACE ] RULE name AS ON event
TO table [ WHERE condition ]
DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) }

CREATE SCHEMA

定义一个新模式。

Define a new schema.

CREATE SCHEMA schema_name
[ AUTHORIZATION username ] [ schema_element [ ... ] ]
CREATE SCHEMA AUTHORIZATION username
[ schema_element [ ... ] ]

CREATE SEQUENCE

定义一个新序列发生器。

Define a new sequence generator.

CREATE [ TEMPORARY | TEMP ] SEQUENCE name
[ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ]
[ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]

CREATE TABLE

定义一个新表。

Define a new table.

CREATE [ [ GLOBAL | LOCAL ] {
   TEMPORARY | TEMP } ] TABLE table_name ( {
      column_name data_type [ DEFAULT default_expr ] [ column_constraint [ ... ] ]
      | table_constraint
      | LIKE parent_table [ { INCLUDING | EXCLUDING } DEFAULTS ]
   } [, ... ]
)
[ INHERITS ( parent_table [, ... ] ) ]
[ WITH OIDS | WITHOUT OIDS ]
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
[ TABLESPACE tablespace ]

其中 column_constraint 为-

Where column_constraint is −

[ CONSTRAINT constraint_name ] {
   NOT NULL |
   NULL |
   UNIQUE [ USING INDEX TABLESPACE tablespace ] |
   PRIMARY KEY [ USING INDEX TABLESPACE tablespace ] |
   CHECK (expression) |
   REFERENCES ref_table [ ( ref_column ) ]
   [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
   [ ON DELETE action ] [ ON UPDATE action ]
}
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

其中 table_constraint 为-

And table_constraint is −

[ CONSTRAINT constraint_name ]
{ UNIQUE ( column_name [, ... ] ) [ USING INDEX TABLESPACE tablespace ] |
PRIMARY KEY ( column_name [, ... ] ) [ USING INDEX TABLESPACE tablespace ] |
CHECK ( expression ) |
FOREIGN KEY ( column_name [, ... ] )
REFERENCES ref_table [ ( ref_column [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE action ] [ ON UPDATE action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]

CREATE TABLE AS

根据查询结果定义一个新表。

Define a new table from the results of a query.

CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE table_name
[ (column_name [, ...] ) ] [ [ WITH | WITHOUT ] OIDS ]
AS query

CREATE TABLESPACE

定义一个新的表空间。

Define a new tablespace.

CREATE TABLESPACE tablespace_name [ OWNER username ] LOCATION 'directory'

CREATE TRIGGER

定义一个新的触发器。

Define a new trigger.

CREATE TRIGGER name { BEFORE | AFTER } { event [ OR ... ] }
ON table [ FOR [ EACH ] { ROW | STATEMENT } ]
EXECUTE PROCEDURE func_name ( arguments )

CREATE TYPE

定义一个新的数据类型。

Define a new data type.

CREATE TYPE name AS
( attribute_name data_type [, ... ] )
CREATE TYPE name (
INPUT = input_function,
OUTPUT = output_function
[, RECEIVE = receive_function ]
[, SEND = send_function ]
[, ANALYZE = analyze_function ]
[, INTERNALLENGTH = { internal_length | VARIABLE } ]
[, PASSEDBYVALUE ]
[, ALIGNMENT = alignment ]
[, STORAGE = storage ]
[, DEFAULT = default ]
[, ELEMENT = element ]
[, DELIMITER = delimiter ]
)

CREATE USER

定义一个新的数据库用户帐户。

Define a new database user account.

CREATE USER name [ [ WITH ] option [ ... ] ]

其中选项可以为 −

Where option can be −

SYSID uid
| [ ENCRYPTED | UNENCRYPTED ] PASSWORD 'password'
| CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| IN GROUP group_name [, ...]
| VALID UNTIL 'abs_time'

CREATE VIEW

定义一个新的视图。

Define a new view.

CREATE [ OR REPLACE ] VIEW name [ ( column_name [, ...] ) ] AS query

DEALLOCATE

取消分配准备好的语句。

Deallocate a prepared statement.

DEALLOCATE [ PREPARE ] plan_name

DECLARE

定义一个游标。

Define a cursor.

DECLARE name [ BINARY ] [ INSENSITIVE ] [ [ NO ] SCROLL ]
CURSOR [ { WITH | WITHOUT } HOLD ] FOR query
[ FOR { READ ONLY | UPDATE [ OF column [, ...] ] } ]

DELETE

删除表中的行。

Delete rows of a table.

DELETE FROM [ ONLY ] table [ WHERE condition ]

DROP AGGREGATE

删除一个聚集函数。

Remove an aggregate function.

DROP AGGREGATE name ( type ) [ CASCADE | RESTRICT ]

DROP CAST

删除一个 cast。

Remove a cast.

DROP CAST (source_type AS target_type) [ CASCADE | RESTRICT ]

DROP CONVERSION

删除一个转换。

Remove a conversion.

DROP CONVERSION name [ CASCADE | RESTRICT ]

DROP DATABASE

删除一个数据库。

Remove a database.

DROP DATABASE name

DROP DOMAIN

删除一个域。

Remove a domain.

DROP DOMAIN name [, ...] [ CASCADE | RESTRICT ]

DROP FUNCTION

删除一个函数。

Remove a function.

DROP FUNCTION name ( [ type [, ...] ] ) [ CASCADE | RESTRICT ]

DROP GROUP

删除一个用户组。

Remove a user group.

DROP GROUP name

DROP INDEX

删除一个索引。

Remove an index.

DROP INDEX name [, ...] [ CASCADE | RESTRICT ]

DROP LANGUAGE

删除一个过程语言。

Remove a procedural language.

DROP [ PROCEDURAL ] LANGUAGE name [ CASCADE | RESTRICT ]

DROP OPERATOR

删除一个操作符。

Remove an operator.

DROP OPERATOR name ( { left_type | NONE }, { right_type | NONE } )
[ CASCADE | RESTRICT ]

DROP OPERATOR CLASS

删除操作员类。

Remove an operator class.

DROP OPERATOR CLASS name USING index_method [ CASCADE | RESTRICT ]

DROP RULE

删除重写规则。

Remove a rewrite rule.

DROP RULE name ON relation [ CASCADE | RESTRICT ]

DROP SCHEMA

删除模式。

Remove a schema.

DROP SCHEMA name [, ...] [ CASCADE | RESTRICT ]

DROP SEQUENCE

删除序列。

Remove a sequence.

DROP SEQUENCE name [, ...] [ CASCADE | RESTRICT ]

DROP TABLE

删除表。

Remove a table.

DROP TABLE name [, ...] [ CASCADE | RESTRICT ]

DROP TABLESPACE

删除表空间。

Remove a tablespace.

DROP TABLESPACE tablespace_name

DROP TRIGGER

删除触发器。

Remove a trigger.

DROP TRIGGER name ON table [ CASCADE | RESTRICT ]

DROP TYPE

删除数据类型。

Remove a data type.

DROP TYPE name [, ...] [ CASCADE | RESTRICT ]

DROP USER

删除数据库用户帐户。

Remove a database user account.

DROP USER name

DROP VIEW

删除视图。

Remove a view.

DROP VIEW name [, ...] [ CASCADE | RESTRICT ]

END

提交当前事务。

Commit the current transaction.

END [ WORK | TRANSACTION ]

EXECUTE

执行已准备好的语句。

Execute a prepared statement.

EXECUTE plan_name [ (parameter [, ...] ) ]

EXPLAIN

显示语句的执行计划。

Show the execution plan of a statement.

EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

FETCH

使用游标从查询中检索行。

Retrieve rows from a query using a cursor.

FETCH [ direction { FROM | IN } ] cursor_name

路径方向可以为空或如下内容之一 −

Where direction can be empty or one of −

NEXT
PRIOR
FIRST
LAST
ABSOLUTE count
RELATIVE count
count
ALL
FORWARD
FORWARD count
FORWARD ALL
BACKWARD
BACKWARD count
BACKWARD ALL

GRANT

定义访问权限。

Define access privileges.

GRANT { { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] table_name [, ...]
TO { username | GROUP group_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE db_name [, ...]
TO { username | GROUP group_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespace_name [, ...]
TO { username | GROUP group_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION func_name ([type, ...]) [, ...]
TO { username | GROUP group_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE lang_name [, ...]
TO { username | GROUP group_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

GRANT { { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
TO { username | GROUP group_name | PUBLIC } [, ...] [ WITH GRANT OPTION ]

INSERT

在表中创建新行。

Create new rows in a table.

INSERT INTO table [ ( column [, ...] ) ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] ) | query }

LISTEN

监听通知。

Listen for a notification.

LISTEN name

LOAD

载入或重新载入共享库文件。

Load or reload a shared library file.

LOAD 'filename'

LOCK

锁定表。

Lock a table.

LOCK [ TABLE ] name [, ...] [ IN lock_mode MODE ] [ NOWAIT ]

其中 lock_mode 是 - 中的一个:

Where lock_mode is one of −

ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE
| SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE

MOVE

放置一个光标。

Position a cursor.

MOVE [ direction { FROM | IN } ] cursor_name

NOTIFY

生成一个通知。

Generate a notification.

NOTIFY name

PREPARE

准备一条语句用以执行。

Prepare a statement for execution.

PREPARE plan_name [ (data_type [, ...] ) ] AS statement

REINDEX

重建索引。

Rebuild indexes.

REINDEX { DATABASE | TABLE | INDEX } name [ FORCE ]

RELEASE SAVEPOINT

销毁一个之前定义的保存点。

Destroy a previously defined savepoint.

RELEASE [ SAVEPOINT ] savepoint_name

RESET

将一个运行时参数的值还原为默认值。

Restore the value of a runtime parameter to the default value.

RESET name
RESET ALL

REVOKE

移除访问权限。

Remove access privileges.

REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | RULE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] table_name [, ...]
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ { CREATE | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE db_name [, ...]
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ CREATE | ALL [ PRIVILEGES ] }
ON TABLESPACE tablespace_name [, ...]
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ EXECUTE | ALL [ PRIVILEGES ] }
ON FUNCTION func_name ([type, ...]) [, ...]
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ USAGE | ALL [ PRIVILEGES ] }
ON LANGUAGE lang_name [, ...]
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

REVOKE [ GRANT OPTION FOR ]
{ { CREATE | USAGE } [,...] | ALL [ PRIVILEGES ] }
ON SCHEMA schema_name [, ...]
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]

ROLLBACK

中断当前事务。

Abort the current transaction.

ROLLBACK [ WORK | TRANSACTION ]

ROLLBACK TO SAVEPOINT

回滚到一个保存点。

Roll back to a savepoint.

ROLLBACK [ WORK | TRANSACTION ] TO [ SAVEPOINT ] savepoint_name

SAVEPOINT

在当前事务中定义一个新的保存点。

Define a new savepoint within the current transaction.

SAVEPOINT savepoint_name

SELECT

从一个表或视图中检索行。

Retrieve rows from a table or view.

SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
* | expression [ AS output_name ] [, ...]
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ]
[ LIMIT { count | ALL } ]
[ OFFSET start ]
[ FOR UPDATE [ OF table_name [, ...] ] ]
[ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
function_name ( [ argument [, ...] ] )
[ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]
function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
from_item [ NATURAL ] join_type from_item
[ ON join_condition | USING ( join_column [, ...] ) ]

SELECT INTO

根据查询结果定义一个新表。

Define a new table from the results of a query.

SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
* | expression [ AS output_name ] [, ...]
INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table
[ FROM from_item [, ...] ]
[ WHERE condition ]
[ GROUP BY expression [, ...] ]
[ HAVING condition [, ...] ]
[ { UNION | INTERSECT | EXCEPT } [ ALL ] select ]
[ ORDER BY expression [ ASC | DESC | USING operator ] [, ...] ]
[ LIMIT { count | ALL } ]
[ OFFSET start ]
[ FOR UPDATE [ OF table_name [, ...] ] ]

SET

更改一个运行时参数。

Change a runtime parameter.

SET [ SESSION | LOCAL ] name { TO | = } { value | 'value' | DEFAULT }
SET [ SESSION | LOCAL ] TIME ZONE { time_zone | LOCAL | DEFAULT }

SET CONSTRAINTS

为当前事务设置约束检查模式。

Set constraint checking modes for the current transaction.

SET CONSTRAINTS { ALL | name [, ...] } { DEFERRED | IMMEDIATE }

SET SESSION AUTHORIZATION

设置当前会话的会话用户标识符和当前用户标识符。

Set the session user identifier and the current user identifier of the current session.

SET [ SESSION | LOCAL ] SESSION AUTHORIZATION username
SET [ SESSION | LOCAL ] SESSION AUTHORIZATION DEFAULT
RESET SESSION AUTHORIZATION

SET TRANSACTION

设置当前事务的特征。

Set the characteristics of the current transaction.

SET TRANSACTION transaction_mode [, ...]
SET SESSION CHARACTERISTICS AS TRANSACTION transaction_mode [, ...]

其中事务模式是 − 中的一个

Where transaction_mode is one of −

ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED
| READ UNCOMMITTED }
READ WRITE | READ ONLY

SHOW

显示一个运行时参数的值。

Show the value of a runtime parameter.

SHOW name
SHOW ALL

START TRANSACTION

启动事务块。

Start a transaction block.

START TRANSACTION [ transaction_mode [, ...] ]

其中事务模式是 − 中的一个

Where transaction_mode is one of −

ISOLATION LEVEL { SERIALIZABLE | REPEATABLE READ | READ COMMITTED
| READ UNCOMMITTED }
READ WRITE | READ ONLY

TRUNCATE

清空一个表。

Empty a table.

TRUNCATE [ TABLE ] name

UNLISTEN

停止监听一个通知。

Stop listening for a notification.

UNLISTEN { name | * }

UPDATE

更新一个表中的行。

Update rows of a table.

UPDATE [ ONLY ] table SET column = { expression | DEFAULT } [, ...]
[ FROM from_list ]
[ WHERE condition ]

VACUUM

手动收集垃圾,可选地分析数据库。

Garbage-collect and optionally analyze a database.

VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ table ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ]

PostgreSQL - Data Type

在本章中,我们将讨论 PostgreSQL 中使用的数据类型。创建表时,对于每一列,您需要指定一种数据类型,即您希望存储在表字段中的数据类型。

In this chapter, we will discuss about the data types used in PostgreSQL. While creating table, for each column, you specify a data type, i.e., what kind of data you want to store in the table fields.

这有几个好处:

This enables several benefits −

  1. Consistency − Operations against columns of same data type give consistent results and are usually the fastest.

  2. Validation − Proper use of data types implies format validation of data and rejection of data outside the scope of data type.

  3. Compactness − As a column can store a single type of value, it is stored in a compact way.

  4. Performance − Proper use of data types gives the most efficient storage of data. The values stored can be processed quickly, which enhances the performance.

PostgreSQL 支持多种数据类型。此外,用户可以使用 CREATE TYPE SQL 命令创建自己的自定义数据类型。PostgreSQL 中有不同的数据类型类别。它们将在下面讨论。

PostgreSQL supports a wide set of Data Types. Besides, users can create their own custom data type using CREATE TYPE SQL command. There are different categories of data types in PostgreSQL. They are discussed below.

Numeric Types

数值类型由两字节、四字节和八字节整数、四字节和八字节浮点数以及可选精度的十进制数组成。下表列出了可用的类型。

Numeric types consist of two-byte, four-byte, and eight-byte integers, four-byte and eight-byte floating-point numbers, and selectable-precision decimals. The following table lists the available types.

Name

Storage Size

Description

Range

smallint

2 bytes

small-range integer

-32768 to +32767

integer

4 bytes

typical choice for integer

-2147483648 to +2147483647

bigint

8 bytes

large-range integer

-9223372036854775808 to 9223372036854775807

decimal

variable

user-specified precision,exact

up to 131072 digits before the decimal point; up to 16383 digits after the decimal point

numeric

variable

user-specified precision,exact

up to 131072 digits before the decimal point; up to 16383 digits after the decimal point

real

4 bytes

variable-precision,inexact

6 decimal digits precision

double precision

8 bytes

variable-precision,inexact

15 decimal digits precision

smallserial

2 bytes

small autoincrementing integer

1 to 32767

serial

4 bytes

autoincrementing integer

1 to 2147483647

bigserial

8 bytes

large autoincrementing integer

1 to 9223372036854775807

Monetary Types

money 类型以固定的分数精度存储货币金额。numeric、int 和 bigint 数据类型的值可以转换为 money。由于存在舍入误差的可能性,因此不建议使用浮点数来处理货币。

The money type stores a currency amount with a fixed fractional precision. Values of the numeric, int, and bigint data types can be cast to money. Using Floating point numbers is not recommended to handle money due to the potential for rounding errors.

Name

Storage Size

Description

Range

money

8 bytes

currency amount

-92233720368547758.08 to +92233720368547758.07

Character Types

下表列出了 PostgreSQL 中提供的通用字符类型。

The table given below lists the general-purpose character types available in PostgreSQL.

S. No.

Name & Description

1

character varying(n), varchar(n) variable-length with limit

2

character(n), char(n) fixed-length, blank padded

3

text variable unlimited length

Binary Data Types

bytea 数据类型允许存储二进制字符串,如下表所示。

The bytea data type allows storage of binary strings as in the table given below.

Name

Storage Size

Description

bytea

1 or 4 bytes plus the actual binary string

variable-length binary string

Date/Time Types

PostgreSQL 支持全套 SQL 日期和时间类型,如下表所示。日期根据公历计算。在此,所有类型的分辨率为 1 microsecond / 14 digits ,除了 date 类型,其分辨率为 day

PostgreSQL supports a full set of SQL date and time types, as shown in table below. Dates are counted according to the Gregorian calendar. Here, all the types have resolution of 1 microsecond / 14 digits except date type, whose resolution is day.

Name

Storage Size

Description

Low Value

High Value

timestamp [(p)] [without time zone ]

8 bytes

both date and time (no time zone)

4713 BC

294276 AD

TIMESTAMPTZ

8 bytes

both date and time, with time zone

4713 BC

294276 AD

date

4 bytes

date (no time of day)

4713 BC

5874897 AD

time [ (p)] [ without time zone ]

8 bytes

time of day (no date)

00:00:00

24:00:00

time [ (p)] with time zone

12 bytes

times of day only, with time zone

00:00:00+1459

24:00:00-1459

interval [fields ] [(p) ]

12 bytes

time interval

-178000000 years

178000000 years

Boolean Type

PostgreSQL 提供标准 SQL 类型 Boolean。Boolean 数据类型可以具有 true、false 状态以及第三个状态 unknown,它由 SQL null 值表示。

PostgreSQL provides the standard SQL type Boolean. The Boolean data type can have the states true, false, and a third state, unknown, which is represented by the SQL null value.

Name

Storage Size

Description

boolean

1 byte

state of true or false

Enumerated Type

枚举 (enum) 类型是一种包含静态有序值集的数据类型。它们相当于许多编程语言中支持的枚举类型。

Enumerated (enum) types are data types that comprise a static, ordered set of values. They are equivalent to the enum types supported in a number of programming languages.

与其他类型不同,枚举类型需要使用 CREATE TYPE 命令来创建。此类型用于存储静态有序值集。例如,罗盘方向(即 NORTH、SOUTH、EAST 和 WEST)或如下所示的星期几:

Unlike other types, Enumerated Types need to be created using CREATE TYPE command. This type is used to store a static, ordered set of values. For example compass directions, i.e., NORTH, SOUTH, EAST, and WEST or days of the week as shown below −

CREATE TYPE week AS ENUM ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun');

枚举创建后,可以像任何其他类型一样使用。

Enumerated, once created, can be used like any other types.

Geometric Type

几何数据类型表示二维空间对象。最基本类型,点,构成了所有其他类型。

Geometric data types represent two-dimensional spatial objects. The most fundamental type, the point, forms the basis for all of the other types.

Name

Storage Size

Representation

Description

point

16 bytes

Point on a plane

(x,y)

line

32 bytes

Infinite line (not fully implemented)

x1,y1),(x2,y2

lseg

32 bytes

Finite line segment

x1,y1),(x2,y2

box

32 bytes

Rectangular box

x1,y1),(x2,y2

path

16+16n bytes

Closed path (similar to polygon)

((x1,y1),…​)

path

16+16n bytes

Open path

[(x1,y1),…​]

polygon

40+16n

Polygon (similar to closed path)

((x1,y1),…​)

circle

24 bytes

Circle

<(x,y),r> (center point and radius)

Network Address Type

PostgreSQL 提供数据类型来存储 IPv4、IPv6 和 MAC 地址。最好使用这些类型而不是纯文本类型来存储网络地址,因为这些类型提供了输入错误检查和专用运算符和函数。

PostgreSQL offers data types to store IPv4, IPv6, and MAC addresses. It is better to use these types instead of plain text types to store network addresses, because these types offer input error checking and specialized operators and functions.

Name

Storage Size

Description

cidr

7 or 19 bytes

IPv4 and IPv6 networks

inet

7 or 19 bytes

IPv4 and IPv6 hosts and networks

macaddr

6 bytes

MAC addresses

Bit String Type

二进制字符串类型用于存储位掩码。它们可能是 0 或 1。有两种 SQL 位类型: bit(n)bit varying(n) ,其中 n 是一个正整数。

Bit String Types are used to store bit masks. They are either 0 or 1. There are two SQL bit types: bit(n) and bit varying(n), where n is a positive integer.

Text Search Type

此类型支持全文搜索,它是一种在自然语言文档集合中搜索最能匹配查询的文档的活动。为此,有两种数据类型:

This type supports full text search, which is the activity of searching through a collection of natural-language documents to locate those that best match a query. There are two Data Types for this −

S. No.

Name & Description

1

tsvector This is a sorted list of distinct words that have been normalized to merge different variants of the same word, called as "lexemes".

2

tsquery This stores lexemes that are to be searched for, and combines them honoring the Boolean operators & (AND),

UUID Type

UUID(通用唯一标识符)被写成一串小写十六进制数字,分为几组,并用连字符分隔,具体来说,一组八位数字,后面跟着三组四位数字,再跟着一组 12 位数字,总共 32 位数字表示 128 位。

A UUID (Universally Unique Identifiers) is written as a sequence of lower-case hexadecimal digits, in several groups separated by hyphens, specifically a group of eight digits, followed by three groups of four digits, followed by a group of 12 digits, for a total of 32 digits representing the 128 bits.

UUID 的一个示例是 - 550e8400-e29b-41d4-a716-446655440000

An example of a UUID is − 550e8400-e29b-41d4-a716-446655440000

XML Type

XML 数据类型可用于存储 XML 数据。要存储 XML 数据,首先必须使用 xmlparse 函数创建 XML 值,如下所示:

The XML data type can be used to store XML data. For storing XML data, first you have to create XML values using the function xmlparse as follows −

XMLPARSE (DOCUMENT '<?xml version="1.0"?>
<tutorial>
<title>PostgreSQL Tutorial </title>
   <topics>...</topics>
</tutorial>')

XMLPARSE (CONTENT 'xyz<foo>bar</foo><bar>foo</bar>')

JSON Type

json 数据类型可用于存储 JSON(JavaScript 对象表示法)数据。此类数据也可以存储为文本,但 json 数据类型具有检查每个存储值是有效 JSON 值的优点。还有可用的相关支持函数,可直接用于处理 JSON 数据类型,如下所示。

The json data type can be used to store JSON (JavaScript Object Notation) data. Such data can also be stored as text, but the json data type has the advantage of checking that each stored value is a valid JSON value. There are also related support functions available, which can be used directly to handle JSON data type as follows.

Example

Example Result

array_to_json('{{1,5},{99,100}}'::int[])

[[1,5],[99,100]]

row_to_json(row(1,'foo'))

{"f1":1,"f2":"foo"}

Array Type

PostgreSQL 提供将表的列定义为变长多维数组的机会。任何内置或用户定义的基本类型、枚举类型或复合类型的数组都可以创建。

PostgreSQL gives the opportunity to define a column of a table as a variable length multidimensional array. Arrays of any built-in or user-defined base type, enum type, or composite type can be created.

Declaration of Arrays

数组类型可以声明为

Array type can be declared as

CREATE TABLE monthly_savings (
   name text,
   saving_per_quarter integer[],
   scheme text[][]
);

或使用关键字“ARRAY”如下声明:

or by using the keyword "ARRAY" as

CREATE TABLE monthly_savings (
   name text,
   saving_per_quarter integer ARRAY[4],
   scheme text[][]
);

Inserting values

数组值可以作为一个文字常量插入,用大括号将元素值括起来,并用逗号分隔。以下是一个示例:

Array values can be inserted as a literal constant, enclosing the element values within curly braces and separating them by commas. An example is shown below −

INSERT INTO monthly_savings
VALUES (‘Manisha’,
‘{20000, 14600, 23500, 13250}’,
‘{{“FD”, “MF”}, {“FD”, “Property”}}’);

Accessing Arrays

下面显示访问数组的示例。下面给出的命令将选择第二季度储蓄高于第四季度的那些人。

An example for accessing Arrays is shown below. The command given below will select the persons whose savings are more in second quarter than fourth quarter.

SELECT name FROM monhly_savings WHERE saving_per_quarter[2] > saving_per_quarter[4];

Modifying Arrays

下面显示修改数组的示例。

An example of modifying arrays is as shown below.

UPDATE monthly_savings SET saving_per_quarter = '{25000,25000,27000,27000}'
WHERE name = 'Manisha';

或使用 ARRAY 表达式语法 −

or using the ARRAY expression syntax −

UPDATE monthly_savings SET saving_per_quarter = ARRAY[25000,25000,27000,27000]
WHERE name = 'Manisha';

Searching Arrays

下面显示搜索数组的示例。

An example of searching arrays is as shown below.

SELECT * FROM monthly_savings WHERE saving_per_quarter[1] = 10000 OR
saving_per_quarter[2] = 10000 OR
saving_per_quarter[3] = 10000 OR
saving_per_quarter[4] = 10000;

如果数组已知的大小,则可以使用上面给出的搜索方法。否则,以下示例显示了在不知道大小的情况下如何搜索。

If the size of array is known, the search method given above can be used. Else, the following example shows how to search when the size is not known.

SELECT * FROM monthly_savings WHERE 10000 = ANY (saving_per_quarter);

Composite Types

此类型表示字段名称及其数据类型的列表,即表的行或记录的结构。

This type represents a list of field names and their data types, i.e., structure of a row or record of a table.

Declaration of Composite Types

以下示例显示如何声明复合类型

The following example shows how to declare a composite type

CREATE TYPE inventory_item AS (
   name text,
   supplier_id integer,
   price numeric
);

可以在创建表中使用此数据类型,如下所示 −

This data type can be used in the create tables as below −

CREATE TABLE on_hand (
   item inventory_item,
   count integer
);

Composite Value Input

复合值可以作为文字常量插入,将字段值括在括号内并用逗号分隔它们。示例如下所示 −

Composite values can be inserted as a literal constant, enclosing the field values within parentheses and separating them by commas. An example is shown below −

INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);

这对于上述定义的 inventory_item 有效。只要表达式中有多个字段,ROW 关键字实际上是可选的。

This is valid for the inventory_item defined above. The ROW keyword is actually optional as long as you have more than one field in the expression.

Accessing Composite Types

要访问复合列的字段,请使用一个点,后接字段名称,很像从表名中选择一个字段。例如,要从我们的 on_hand 示例表中选择一些子字段,查询如下所示 −

To access a field of a composite column, use a dot followed by the field name, much like selecting a field from a table name. For example, to select some subfields from our on_hand example table, the query would be as shown below −

SELECT (item).name FROM on_hand WHERE (item).price > 9.99;

你甚至可以使用表名(比如在多表查询中),如下所示 −

You can even use the table name as well (for instance in a multitable query), like this −

SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;

Range Types

范围类型表示使用数据范围的数据类型。范围类型可以是离散范围(例如,所有整数值 1 到 10)或连续范围(例如,上午 10:00 到上午 11:00 之间的任何时间点)。

Range types represent data types that uses a range of data. Range type can be discrete ranges (e.g., all integer values 1 to 10) or continuous ranges (e.g., any point in time between 10:00am and 11:00am).

可用的内置范围类型包括以下范围 −

The built-in range types available include the following ranges −

  1. int4range − Range of integer

  2. int8range − Range of bigint

  3. numrange − Range of numeric

  4. tsrange − Range of timestamp without time zone

  5. tstzrange − Range of timestamp with time zone

  6. daterange − Range of date

可以创建自定义范围类型以使新类型的范围可用,例如将 inet 类型用作基础的 IP 地址范围,或将 float 数据类型用作基础的 float 范围。

Custom range types can be created to make new types of ranges available, such as IP address ranges using the inet type as a base, or float ranges using the float data type as a base.

范围类型使用 [ ] 和 ( ) 字符分别支持包含和不包含的范围边界。例如,“[4,9)” 表示从 4 及其本身开始至但不到 9 的所有整数。

Range types support inclusive and exclusive range boundaries using the [ ] and ( ) characters, respectively. For example '[4,9)' represents all the integers starting from and including 4 up to but not including 9.

Object Identifier Types

对象标识符 (OID) 由 PostgreSQL 在内部用作各种系统表的初级关键字。如果指定了 WITH OIDS 或启用了 default_with_oids 配置变量,则只有在这些情况下,才将 OID 添加到用户创建的表中。下表列出多条别名类型。除了专门的输入和输出例程外,OID 别名类型没有自己的操作。

Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various system tables. If WITH OIDS is specified or default_with_oids configuration variable is enabled, only then, in such cases OIDs are added to user-created tables. The following table lists several alias types. The OID alias types have no operations of their own except for specialized input and output routines.

Name

References

Description

Value Example

oid

any

numeric object identifier

564182

regproc

pg_proc

function name

sum

regprocedure

pg_proc

function with argument types

sum(int4)

regoper

pg_operator

operator name

+

regoperator

pg_operator

operator with argument types

*(integer,integer) or -(NONE,integer)

regclass

pg_class

relation name

pg_type

regtype

pg_type

data type name

integer

regconfig

pg_ts_config

text search configuration

English

regdictionary

pg_ts_dict

text search dictionary

simple

Pseudo Types

PostgreSQL 类型系统包含许多特殊用途的条目,这些条目统称为伪类型。伪类型不能用作列数据类型,但可以用作声明函数的参数或结果类型。

The PostgreSQL type system contains a number of special-purpose entries that are collectively called pseudo-types. A pseudo-type cannot be used as a column data type, but it can be used to declare a function’s argument or result type.

下表列出了一些现有的伪类型。

The table given below lists the existing pseudo-types.

S. No.

Name & Description

1

any Indicates that a function accepts any input data type.

2

anyelement Indicates that a function accepts any data type.

3

anyarray Indicates that a function accepts any array data type.

4

anynonarray Indicates that a function accepts any non-array data type.

5

anyenum Indicates that a function accepts any enum data type.

6

anyrange Indicates that a function accepts any range data type.

7

cstring Indicates that a function accepts or returns a null-terminated C string.

8

internal Indicates that a function accepts or returns a server-internal data type.

9

language_handler A procedural language call handler is declared to return language_handler.

10

fdw_handler A foreign-data wrapper handler is declared to return fdw_handler.

11

record Identifies a function returning an unspecified row type.

12

trigger A trigger function is declared to return trigger.

13

void Indicates that a function returns no value.

PostgreSQL - CREATE Database

本章讨论如何在 PostgreSQL 中创建新数据库。PostgreSQL 提供两种创建新数据库的方法:

This chapter discusses about how to create a new database in your PostgreSQL. PostgreSQL provides two ways of creating a new database −

  1. Using CREATE DATABASE, an SQL command.

  2. Using createdb a command-line executable.

Using CREATE DATABASE

此命令将从 PostgreSQL shell 提示符创建一个数据库,但您必须具有创建数据库的适当权限。默认情况下,新数据库将通过克隆标准系统数据库模板 1 来创建。

This command will create a database from PostgreSQL shell prompt, but you should have appropriate privilege to create a database. By default, the new database will be created by cloning the standard system database template1.

Syntax

CREATE DATABASE 语句的基本语法如下:

The basic syntax of CREATE DATABASE statement is as follows −

CREATE DATABASE dbname;

其中 dbname 是要创建的数据库的名称。

where dbname is the name of a database to create.

Example

以下是一个简单的示例,它将在 PostgreSQL 架构中创建 testdb

The following is a simple example, which will create testdb in your PostgreSQL schema

postgres=# CREATE DATABASE testdb;
postgres-#

Using createdb Command

PostgreSQL 命令行可执行文件 createdb 是对 SQL 命令 CREATE DATABASE 的包装。此命令和 SQL 命令 CREATE DATABASE 之间的唯一区别在于前者可以直接从命令行运行,并且允许在一个命令中向数据库中添加注释。

PostgreSQL command line executable createdb is a wrapper around the SQL command CREATE DATABASE. The only difference between this command and SQL command CREATE DATABASE is that the former can be directly run from the command line and it allows a comment to be added into the database, all in one command.

Syntax

createdb 的语法如下所示:

The syntax for createdb is as shown below −

createdb [option...] [dbname [description]]

Parameters

下表列出了参数及其说明。

The table given below lists the parameters with their descriptions.

S. No.

Parameter & Description

1

dbname The name of a database to create.

2

description Specifies a comment to be associated with the newly created database.

3

options command-line arguments, which createdb accepts.

Options

下表列出了 createdb 可接受的命令行参数:

The following table lists the command line arguments createdb accepts −

S. No.

Option & Description

1

-D tablespace Specifies the default tablespace for the database.

2

-e Echo the commands that createdb generates and sends to the server.

3

-E encoding Specifies the character encoding scheme to be used in this database.

4

-l locale Specifies the locale to be used in this database.

5

-T template Specifies the template database from which to build this database.

6

--help Show help about createdb command line arguments, and exit.

7

-h host Specifies the host name of the machine on which the server is running.

8

-p port Specifies the TCP port or the local Unix domain socket file extension on which the server is listening for connections.

9

-U username User name to connect as.

10

-w Never issue a password prompt.

11

-W Force createdb to prompt for a password before connecting to a database.

打开命令提示符并转到PostgreSQL安装所在的目录。转到bin目录并执行以下命令来创建数据库。

Open the command prompt and go to the directory where PostgreSQL is installed. Go to the bin directory and execute the following command to create a database.

createdb -h localhost -p 5432 -U postgres testdb
password ******

给定的上面命令将提示您提供PostgreSQL管理员用户的密码,默认情况下,密码为 postgres 。因此,请提供一个密码并继续创建新数据库

The above given command will prompt you for password of the PostgreSQL admin user, which is postgres, by default. Hence, provide a password and proceed to create your new database

使用上述方法之一创建数据库后,可以使用 \l (即反斜杠el命令)按如下方式检查数据库列表:-

Once a database is created using either of the above-mentioned methods, you can check it in the list of databases using \l, i.e., backslash el command as follows −

postgres-# \l
                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges
-----------+----------+----------+---------+-------+-----------------------
 postgres  | postgres | UTF8     | C       | C     |
 template0 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
 template1 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
 testdb    | postgres | UTF8     | C       | C     |
(4 rows)

postgres-#

PostgreSQL - SELECT Database

本章介绍了访问数据库的各种方法。假定我们在上一章中已经创建了一个数据库。可以使用以下方法之一选择数据库:-

This chapter explains various methods of accessing the database. Assume that we have already created a database in our previous chapter. You can select the database using either of the following methods −

  1. Database SQL Prompt

  2. OS Command Prompt

Database SQL Prompt

假设您已经启动了PostgreSQL客户端,并且您已经登陆到以下SQL提示符:-

Assume you have already launched your PostgreSQL client and you have landed at the following SQL prompt −

postgres=#

可以使用 \l (即反斜杠el命令)按如下方式检查可用的数据库列表:-

You can check the available database list using \l, i.e., backslash el command as follows −

postgres-# \l
                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges
-----------+----------+----------+---------+-------+-----------------------
 postgres  | postgres | UTF8     | C       | C     |
 template0 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
 template1 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
 testdb    | postgres | UTF8     | C       | C     |
(4 rows)

postgres-#

现在,键入以下命令来连接/选择所需数据库;在此处,我们将连接到testdb数据库。

Now, type the following command to connect/select a desired database; here, we will connect to the testdb database.

postgres=# \c testdb;
psql (9.2.4)
Type "help" for help.
You are now connected to database "testdb" as user "postgres".
testdb=#

OS Command Prompt

您可以在登录到数据库时从命令提示符本身选择您的数据库。以下是简单的示例:-

You can select your database from the command prompt itself at the time when you login to your database. Following is a simple example −

psql -h localhost -p 5432 -U postgress testdb
Password for user postgress: ****
psql (9.2.4)
Type "help" for help.
You are now connected to database "testdb" as user "postgres".
testdb=#

您现在已登录PostgreSQL testdb,可以执行testdb内的命令。若要退出数据库,可以使用命令\q。

You are now logged into PostgreSQL testdb and ready to execute your commands inside testdb. To exit from the database, you can use the command \q.

PostgreSQL - DROP Database

在本章中,我们将讨论如何删除PostgreSQL中的数据库。有两种选择可以删除数据库:-

In this chapter, we will discuss how to delete the database in PostgreSQL. There are two options to delete a database −

  1. Using DROP DATABASE, an SQL command.

  2. Using dropdb a command-line executable.

Using DROP DATABASE

此命令删除一个数据库。它删除数据库的目录条目并删除包含数据的目录。只有数据库所有者才能执行此操作。当您或其他人连接到目标数据库时,无法执行此命令(连接到postgres或任何其他数据库来发出此命令)。

This command drops a database. It removes the catalog entries for the database and deletes the directory containing the data. It can only be executed by the database owner. This command cannot be executed while you or anyone else is connected to the target database (connect to postgres or any other database to issue this command).

Syntax

DROP DATABASE 语法如下 −

The syntax for DROP DATABASE is given below −

DROP DATABASE [ IF EXISTS ] name

Parameters

该表列出了参数及其描述。

The table lists the parameters with their descriptions.

S. No.

Parameter & Description

1

IF EXISTS Do not throw an error if the database does not exist. A notice is issued in this case.

2

name The name of the database to remove.

Example

以下是一个简单的示例,它将从 PostgreSQL 架构中删除 testdb

The following is a simple example, which will delete testdb from your PostgreSQL schema −

postgres=# DROP DATABASE testdb;
postgres-#

Using dropdb Command

PostgresSQL 命令行可执行文件 dropdb 是对 SQL 命令 DROP DATABASE 的命令行包装器。通过此实用工具和通过其他方法访问服务器来删除数据库之间没有实际差异。dropdb 摧毁了一个现有的 PostgreSQL 数据库。执行此命令的用户必须是数据库超级用户或数据库的所有者。

PostgresSQL command line executable dropdb is a command-line wrapper around the SQL command DROP DATABASE. There is no effective difference between dropping databases via this utility and via other methods for accessing the server. dropdb destroys an existing PostgreSQL database. The user, who executes this command must be a database super user or the owner of the database.

Syntax

dropdb 的语法如下所示 −

The syntax for dropdb is as shown below −

dropdb  [option...] dbname

Parameters

下表列出了参数及其描述

The following table lists the parameters with their descriptions

S. No.

Parameter & Description

1

dbname The name of a database to be deleted.

2

option command-line arguments, which dropdb accepts.

Options

下表列出了命令行参数 dropdb 接受这些参数 −

The following table lists the command-line arguments dropdb accepts −

S. No.

Option & Description

1

-e Shows the commands being sent to the server.

2

-i Issues a verification prompt before doing anything destructive.

3

-V Print the dropdb version and exit.

4

--if-exists Do not throw an error if the database does not exist. A notice is issued in this case.

5

--help Show help about dropdb command-line arguments, and exit.

6

-h host Specifies the host name of the machine on which the server is running.

7

-p port Specifies the TCP port or the local UNIX domain socket file extension on which the server is listening for connections.

8

-U username User name to connect as.

9

-w Never issue a password prompt.

10

-W Force dropdb to prompt for a password before connecting to a database.

11

--maintenance-db=dbname Specifies the name of the database to connect to in order to drop the target database.

Example

以下示例演示了从 OS 命令提示符删除一个数据库 -

The following example demonstrates deleting a database from OS command prompt −

dropdb -h localhost -p 5432 -U postgress testdb
Password for user postgress: ****

以上命令丢弃了数据库 testdb 。此处,我使用了 postgres (在 template1 的 pg_roles 下找到)用户名来丢弃数据库。

The above command drops the database testdb. Here, I have used the postgres (found under the pg_roles of template1) username to drop the database.

PostgreSQL - CREATE Table

PostgreSQL CREATE TABLE 语句用于在任何给定数据库中创建一个新表。

The PostgreSQL CREATE TABLE statement is used to create a new table in any of the given database.

Syntax

CREATE TABLE 语句的基本语法如下 -

Basic syntax of CREATE TABLE statement is as follows −

CREATE TABLE table_name(
   column1 datatype,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
   PRIMARY KEY( one or more columns )
);

CREATE TABLE 是一个关键字,它告诉数据库系统创建一个新表。表的唯一名称或标识符位于 CREATE TABLE 语句之后。最初,当前数据库中的空表归属发出该命令的用户。

CREATE TABLE is a keyword, telling the database system to create a new table. The unique name or identifier for the table follows the CREATE TABLE statement. Initially, the empty table in the current database is owned by the user issuing the command.

然后,在括号中,会有一个列表,它定义了表中的每一列以及它们是什么类型的数据。该语法将在下面给出的一个示例中明确显示。

Then, in brackets, comes the list, defining each column in the table and what sort of data type it is. The syntax will become clear with an example given below.

Examples

以下是一个示例,它创建了一个以 ID 作为主键、NOT NULL 作为约束的 COMPANY 表,指示在该表中创建记录时这些字段不能为 NULL -

The following is an example, which creates a COMPANY table with ID as primary key and NOT NULL are the constraints showing that these fields cannot be NULL while creating records in this table −

CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

让我们再创建一个将在后续章节中用于练习的表 -

Let us create one more table, which we will use in our exercises in subsequent chapters −

CREATE TABLE DEPARTMENT(
   ID INT PRIMARY KEY      NOT NULL,
   DEPT           CHAR(50) NOT NULL,
   EMP_ID         INT      NOT NULL
);

你可以使用 \d 命令来验证你的表是否已成功创建,该命令将用来列出已附加数据库中的所有表。

You can verify if your table has been created successfully using \d command, which will be used to list down all the tables in an attached database.

testdb-# \d

以上给出的 PostgreSQL 语句将产生以下结果 -

The above given PostgreSQL statement will produce the following result −

           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | company    | table | postgres
 public | department | table | postgres
(2 rows)

使用 \d tablename 来描述每个表,如下所示 -

Use \d tablename to describe each table as shown below −

testdb-# \d company

以上给出的 PostgreSQL 语句将产生以下结果 -

The above given PostgreSQL statement will produce the following result −

        Table "public.company"
  Column   |     Type      | Modifiers
-----------+---------------+-----------
 id        | integer       | not null
 name      | text          | not null
 age       | integer       | not null
 address   | character(50) |
 salary    | real          |
 join_date | date          |
Indexes:
    "company_pkey" PRIMARY KEY, btree (id)

PostgreSQL - DROP Table

PostgreSQL DROP TABLE 语句用于删除表定义以及该表的全部相关数据、索引、规则、触发器和约束。

The PostgreSQL DROP TABLE statement is used to remove a table definition and all associated data, indexes, rules, triggers, and constraints for that table.

Syntax

DROP TABLE 语句的基本语法如下 -

Basic syntax of DROP TABLE statement is as follows −

DROP TABLE table_name;

Example

我们在前一章中创建了 DEPARTMENT 和 COMPANY 表。首先,验证这些表(使用 \d 来列出这些表) -

We had created the tables DEPARTMENT and COMPANY in the previous chapter. First, verify these tables (use \d to list the tables) −

testdb-# \d

这将产生以下结果 -

This would produce the following result −

           List of relations
 Schema |    Name    | Type  |  Owner
--------+------------+-------+----------
 public | company    | table | postgres
 public | department | table | postgres
(2 rows)

这意味着 DEPARTMENT 和 COMPANY 表已存在。那么,让我们按如下方式将其丢弃 -

This means DEPARTMENT and COMPANY tables are present. So let us drop them as follows −

testdb=# drop table department, company;

这将产生以下结果 -

This would produce the following result −

DROP TABLE
testdb=# \d
relations found.
testdb=#

返回消息 DROP TABLE 指示已成功执行丢弃命令。

The message returned DROP TABLE indicates that drop command is executed successfully.

PostgreSQL - Schema

schema 是一组命名的表。架构还可以包含视图、索引、序列、数据类型、运算符和函数。架构类似于操作系统级别的目录,不同的是架构不能嵌套。PostgreSQL 语句 CREATE SCHEMA 创建了一个架构。

A schema is a named collection of tables. A schema can also contain views, indexes, sequences, data types, operators, and functions. Schemas are analogous to directories at the operating system level, except that schemas cannot be nested. PostgreSQL statement CREATE SCHEMA creates a schema.

Syntax

CREATE SCHEMA 的基本语法如下 -

The basic syntax of CREATE SCHEMA is as follows −

CREATE SCHEMA name;

其中 name 是架构的名称。

Where name is the name of the schema.

Syntax to Create Table in Schema

创建模式中的表的基本语法如下:

The basic syntax to create table in schema is as follows −

CREATE TABLE myschema.mytable (
...
);

Example

让我们看一个创建模式的示例。连接到数据库 testdb 并创建一个模式 myschema,如下所示:

Let us see an example for creating a schema. Connect to the database testdb and create a schema myschema as follows −

testdb=# create schema myschema;
CREATE SCHEMA

消息“CREATE SCHEMA”表示该模式已成功创建。

The message "CREATE SCHEMA" signifies that the schema is created successfully.

现在,让我们在上面的模式中创建一个表,如下所示:

Now, let us create a table in the above schema as follows −

testdb=# create table myschema.company(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25),
   SALARY   DECIMAL (18, 2),
   PRIMARY KEY (ID)
);

这将创建一个空表。您可以使用下面给出的命令验证已创建的表:

This will create an empty table. You can verify the table created with the command given below −

testdb=# select * from myschema.company;

这将产生以下结果 -

This would produce the following result −

 id | name | age | address | salary
----+------+-----+---------+--------
(0 rows)

Syntax to Drop Schema

要删除一个空的模式(其中的所有对象已被删除),请使用以下命令:

To drop a schema if it is empty (all objects in it have been dropped), use the command −

DROP SCHEMA myschema;

要删除一个模式,包括其中包含的所有对象,请使用以下命令:

To drop a schema including all contained objects, use the command −

DROP SCHEMA myschema CASCADE;

Advantages of using a Schema

  1. It allows many users to use one database without interfering with each other.

  2. It organizes database objects into logical groups to make them more manageable.

  3. Third-party applications can be put into separate schemas so they do not collide with the names of other objects.

PostgreSQL - INSERT Query

PostgreSQL INSERT INTO 语句允许将新行插入到表中。可以一次插入一行或作为查询结果插入多行。

The PostgreSQL INSERT INTO statement allows one to insert new rows into a table. One can insert a single row at a time or several rows as a result of a query.

Syntax

INSERT INTO 语句的基本语法如下:

Basic syntax of INSERT INTO statement is as follows −

INSERT INTO TABLE_NAME (column1, column2, column3,...columnN)
VALUES (value1, value2, value3,...valueN);
  1. Here, column1, column2,…​columnN are the names of the columns in the table into which you want to insert data.

  2. The target column names can be listed in any order. The values supplied by the VALUES clause or query are associated with the explicit or implicit column list left-to-right.

如果您要为表的所有列添加值,则不必在 SQL 查询中指定列名称。但是,确保值的顺序与表中的列顺序相同。SQL INSERT INTO 语法如下:

You may not need to specify the column(s) name in the SQL query if you are adding values for all the columns of the table. However, make sure the order of the values is in the same order as the columns in the table. The SQL INSERT INTO syntax would be as follows −

INSERT INTO TABLE_NAME VALUES (value1,value2,value3,...valueN);

Output

下表总结了输出消息及其含义:

The following table summarizes the output messages and their meaning −

S. No.

Output Message & Description

1

INSERT oid 1 Message returned if only one row was inserted. oid is the numeric OID of the inserted row.

2

INSERT 0 # Message returned if more than one rows were inserted. # is the number of rows inserted.

Examples

让我们在 testdb 中创建 COMPANY 表,如下所示:

Let us create COMPANY table in testdb as follows −

CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL,
   JOIN_DATE	  DATE
);

以下示例将一行插入到 COMPANY 表中:

The following example inserts a row into the COMPANY table −

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (1, 'Paul', 32, 'California', 20000.00,'2001-07-13');

以下示例是插入一行;此处省略了薪酬列,因此它将具有默认值 −

The following example is to insert a row; here salary column is omitted and therefore it will have the default value −

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,JOIN_DATE) VALUES (2, 'Allen', 25, 'Texas', '2007-12-13');

以下示例对 JOIN_DATE 列使用 DEFAULT 子句,而不是指定一个值 −

The following example uses the DEFAULT clause for the JOIN_DATE column rather than specifying a value −

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (3, 'Teddy', 23, 'Norway', 20000.00, DEFAULT );

以下示例使用多行 VALUES 语法插入多行 −

The following example inserts multiple rows using the multirow VALUES syntax −

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00, '2007-12-13' ), (5, 'David', 27, 'Texas', 85000.00, '2007-12-13');

以上所有语句都会在 COMPANY 表中创建以下记录。下一章将会教你如何从表中显示所有这些记录。

All the above statements would create the following records in COMPANY table. The next chapter will teach you how to display all these records from a table.

ID        NAME        AGE        ADDRESS     SALARY	  JOIN_DATE
----      ----------  -----      ----------  -------      --------
1         Paul        32         California  20000.0      2001-07-13
2         Allen       25         Texas                    2007-12-13
3         Teddy       23         Norway      20000.0
4         Mark        25         Rich-Mond   65000.0      2007-12-13
5         David       27         Texas       85000.0      2007-12-13

PostgreSQL - SELECT Query

PostgreSQL SELECT 语句用于从数据库表中提取数据,它以结果表的形式返回数据。这些结果表称为结果集。

PostgreSQL SELECT statement is used to fetch the data from a database table, which returns data in the form of result table. These result tables are called result-sets.

Syntax

SELECT 语句的基本语法如下所示:

The basic syntax of SELECT statement is as follows −

SELECT column1, column2, columnN FROM table_name;

此处,column1、column2…​是你要提取其值的表的字段。如果你想提取字段中存在的所有字段,那么可以使用以下语法 −

Here, column1, column2…​are the fields of a table, whose values you want to fetch. If you want to fetch all the fields available in the field then you can use the following syntax −

SELECT * FROM table_name;

Example

考虑 COMPANY 表具有以下记录:

Consider the table COMPANY having records as follows −

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

以下是一个示例,它将提取 CUSTOMERS 表中存在的客户的 ID、姓名和薪酬字段 −

The following is an example, which would fetch ID, Name and Salary fields of the customers available in CUSTOMERS table −

testdb=# SELECT ID, NAME, SALARY FROM COMPANY ;

这将产生以下结果 -

This would produce the following result −

  id | name  | salary
 ----+-------+--------
   1 | Paul  |  20000
   2 | Allen |  15000
   3 | Teddy |  20000
   4 | Mark  |  65000
   5 | David |  85000
   6 | Kim   |  45000
   7 | James |  10000
(7 rows)

如果你想提取 CUSTOMERS 表的所有字段,那么使用以下查询 −

If you want to fetch all the fields of CUSTOMERS table, then use the following query −

testdb=# SELECT * FROM COMPANY;

这将产生以下结果 -

This would produce the following result −

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

PostgreSQL - Operators

What is an Operator in PostgreSQL?

运算符是保留字或主要用于 PostgreSQL 语句的 WHERE 子句中的字符,用于执行运算(例如,比较和数学运算)。

An operator is a reserved word or a character used primarily in a PostgreSQL statement’s WHERE clause to perform operation(s), such as comparisons and arithmetic operations.

运算符用于指定 PostgreSQL 语句中的条件,并作为语句中多个条件的合取。

Operators are used to specify conditions in a PostgreSQL statement and to serve as conjunctions for multiple conditions in a statement.

  1. Arithmetic operators

  2. Comparison operators

  3. Logical operators

  4. Bitwise operators

PostgreSQL Arithmetic Operators

假设变量 a 存储 2,变量 b 存储 3,那么 −

Assume variable a holds 2 and variable b holds 3, then −

Operator

Description

Example

+

Addition - Adds values on either side of the operator

a + b will give 5

-

Subtraction - Subtracts right hand operand from left hand operand

a - b will give -1

*

Multiplication - Multiplies values on either side of the operator

a * b will give 6

/

Division - Divides left hand operand by right hand operand

b / a will give 1

%

Modulus - Divides left hand operand by right hand operand and returns remainder

b % a will give 1

^

Exponentiation - This gives the exponent value of the right hand operand

a ^ b will give 8

/

square root

/ 25.0 will give 5

/

Cube root

/ 27.0 will give 3

!

factorial

5 ! will give 120

!!

factorial (prefix operator)

!! 5 will give 120

PostgreSQL Comparison Operators

假设变量 a 等于 10,变量 b 等于 20,则 −

Assume variable a holds 10 and variable b holds 20, then −

Operator

Description

Example

=

Checks if the values of two operands are equal or not, if yes then condition becomes true.

(a = b) is not true.

!=

Checks if the values of two operands are equal or not, if values are not equal then condition becomes true.

(a != b) is true.

<>

Checks if the values of two operands are equal or not, if values are not equal then condition becomes true.

(a <> b) is true.

>

Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.

(a > b) is not true.

<

Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.

(a < b) is true.

>=

Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.

(a >= b) is not true.

Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.

(a ⇐ b) is true.

PostgreSQL Logical Operators

以下是 PostgresSQL 中所有可用的逻辑运算符列表。

Here is a list of all the logical operators available in PostgresSQL.

S. No.

Operator & Description

1

AND The AND operator allows the existence of multiple conditions in a PostgresSQL statement’s WHERE clause.

2

NOT The NOT operator reverses the meaning of the logical operator with which it is used. Eg. NOT EXISTS, NOT BETWEEN, NOT IN etc. This is negate operator.

3

OR The OR operator is used to combine multiple conditions in a PostgresSQL statement’s WHERE clause.

PostgreSQL Bit String Operators

按位运算符处理位,并执行逐位运算。& 和 | 的真值表如下 −

Bitwise operator works on bits and performs bit-by-bit operation. The truth table for & and | is as follows −

p

q

p &

p

q

0

0

0

0

0

1

0

1

1

1

1

1

1

0

0

假设如果 A = 60;并且 B = 13;现在以二进制格式,它们将如下所示 −

Assume if A = 60; and B = 13; now in binary format they will be as follows −

A = 0011 1100

B = 0000 1101

A&B = 0000 1100

A|B = 0011 1101

~A  = 1100 0011

link:../postgresql/postgresql_bitwise-operators.html[Show Examples]

The Bitwise operators supported by PostgreSQL are listed in the following table −
[%autowidth]
|===

|Operator|Description|Example
|&|Binary AND Operator copies a bit to the result if it exists in both operands.|(A & B) will give 12 which is 0000 1100
|||Binary OR Operator copies a bit if it exists in either operand.|(A | B) will give 61 which is 0011 1101
|~|Binary Ones Complement Operator is unary and has the effect of 'flipping' bits.|(~A ) will give -61 which is 1100 0011 in 2's complement form due to a signed binary number.
|<<|Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.|A << 2 will give 240 which is 1111 0000
|>>|Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.|A >> 2 will give 15 which is 0000 1111
|#|bitwise XOR.|A # B will give 49 which is 00110001
|===


== PostgreSQL - Expressions

An expression is a combination of one or more values, operators, and PostgresSQL functions that evaluate to a value.

PostgreSQL EXPRESSIONS are like formulas and they are written in query language. You can also use to query the database for specific set of data.


==== Syntax

Consider the basic syntax of the SELECT statement as follows −

[source]

SELECT column1, column2, columnN FROM table_name WHERE [CONDITION | EXPRESSION];

There are different types of PostgreSQL expressions, which are mentioned below −


=== PostgreSQL - Boolean Expressions

PostgreSQL Boolean Expressions fetch the data on the basis of matching single value. Following is the syntax −

[source]

SELECT column1, column2, columnN FROM table_name WHERE SINGLE VALUE MATCHTING EXPRESSION;

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]

testdb# select * from COMPANY; id | name | age | address | salary ----------------------------------- 1 | Paul | 32 | California| 20000 2 | Allen | 25 | Texas | 15000 3 | Teddy | 23 | Norway | 20000 4 | Mark | 25 | Rich-Mond | 65000 5 | David | 27 | Texas | 85000 6 | Kim | 22 | South-Hall| 45000 7 | James | 24 | Houston | 10000 (7 rows)

Here is the simple example showing usage of PostgreSQL Boolean Expressions −

[source]

testdb=# SELECT * FROM COMPANY WHERE SALARY = 10000;

The above given PostgreSQL statement will produce the following result −

[source]
 id | name  | age | address  | salary
----+-------+-----+----------+--------
  7 | James |  24 | Houston  |  10000
(1 row)
=== PostgreSQL - Numeric Expression

These expressions are used to perform any mathematical operation in any query. Following is the syntax −

[source]

SELECT numerical_expression as OPERATION_NAME [FROM table_name WHERE CONDITION] ;

Here numerical_expression is used for mathematical expression or any formula. Following is a simple example showing usage of SQL Numeric Expressions −

[source]

testdb=# SELECT (15 + 6) AS ADDITION ;

The above given PostgreSQL statement will produce the following result −

[source]

addition

       21
(1 row)
There are several built-in functions like avg(), sum(), count() to perform what is known as aggregate data calculations against a table or a specific table column.

[source]

testdb=# SELECT COUNT(*) AS "RECORDS" FROM COMPANY;

The above given PostgreSQL statement will produce the following result −

[source]

RECORDS

       7
(1 row)
=== PostgreSQL - Date Expressions

Date Expressions return the current system date and time values and these expressions are used in various data manipulations.

[source]

testdb=# SELECT CURRENT_TIMESTAMP;

The above given PostgreSQL statement will produce the following result −

[source]
now
 2013-05-06 14:38:28.078+05:30
(1 row)

----


== PostgreSQL - WHERE Clause

The PostgreSQL WHERE clause is used to specify a condition while fetching the data from single table or joining with multiple tables.

If the given condition is satisfied, only then it returns specific value from the table. You can filter out rows that you do not want included in the result-set by using the WHERE clause.

The WHERE clause not only is used in SELECT statement, but it is also used in UPDATE, DELETE statement, etc., which we would examine in subsequent chapters.


=== Syntax

The basic syntax of SELECT statement with WHERE clause is as follows −

[source]
----
SELECT column1, column2, columnN
FROM table_name
WHERE [search_condition]

----

You can specify a search_condition using link:../postgresql/postgresql_operators.html[comparison or logical operators.] like >, <, =, LIKE, NOT, etc. The following examples would make this concept clear.


=== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

Here are simple examples showing usage of PostgreSQL Logical Operators. Following SELECT statement will list down all the records where AGE is greater than or equal to 25 *AND* salary is greater than or equal to 65000.00 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age |  address   | salary
----+-------+-----+------------+--------
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
(2 rows)

----

The following SELECT statement lists down all the records where AGE is greater than or equal to 25 *OR* salary is greater than or equal to 65000.00 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE >= 25 OR SALARY >= 65000;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  1 | Paul  |  32 | California  |  20000
  2 | Allen |  25 | Texas       |  15000
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
(4 rows)

----

The following SELECT statement lists down all the records where AGE is not NULL which means all the records, because none of the record has AGE equal to NULL −

[source]
----
testdb=#  SELECT * FROM COMPANY WHERE AGE IS NOT NULL;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
  id | name  | age | address    | salary
 ----+-------+-----+------------+--------
   1 | Paul  |  32 | California |  20000
   2 | Allen |  25 | Texas      |  15000
   3 | Teddy |  23 | Norway     |  20000
   4 | Mark  |  25 | Rich-Mond  |  65000
   5 | David |  27 | Texas      |  85000
   6 | Kim   |  22 | South-Hall |  45000
   7 | James |  24 | Houston    |  10000
(7 rows)

----

The following SELECT statement lists down all the records where NAME starts with 'Pa', does not matter what comes after 'Pa'.

[source]
----
testdb=# SELECT * FROM COMPANY WHERE NAME LIKE 'Pa%';

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name | age |address    | salary
----+------+-----+-----------+--------
  1 | Paul |  32 | California|  20000

----

The following SELECT statement lists down all the records where AGE value is either 25 or 27 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE IN ( 25, 27 );

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  2 | Allen |  25 | Texas      |  15000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
(3 rows)

----

The following SELECT statement lists down all the records where AGE value is neither 25 nor 27 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE NOT IN ( 25, 27 );

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  3 | Teddy |  23 | Norway     |  20000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000
(4 rows)

----

The following SELECT statement lists down all the records where AGE value is in BETWEEN 25 AND 27 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE BETWEEN 25 AND 27;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  2 | Allen |  25 | Texas      |  15000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
(3 rows)

----

The following SELECT statement makes use of SQL subquery where subquery finds all the records with AGE field having SALARY > 65000 and later WHERE clause is being used along with EXISTS operator to list down all the records where AGE from the outside query exists in the result returned by sub-query −

[source]
----
testdb=# SELECT AGE FROM COMPANY
        WHERE EXISTS (SELECT AGE FROM COMPANY WHERE SALARY > 65000);

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 age
-----
  32
  25
  23
  25
  27
  22
  24
(7 rows)

----

The following SELECT statement makes use of SQL subquery where subquery finds all the records with AGE field having SALARY > 65000 and later WHERE clause is being used along with > operator to list down all the records where AGE from outside query is greater than the age in the result returned by sub-query −

[source]
----
testdb=# SELECT * FROM COMPANY
        WHERE AGE > (SELECT AGE FROM COMPANY WHERE SALARY > 65000);

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name | age | address    | salary
----+------+-----+------------+--------
  1 | Paul |  32 | California |  20000

----


== AND and OR Conjunctive Operators

The PostgreSQL *AND* and *OR* operators are used to combine multiple conditions to narrow down selected data in a PostgreSQL statement. These two operators are called conjunctive operators.

These operators provide a means to make multiple comparisons with different operators in the same PostgreSQL statement.


=== The AND Operator

The *AND* operator allows the existence of multiple conditions in a PostgreSQL statement's WHERE clause. While using AND operator, complete condition will be assumed true when all the conditions are true. For example [condition1] AND [condition2] will be true only when both condition1 and condition2 are true.


==== Syntax

The basic syntax of AND operator with WHERE clause is as follows −

[source]
----
SELECT column1, column2, columnN
FROM table_name
WHERE [condition1] AND [condition2]...AND [conditionN];

----

You can combine N number of conditions using AND operator. For an action to be taken by the PostgreSQL statement, whether it be a transaction or query, all conditions separated by the AND must be TRUE.


==== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following SELECT statement lists down all the records where AGE is greater than or equal to 25 *AND* salary is greater than or equal to 65000.00 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE >= 25 AND SALARY >= 65000;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
(2 rows)

----


=== The OR Operator

The OR operator is also used to combine multiple conditions in a PostgreSQL statement's WHERE clause. While using OR operator, complete condition will be assumed true when at least any of the conditions is true. For example [condition1] OR [condition2] will be true if either condition1 or condition2 is true.


==== Syntax

The basic syntax of OR operator with WHERE clause is as follows −

[source]
----
SELECT column1, column2, columnN
FROM table_name
WHERE [condition1] OR [condition2]...OR [conditionN]

----

You can combine N number of conditions using OR operator. For an action to be taken by the PostgreSQL statement, whether it be a transaction or query, only any ONE of the conditions separated by the OR must be TRUE.


==== Example

Consider the link:../postgresql/company.sql[COMPANY] table, having the following records −

[source]
----
 # select * from COMPANY;
  id | name  | age | address   | salary
 ----+-------+-----+-----------+--------
   1 | Paul  |  32 | California|  20000
   2 | Allen |  25 | Texas     |  15000
   3 | Teddy |  23 | Norway    |  20000
   4 | Mark  |  25 | Rich-Mond |  65000
   5 | David |  27 | Texas     |  85000
   6 | Kim   |  22 | South-Hall|  45000
   7 | James |  24 | Houston   |  10000
(7 rows)

----

The following SELECT statement lists down all the records where AGE is greater than or equal to 25 *OR* salary is greater than or equal to 65000.00 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE >= 25 OR SALARY >= 65000;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
(4 rows)

----


== PostgreSQL - UPDATE Query

The PostgreSQL *UPDATE* Query is used to modify the existing records in a table. You can use WHERE clause with UPDATE query to update the selected rows. Otherwise, all the rows would be updated.


=== Syntax

The basic syntax of UPDATE query with WHERE clause is as follows −

[source]
----
UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];

----

You can combine N number of conditions using AND or OR operators.


=== Example

Consider the table link:../postgresql/company.sql[COMPANY], having records as follows −

[source]
----
testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following is an example, which would update ADDRESS for a customer, whose ID is 6 −

[source]
----
testdb=# UPDATE COMPANY SET SALARY = 15000 WHERE ID = 3;

----

Now, COMPANY table would have the following records −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000
  3 | Teddy |  23 | Norway     |  15000
(7 rows)

----

If you want to modify all ADDRESS and SALARY column values in COMPANY table, you do not need to use WHERE clause and UPDATE query would be as follows −

[source]
----
testdb=# UPDATE COMPANY SET ADDRESS = 'Texas', SALARY=20000;

----

Now, COMPANY table will have the following records −

[source]
----
 id | name  | age | address | salary
----+-------+-----+---------+--------
  1 | Paul  |  32 | Texas   |  20000
  2 | Allen |  25 | Texas   |  20000
  4 | Mark  |  25 | Texas   |  20000
  5 | David |  27 | Texas   |  20000
  6 | Kim   |  22 | Texas   |  20000
  7 | James |  24 | Texas   |  20000
  3 | Teddy |  23 | Texas   |  20000
(7 rows)

----


== PostgreSQL - DELETE Query

The PostgreSQL *DELETE* Query is used to delete the existing records from a table. You can use WHERE clause with DELETE query to delete the selected rows. Otherwise, all the records would be deleted.


=== Syntax

The basic syntax of DELETE query with WHERE clause is as follows −

[source]
----
DELETE FROM table_name
WHERE [condition];

----

You can combine N number of conditions using AND or OR operators.


=== Example

Consider the table link:../postgresql/company.sql[COMPANY], having records as follows −

[source]
----
# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following is an example, which would DELETE a customer whose ID is 7 −

[source]
----
testdb=# DELETE FROM COMPANY WHERE ID = 2;

----

Now, COMPANY table will have the following records −

[source]
----
 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  1 | Paul  |  32 | California  |  20000
  3 | Teddy |  23 | Norway      |  20000
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
  6 | Kim   |  22 | South-Hall  |  45000
  7 | James |  24 | Houston     |  10000
(6 rows)

----

If you want to DELETE all the records from COMPANY table, you do not need to use WHERE clause with DELETE queries, which would be as follows −

[source]
----
testdb=# DELETE FROM COMPANY;

----

Now, COMPANY table does not have any record because all the records have been deleted by the DELETE statement.


== PostgreSQL - LIKE Clause

The PostgreSQL *LIKE* operator is used to match text values against a pattern using wildcards. If the search expression can be matched to the pattern expression, the LIKE operator will return true, which is *1*.

There are two wildcards used in conjunction with the LIKE operator −

. The percent sign (%)

. The underscore (_)

The percent sign represents zero, one, or multiple numbers or characters. The underscore represents a single number or character. These symbols can be used in combinations.

If either of these two signs is not used in conjunction with the LIKE clause, then the LIKE acts like the equals operator.


=== Syntax

The basic syntax of % and _ is as follows −

[source]
----
SELECT FROM table_name
WHERE column LIKE 'XXXX%'

or

SELECT FROM table_name
WHERE column LIKE '%XXXX%'

or

SELECT FROM table_name
WHERE column LIKE 'XXXX_'

or

SELECT FROM table_name
WHERE column LIKE '_XXXX'

or

SELECT FROM table_name
WHERE column LIKE '_XXXX_'

----

You can combine N number of conditions using AND or OR operators. Here XXXX could be any numeric or string value.


=== Example

Here are number of examples showing WHERE part having different LIKE clause with '%' and '_' operators −
[%autowidth]
|===

|S. No.|Statement & Description
|1|*WHERE SALARY::text LIKE '200%'*
Finds any values that start with 200

|2|*WHERE SALARY::text LIKE '%200%'*
Finds any values that have 200 in any position

|3|*WHERE SALARY::text LIKE '_00%'*
Finds any values that have 00 in the second and third positions

|4|*WHERE SALARY::text LIKE '2_%_%'*
Finds any values that start with 2 and are at least 3 characters in length

|5|*WHERE SALARY::text LIKE '%2'*
Finds any values that end with 2

|6|*WHERE SALARY::text LIKE '_2%3'*
Finds any values that have 2 in the second position and end with a 3

|7|*WHERE SALARY::text LIKE '2___3'*
Finds any values in a five-digit number that start with 2 and end with 3

|===

Let us take a real example, consider the table link:../postgresql/company.sql[COMPANY], having records as follows −

[source]
----
# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following is an example, which would display all the records from COMPANY table where AGE starts with 2 −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE AGE::text LIKE '2%';

----

This would produce the following result −

[source]
----
 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  2 | Allen |  25 | Texas       |  15000
  3 | Teddy |  23 | Norway      |  20000
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
  6 | Kim   |  22 | South-Hall  |  45000
  7 | James |  24 | Houston     |  10000
  8 | Paul  |  24 | Houston     |  20000
(7 rows)

----

The following is an example, which would display all the records from COMPANY table where ADDRESS will have a hyphen (-) inside the text −

[source]
----
testdb=# SELECT * FROM COMPANY WHERE ADDRESS  LIKE '%-%';

----

This would produce the following result −

[source]
----
 id | name | age |                      address              | salary
----+------+-----+-------------------------------------------+--------
  4 | Mark |  25 | Rich-Mond                                 |  65000
  6 | Kim  |  22 | South-Hall                                |  45000
(2 rows)

----


== PostgreSQL - LIMIT Clause

The PostgreSQL *LIMIT* clause is used to limit the data amount returned by the SELECT statement.


=== Syntax

The basic syntax of SELECT statement with LIMIT clause is as follows −

[source]
----
SELECT column1, column2, columnN
FROM table_name
LIMIT [no of rows]

----

The following is the syntax of LIMIT clause when it is used along with OFFSET clause −

[source]
----
SELECT column1, column2, columnN
FROM table_name
LIMIT [no of rows] OFFSET [row num]

----

LIMIT and OFFSET allow you to retrieve just a portion of the rows that are generated by the rest of the query.


=== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following is an example, which limits the row in the table according to the number of rows you want to fetch from table −

[source]
----
testdb=# SELECT * FROM COMPANY LIMIT 4;

----

This would produce the following result −

[source]
----
 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  1 | Paul  |  32 | California  |  20000
  2 | Allen |  25 | Texas       |  15000
  3 | Teddy |  23 | Norway      |  20000
  4 | Mark  |  25 | Rich-Mond   |  65000
(4 rows)

----

However, in certain situation, you may need to pick up a set of records from a particular offset. Here is an example, which picks up three records starting from the third position −

[source]
----
testdb=# SELECT * FROM COMPANY LIMIT 3 OFFSET 2;

----

This would produce the following result −

[source]
----
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
(3 rows)

----


== PostgreSQL - ORDER BY Clause

The PostgreSQL *ORDER BY* clause is used to sort the data in ascending or descending order, based on one or more columns.


=== Syntax

The basic syntax of ORDER BY clause is as follows −

[source]
----
SELECT column-list
FROM table_name
[WHERE condition]
[ORDER BY column1, column2, .. columnN] [ASC | DESC];

----

You can use more than one column in the ORDER BY clause. Make sure whatever column you are using to sort, that column should be available in column-list.


=== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following is an example, which would sort the result in ascending order by SALARY −

[source]
----
testdb=# SELECT * FROM COMPANY ORDER BY AGE ASC;

----

This would produce the following result −

[source]
----
  id | name  | age | address    | salary
 ----+-------+-----+------------+--------
   6 | Kim   |  22 | South-Hall |  45000
   3 | Teddy |  23 | Norway     |  20000
   7 | James |  24 | Houston    |  10000
   8 | Paul  |  24 | Houston    |  20000
   4 | Mark  |  25 | Rich-Mond  |  65000
   2 | Allen |  25 | Texas      |  15000
   5 | David |  27 | Texas      |  85000
   1 | Paul  |  32 | California |  20000
   9 | James |  44 | Norway     |   5000
  10 | James |  45 | Texas      |   5000
(10 rows)

----

The following is an example, which would sort the result in ascending order by NAME and SALARY −

[source]
----
testdb=# SELECT * FROM COMPANY ORDER BY NAME, SALARY ASC;

----

This would produce the following result −

[source]
----
 id | name  | age | address      | salary
----+-------+-----+--------------+--------
  2 | Allen |  25 | Texas        |  15000
  5 | David |  27 | Texas        |  85000
 10 | James |  45 | Texas        |   5000
  9 | James |  44 | Norway       |   5000
  7 | James |  24 | Houston      |  10000
  6 | Kim   |  22 | South-Hall   |  45000
  4 | Mark  |  25 | Rich-Mond    |  65000
  1 | Paul  |  32 | California   |  20000
  8 | Paul  |  24 | Houston      |  20000
  3 | Teddy |  23 | Norway       |  20000
(10 rows)

----

The following is an example, which would sort the result in descending order by NAME −

[source]
----
testdb=# SELECT * FROM COMPANY ORDER BY NAME DESC;

----

This would produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  3 | Teddy |  23 | Norway     |  20000
  1 | Paul  |  32 | California |  20000
  8 | Paul  |  24 | Houston    |  20000
  4 | Mark  |  25 | Rich-Mond  |  65000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000
  9 | James |  44 | Norway     |   5000
 10 | James |  45 | Texas      |   5000
  5 | David |  27 | Texas      |  85000
  2 | Allen |  25 | Texas      |  15000
(10 rows)

----


== PostgreSQL - GROUP BY

The PostgreSQL *GROUP BY* clause is used in collaboration with the SELECT statement to group together those rows in a table that have identical data. This is done to eliminate redundancy in the output and/or compute aggregates that apply to these groups.

The GROUP BY clause follows the WHERE clause in a SELECT statement and precedes the ORDER BY clause.


=== Syntax

The basic syntax of GROUP BY clause is given below. The GROUP BY clause must follow the conditions in the WHERE clause and must precede the ORDER BY clause if one is used.

[source]
----
SELECT column-list
FROM table_name
WHERE [ conditions ]
GROUP BY column1, column2....columnN
ORDER BY column1, column2....columnN

----

You can use more than one column in the GROUP BY clause. Make sure whatever column you are using to group, that column should be available in column-list.


=== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

If you want to know the total amount of salary of each customer, then GROUP BY query would be as follows −

[source]
----
testdb=# SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME;

----

This would produce the following result −

[source]
----
  name  |  sum
 -------+-------
  Teddy | 20000
  Paul  | 20000
  Mark  | 65000
  David | 85000
  Allen | 15000
  Kim   | 45000
  James | 10000
(7 rows)

----

Now, let us create three more records in COMPANY table using the following INSERT statements −

[source]
----
INSERT INTO COMPANY VALUES (8, 'Paul', 24, 'Houston', 20000.00);
INSERT INTO COMPANY VALUES (9, 'James', 44, 'Norway', 5000.00);
INSERT INTO COMPANY VALUES (10, 'James', 45, 'Texas', 5000.00);

----

Now, our table has the following records with duplicate names −

[source]
----
  id | name  | age | address      | salary
 ----+-------+-----+--------------+--------
   1 | Paul  |  32 | California   |  20000
   2 | Allen |  25 | Texas        |  15000
   3 | Teddy |  23 | Norway       |  20000
   4 | Mark  |  25 | Rich-Mond    |  65000
   5 | David |  27 | Texas        |  85000
   6 | Kim   |  22 | South-Hall   |  45000
   7 | James |  24 | Houston      |  10000
   8 | Paul  |  24 | Houston      |  20000
   9 | James |  44 | Norway       |   5000
  10 | James |  45 | Texas        |   5000
(10 rows)

----

Again, let us use the same statement to group-by all the records using NAME column as follows −

[source]
----
testdb=# SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME;

----

This would produce the following result −

[source]
----
 name  |  sum
-------+-------
 Allen | 15000
 David | 85000
 James | 20000
 Kim   | 45000
 Mark  | 65000
 Paul  | 40000
 Teddy | 20000
(7 rows)

----

Let us use ORDER BY clause along with GROUP BY clause as follows −

[source]
----
testdb=#  SELECT NAME, SUM(SALARY)
         FROM COMPANY GROUP BY NAME ORDER BY NAME DESC;

----

This would produce the following result −

[source]
----
 name  |  sum
-------+-------
 Teddy | 20000
 Paul  | 40000
 Mark  | 65000
 Kim   | 45000
 James | 20000
 David | 85000
 Allen | 15000
(7 rows)

----


== PostgreSQL - WITH Clause

In PostgreSQL, the WITH query provides a way to write auxiliary statements for use in a larger query. It helps in breaking down complicated and large queries into simpler forms, which are easily readable. These statements often referred to as Common Table Expressions or CTEs, can be thought of as defining temporary tables that exist just for one query.

The WITH query being CTE query, is particularly useful when subquery is executed multiple times. It is equally helpful in place of temporary tables. It computes the aggregation once and allows us to reference it by its name (may be multiple times) in the queries.

The WITH clause must be defined before it is used in the query.


==== Syntax

The basic syntax of WITH query is as follows −

[source]
----
WITH
   name_for_summary_data AS (
      SELECT Statement)
   SELECT columns
   FROM name_for_summary_data
   WHERE conditions <=> (
      SELECT column
      FROM name_for_summary_data)
   [ORDER BY columns]

----

Where name_for_summary_data is the name given to the WITH clause. The name_for_summary_data can be the same as an existing table name and will take precedence.

You can use data-modifying statements (INSERT, UPDATE or DELETE) in WITH. This allows you to perform several different operations in the same query.


=== Recursive WITH


==== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

Now, let us write a query using the WITH clause to select the records from the above table, as follows −

[source]
----
With CTE AS
(Select
 ID
, NAME
, AGE
, ADDRESS
, SALARY
FROM COMPANY )
Select * From CTE;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

Now, let us write a query using the RECURSIVE keyword along with the WITH clause, to find the sum of the salaries less than 20000, as follows −

[source]
----
WITH RECURSIVE t(n) AS (
   VALUES (0)
   UNION ALL
   SELECT SALARY FROM COMPANY WHERE SALARY < 20000
)
SELECT sum(n) FROM t;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
  sum
-------
 25000
(1 row)

----

Let us write a query using data modifying statements along with the WITH clause, as shown below.

First, create a table COMPANY1 similar to the table COMPANY. The query in the example effectively moves rows from COMPANY to COMPANY1. The DELETE in WITH deletes the specified rows from COMPANY, returning their contents by means of its RETURNING clause; and then the primary query reads that output and inserts it into COMPANY1 TABLE −

[source]
----
CREATE TABLE COMPANY1(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

WITH moved_rows AS (
   DELETE FROM COMPANY
   WHERE
      SALARY >= 30000
   RETURNING *
)
INSERT INTO COMPANY1 (SELECT * FROM moved_rows);

----

The above given PostgreSQL statement will produce the following result −

[source]
----
INSERT 0 3

----

Now, the records in the tables COMPANY and COMPANY1 are as follows −

[source]
----
testdb=# SELECT * FROM COMPANY;
 id | name  | age |  address   | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  7 | James |  24 | Houston    |  10000
(4 rows)


testdb=# SELECT * FROM COMPANY1;
 id | name  | age | address | salary
----+-------+-----+-------------+--------
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
  6 | Kim   |  22 | South-Hall  |  45000
(3 rows)

----


== PostgreSQL - HAVING Clause

The HAVING clause allows us to pick out particular rows where the function's result meets some condition.

The WHERE clause places conditions on the selected columns, whereas the HAVING clause places conditions on groups created by the GROUP BY clause.


=== Syntax

The following is the position of the HAVING clause in a SELECT query −

[source]
----
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY

----

The HAVING clause must follow the GROUP BY clause in a query and must also precede the ORDER BY clause if used. The following is the syntax of the SELECT statement, including the HAVING clause −

[source]
----
SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2

----


=== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

The following is an example, which would display record for which the name count is less than 2 −

[source]
----
testdb-# SELECT NAME FROM COMPANY GROUP BY name HAVING count(name) < 2;

----

This would produce the following result −

[source]
----
  name
 -------
  Teddy
  Paul
  Mark
  David
  Allen
  Kim
  James
(7 rows)

----

Now, let us create three more records in COMPANY table using the following INSERT statements −

[source]
----
INSERT INTO COMPANY VALUES (8, 'Paul', 24, 'Houston', 20000.00);
INSERT INTO COMPANY VALUES (9, 'James', 44, 'Norway', 5000.00);
INSERT INTO COMPANY VALUES (10, 'James', 45, 'Texas', 5000.00);

----

Now, our table has the following records with duplicate names −

[source]
----
  id | name  | age | address      | salary
 ----+-------+-----+--------------+--------
   1 | Paul  |  32 | California   |  20000
   2 | Allen |  25 | Texas        |  15000
   3 | Teddy |  23 | Norway       |  20000
   4 | Mark  |  25 | Rich-Mond    |  65000
   5 | David |  27 | Texas        |  85000
   6 | Kim   |  22 | South-Hall   |  45000
   7 | James |  24 | Houston      |  10000
   8 | Paul  |  24 | Houston      |  20000
   9 | James |  44 | Norway       |   5000
  10 | James |  45 | Texas        |   5000
(10 rows)

----

The following is the example, which would display record for which the name count is greater than 1 −

[source]
----
testdb-# SELECT NAME FROM COMPANY GROUP BY name HAVING count(name) > 1;

----

This would produce the following result −

[source]
----
 name
-------
 Paul
 James
(2 rows)

----


== PostgreSQL - DISTINCT Keyword

The PostgreSQL *DISTINCT* keyword is used in conjunction with SELECT statement to eliminate all the duplicate records and fetching only unique records.

There may be a situation when you have multiple duplicate records in a table. While fetching such records, it makes more sense to fetch only unique records instead of fetching duplicate records.


=== Syntax

The basic syntax of DISTINCT keyword to eliminate duplicate records is as follows −

[source]
----
SELECT DISTINCT column1, column2,.....columnN
FROM table_name
WHERE [condition]

----


=== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----
# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

Let us add two more records to this table as follows −

[source]
----
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (8, 'Paul', 32, 'California', 20000.00 );

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (9, 'Allen', 25, 'Texas', 15000.00 );

----

Now, the records in the COMPANY table would be −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000
  8 | Paul  |  32 | California |  20000
  9 | Allen |  25 | Texas      |  15000
(9 rows)

----

First, let us see how the following SELECT query returns duplicate salary records −

[source]
----
testdb=# SELECT name FROM COMPANY;

----

This would produce the following result −

[source]
----
 name
-------
 Paul
 Allen
 Teddy
 Mark
 David
 Kim
 James
 Paul
 Allen
(9 rows)

----

Now, let us use *DISTINCT* keyword with the above SELECT query and see the result −

[source]
----
testdb=# SELECT DISTINCT name FROM COMPANY;

----

This would produce the following result where we do not have any duplicate entry −

[source]
----
 name
-------
 Teddy
 Paul
 Mark
 David
 Allen
 Kim
 James
(7 rows)

----


== PostgreSQL - CONSTRAINTS

Constraints are the rules enforced on data columns on table. These are used to prevent invalid data from being entered into the database. This ensures the accuracy and reliability of the data in the database.

Constraints could be column level or table level. Column level constraints are applied only to one column whereas table level constraints are applied to the whole table. Defining a data type for a column is a constraint in itself. For example, a column of type DATE constrains the column to valid dates.

The following are commonly used constraints available in PostgreSQL.

. *NOT NULL Constraint* − Ensures that a column cannot have NULL value.


. *UNIQUE Constraint* − Ensures that all values in a column are different.


. *PRIMARY Key* − Uniquely identifies each row/record in a database table.


. *FOREIGN Key* − Constrains data based on columns in other tables.


. *CHECK Constraint* − The CHECK constraint ensures that all values in a column satisfy certain conditions.


. *EXCLUSION Constraint* − The EXCLUDE constraint ensures that if any two rows are compared on the specified column(s) or expression(s) using the specified operator(s), not all of these comparisons will return TRUE.



=== NOT NULL Constraint

By default, a column can hold NULL values. If you do not want a column to have a NULL value, then you need to define such constraint on this column specifying that NULL is now not allowed for that column. A NOT NULL constraint is always written as a column constraint.

A NULL is not the same as no data; rather, it represents unknown data.


==== Example

For example, the following PostgreSQL statement creates a new table called COMPANY1 and adds five columns, three of which, ID and NAME and AGE, specify not to accept NULL values −

[source]
----
CREATE TABLE COMPANY1(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

----


=== UNIQUE Constraint

The UNIQUE Constraint prevents two records from having identical values in a particular column. In the COMPANY table, for example, you might want to prevent two or more people from having identical age.


==== Example

For example, the following PostgreSQL statement creates a new table called COMPANY3 and adds five columns. Here, AGE column is set to UNIQUE, so that you cannot have two records with same age −

[source]
----
CREATE TABLE COMPANY3(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL UNIQUE,
   ADDRESS        CHAR(50),
   SALARY         REAL    DEFAULT 50000.00
);

----


=== PRIMARY KEY Constraint

The PRIMARY KEY constraint uniquely identifies each record in a database table. There can be more UNIQUE columns, but only one primary key in a table. Primary keys are important when designing the database tables. Primary keys are unique ids.

We use them to refer to table rows. Primary keys become foreign keys in other tables, when creating relations among tables. Due to a 'longstanding coding oversight', primary keys can be NULL in SQLite. This is not the case with other databases

A primary key is a field in a table, which uniquely identifies each row/record in a database table. Primary keys must contain unique values. A primary key column cannot have NULL values.

A table can have only one primary key, which may consist of single or multiple fields. When multiple fields are used as a primary key, they are called a *composite key*.

If a table has a primary key defined on any field(s), then you cannot have two records having the same value of that field(s).


==== Example

You already have seen various examples above where we have created COMAPNY4 table with ID as primary key −

[source]
----
CREATE TABLE COMPANY4(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

----


=== FOREIGN KEY Constraint

A foreign key constraint specifies that the values in a column (or a group of columns) must match the values appearing in some row of another table. We say this maintains the referential integrity between two related tables. They are called foreign keys because the constraints are foreign; that is, outside the table. Foreign keys are sometimes called a referencing key.


==== Example

For example, the following PostgreSQL statement creates a new table called COMPANY5 and adds five columns.

[source]
----
CREATE TABLE COMPANY6(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

----

For example, the following PostgreSQL statement creates a new table called DEPARTMENT1, which adds three columns. The column EMP_ID is the foreign key and references the ID field of the table COMPANY6.

[source]
----
CREATE TABLE DEPARTMENT1(
   ID INT PRIMARY KEY      NOT NULL,
   DEPT           CHAR(50) NOT NULL,
   EMP_ID         INT      references COMPANY6(ID)
);

----


=== CHECK Constraint

The CHECK Constraint enables a condition to check the value being entered into a record. If the condition evaluates to false, the record violates the constraint and is not entered into the table.


==== Example

For example, the following PostgreSQL statement creates a new table called COMPANY5 and adds five columns. Here, we add a CHECK with SALARY column, so that you cannot have any SALARY as Zero.

[source]
----
CREATE TABLE COMPANY5(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL    CHECK(SALARY > 0)
);

----


=== EXCLUSION Constraint

Exclusion constraints ensure that if any two rows are compared on the specified columns or expressions using the specified operators, at least one of these operator comparisons will return false or null.


==== Example

For example, the following PostgreSQL statement creates a new table called COMPANY7 and adds five columns. Here, we add an EXCLUDE constraint −

[source]
----
CREATE TABLE COMPANY7(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT,
   AGE            INT  ,
   ADDRESS        CHAR(50),
   SALARY         REAL,
   EXCLUDE USING gist
   (NAME WITH =,
   AGE WITH <>)
);

----

Here, USING gist is the type of index to build and use for enforcement.

As we have enforced the age has to be same, let us see this by inserting records to the table −

[source]
----
INSERT INTO COMPANY7 VALUES(1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY7 VALUES(2, 'Paul', 32, 'Texas', 20000.00 );
INSERT INTO COMPANY7 VALUES(3, 'Paul', 42, 'California', 20000.00 );

----

For the first two INSERT statements, the records are added to the COMPANY7 table. For the third INSERT statement, the following error is displayed −

[source]
----
ERROR:  conflicting key value violates exclusion constraint "company7_name_age_excl"
DETAIL:  Key (name, age)=(Paul, 42) conflicts with existing key (name, age)=(Paul, 32).

----


=== Dropping Constraints

To remove a constraint you need to know its name. If the name is known, it is easy to drop. Else, you need to find out the system-generated name. The psql command \d table name can be helpful here. The general syntax is −

[source]
----
ALTER TABLE table_name DROP CONSTRAINT some_name;

----


== PostgreSQL - JOINS

The PostgreSQL *Joins* clause is used to combine records from two or more tables in a database. A JOIN is a means for combining fields from two tables by using values common to each.

Join Types in PostgreSQL are −

. The CROSS JOIN

. The INNER JOIN

. The LEFT OUTER JOIN

. The RIGHT OUTER JOIN

. The FULL OUTER JOIN

Before we proceed, let us consider two tables, COMPANY and DEPARTMENT. We already have seen INSERT statements to populate COMPANY table. So just let us assume the list of records available in COMPANY table −

[source]
----
 id | name  | age | address   | salary | join_date
----+-------+-----+-----------+--------+-----------
  1 | Paul  |  32 | California|  20000 | 2001-07-13
  3 | Teddy |  23 | Norway    |  20000 |
  4 | Mark  |  25 | Rich-Mond |  65000 | 2007-12-13
  5 | David |  27 | Texas     |  85000 | 2007-12-13
  2 | Allen |  25 | Texas     |        | 2007-12-13
  8 | Paul  |  24 | Houston   |  20000 | 2005-07-13
  9 | James |  44 | Norway    |   5000 | 2005-07-13
 10 | James |  45 | Texas     |   5000 | 2005-07-13

----

Another table is DEPARTMENT, has the following definition −

[source]
----
CREATE TABLE DEPARTMENT(
   ID INT PRIMARY KEY      NOT NULL,
   DEPT           CHAR(50) NOT NULL,
   EMP_ID         INT      NOT NULL
);

----

Here is the list of INSERT statements to populate DEPARTMENT table −

[source]
----
INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID)
VALUES (1, 'IT Billing', 1 );

INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID)
VALUES (2, 'Engineering', 2 );

INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID)
VALUES (3, 'Finance', 7 );

----

Finally, we have the following list of records available in DEPARTMENT table −

[source]
----
 id | dept        | emp_id
----+-------------+--------
  1 | IT Billing  |  1
  2 | Engineering |  2
  3 | Finance     |  7

----


=== The CROSS JOIN

A CROSS JOIN matches every row of the first table with every row of the second table. If the input tables have x and y columns, respectively, the resulting table will have x+y columns. Because CROSS JOINs have the potential to generate extremely large tables, care must be taken to use them only when appropriate.

The following is the syntax of CROSS JOIN −

[source]
----
SELECT ... FROM table1 CROSS JOIN table2 ...

----

Based on the above tables, we can write a CROSS JOIN as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY CROSS JOIN DEPARTMENT;

----

The above given query will produce the following result −

[source]
----
emp_id| name  |  dept
------|-------|--------------
    1 | Paul  | IT Billing
    1 | Teddy | IT Billing
    1 | Mark  | IT Billing
    1 | David | IT Billing
    1 | Allen | IT Billing
    1 | Paul  | IT Billing
    1 | James | IT Billing
    1 | James | IT Billing
    2 | Paul  | Engineering
    2 | Teddy | Engineering
    2 | Mark  | Engineering
    2 | David | Engineering
    2 | Allen | Engineering
    2 | Paul  | Engineering
    2 | James | Engineering
    2 | James | Engineering
    7 | Paul  | Finance
    7 | Teddy | Finance
    7 | Mark  | Finance
    7 | David | Finance
    7 | Allen | Finance
    7 | Paul  | Finance
    7 | James | Finance
    7 | James | Finance

----


=== The INNER JOIN

A INNER JOIN creates a new result table by combining column values of two tables (table1 and table2) based upon the join-predicate. The query compares each row of table1 with each row of table2 to find all pairs of rows, which satisfy the join-predicate. When the join-predicate is satisfied, column values for each matched pair of rows of table1 and table2 are combined into a result row.

An INNER JOIN is the most common type of join and is the default type of join. You can use INNER keyword optionally.

The following is the syntax of INNER JOIN −

[source]
----
SELECT table1.column1, table2.column2...
FROM table1
INNER JOIN table2
ON table1.common_filed = table2.common_field;

----

Based on the above tables, we can write an INNER JOIN as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT
        ON COMPANY.ID = DEPARTMENT.EMP_ID;

----

The above given query will produce the following result −

[source]
----
 emp_id | name  | dept
--------+-------+------------
      1 | Paul  | IT Billing
      2 | Allen | Engineering

----


=== The LEFT OUTER JOIN

The OUTER JOIN is an extension of the INNER JOIN. SQL standard defines three types of OUTER JOINs: LEFT, RIGHT, and FULL and PostgreSQL supports all of these.

In case of LEFT OUTER JOIN, an inner join is performed first. Then, for each row in table T1 that does not satisfy the join condition with any row in table T2, a joined row is added with null values in columns of T2. Thus, the joined table always has at least one row for each row in T1.

The following is the syntax of LEFT OUTER JOIN −

[source]
----
SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...

----

Based on the above tables, we can write an inner join as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
   ON COMPANY.ID = DEPARTMENT.EMP_ID;

----

The above given query will produce the following result −

[source]
----
 emp_id | name  | dept
--------+-------+------------
      1 | Paul  | IT Billing
      2 | Allen | Engineering
        | James |
        | David |
        | Paul  |
        | Mark  |
        | Teddy |
        | James |

----


=== The RIGHT OUTER JOIN

First, an inner join is performed. Then, for each row in table T2 that does not satisfy the join condition with any row in table T1, a joined row is added with null values in columns of T1. This is the converse of a left join; the result table will always have a row for each row in T2.

The following is the syntax of RIGHT OUTER JOIN −

[source]
----
SELECT ... FROM table1 RIGHT OUTER JOIN table2 ON conditional_expression ...

----

Based on the above tables, we can write an inner join as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY RIGHT OUTER JOIN DEPARTMENT
   ON COMPANY.ID = DEPARTMENT.EMP_ID;

----

The above given query will produce the following result −

[source]
----
 emp_id | name  | dept
--------+-------+--------
      1 | Paul  | IT Billing
      2 | Allen | Engineering
      7 |       | Finance

----


=== The FULL OUTER JOIN

First, an inner join is performed. Then, for each row in table T1 that does not satisfy the join condition with any row in table T2, a joined row is added with null values in columns of T2. In addition, for each row of T2 that does not satisfy the join condition with any row in T1, a joined row with null values in the columns of T1 is added.

The following is the syntax of FULL OUTER JOIN −

[source]
----
SELECT ... FROM table1 FULL OUTER JOIN table2 ON conditional_expression ...

----

Based on the above tables, we can write an inner join as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY FULL OUTER JOIN DEPARTMENT
   ON COMPANY.ID = DEPARTMENT.EMP_ID;

----

The above given query will produce the following result −

[source]
----
 emp_id | name  | dept
--------+-------+---------------
      1 | Paul  | IT Billing
      2 | Allen | Engineering
      7 |       | Finance
        | James |
        | David |
        | Paul  |
        | Mark  |
        | Teddy |
        | James |

----


== PostgreSQL - UNIONS Clause

The PostgreSQL *UNION* clause/operator is used to combine the results of two or more SELECT statements without returning any duplicate rows.

To use UNION, each SELECT must have the same number of columns selected, the same number of column expressions, the same data type, and have them in the same order but they do not have to be the same length.


=== Syntax

The basic syntax of *UNION* is as follows −

[source]
----
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

----

Here, given condition could be any given expression based on your requirement.


=== Example

Consider the following two tables, (a) link:../postgresql/company.sql[COMPANY] table is as follows −

[source]
----
testdb=# SELECT * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

(b) Another table is link:../postgresql/department.sql[DEPARTMENT] as follows −

[source]
----
testdb=# SELECT * from DEPARTMENT;
 id | dept        | emp_id
----+-------------+--------
  1 | IT Billing  |      1
  2 | Engineering |      2
  3 | Finance     |      7
  4 | Engineering |      3
  5 | Finance     |      4
  6 | Engineering |      5
  7 | Finance     |      6
(7 rows)

----

Now let us join these two tables using SELECT statement along with UNION clause as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT
   ON COMPANY.ID = DEPARTMENT.EMP_ID
   UNION
      SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
         ON COMPANY.ID = DEPARTMENT.EMP_ID;

----

This would produce the following result −

[source]
----
 emp_id | name  |  dept
--------+-------+--------------
      5 | David | Engineering
      6 | Kim   | Finance
      2 | Allen | Engineering
      3 | Teddy | Engineering
      4 | Mark  | Finance
      1 | Paul  | IT Billing
      7 | James | Finance
(7 rows)

----


=== The UNION ALL Clause

The UNION ALL operator is used to combine the results of two SELECT statements including duplicate rows. The same rules that apply to UNION apply to the UNION ALL operator as well.


==== Syntax

The basic syntax of *UNION ALL* is as follows −

[source]
----
SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

UNION ALL

SELECT column1 [, column2 ]
FROM table1 [, table2 ]
[WHERE condition]

----

Here, given condition could be any given expression based on your requirement.


==== Example

Now, let us join above-mentioned two tables in our SELECT statement as follows −

[source]
----
testdb=# SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT
   ON COMPANY.ID = DEPARTMENT.EMP_ID
   UNION ALL
      SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT
         ON COMPANY.ID = DEPARTMENT.EMP_ID;

----

This would produce the following result −

[source]
----
 emp_id | name  | dept
--------+-------+--------------
      1 | Paul  | IT Billing
      2 | Allen | Engineering
      7 | James | Finance
      3 | Teddy | Engineering
      4 | Mark  | Finance
      5 | David | Engineering
      6 | Kim   | Finance
      1 | Paul  | IT Billing
      2 | Allen | Engineering
      7 | James | Finance
      3 | Teddy | Engineering
      4 | Mark  | Finance
      5 | David | Engineering
      6 | Kim   | Finance
(14 rows)

----


== PostgreSQL - NULL Values

The PostgreSQL *NULL* is the term used to represent a missing value. A NULL value in a table is a value in a field that appears to be blank.

A field with a NULL value is a field with no value. It is very important to understand that a NULL value is different from a zero value or a field that contains spaces.


=== Syntax

The basic syntax of using *NULL* while creating a table is as follows −

[source]
----
CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

----

Here, *NOT NULL* signifies that column should always accept an explicit value of the given data type. There are two columns where we did not use NOT NULL. Hence, this means these columns could be NULL.

A field with a NULL value is one that has been left blank during record creation.


=== Example

The NULL value can cause problems when selecting data, because when comparing an unknown value to any other value, the result is always unknown and not included in the final results. Consider the following table, link:../postgresql/company.sql[COMPANY] having the following records −

[source]
----
ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0

----

Let us use the UPDATE statement to set few nullable values as NULL as follows −

[source]
----
testdb=# UPDATE COMPANY SET ADDRESS = NULL, SALARY = NULL where ID IN(6,7);

----

Now, COMPANY table should have the following records −

[source]
----
 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  1 | Paul  |  32 | California  |  20000
  2 | Allen |  25 | Texas       |  15000
  3 | Teddy |  23 | Norway      |  20000
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
  6 | Kim   |  22 |             |
  7 | James |  24 |             |
(7 rows)

----

Next, let us see the usage of *IS NOT NULL* operator to list down all the records where SALARY is not NULL −

[source]
----
testdb=#  SELECT  ID, NAME, AGE, ADDRESS, SALARY
   FROM COMPANY
   WHERE SALARY IS NOT NULL;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
(5 rows)

----

The following is the usage of *IS NULL* operator which will list down all the records where SALARY is NULL −

[source]
----
testdb=#  SELECT  ID, NAME, AGE, ADDRESS, SALARY
        FROM COMPANY
        WHERE SALARY IS NULL;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age | address | salary
----+-------+-----+---------+--------
  6 | Kim   |  22 |         |
  7 | James |  24 |         |
(2 rows)

----


== PostgreSQL - ALIAS Syntax

You can rename a table or a column temporarily by giving another name, which is known as *ALIAS*. The use of table aliases means to rename a table in a particular PostgreSQL statement. Renaming is a temporary change and the actual table name does not change in the database.

The column aliases are used to rename a table's columns for the purpose of a particular PostgreSQL query.


=== Syntax

The basic syntax of *table* alias is as follows −

[source]
----
SELECT column1, column2....
FROM table_name AS alias_name
WHERE [condition];

----

The basic syntax of *column* alias is as follows −

[source]
----
SELECT column_name AS alias_name
FROM table_name
WHERE [condition];

----


=== Example

Consider the following two tables, (a) link:../postgresql/company.sql[COMPANY] table is as follows −

[source]
----
testdb=# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

(b) Another table is link:../postgresql/department.sql[DEPARTMENT] as follows −

[source]
----
 id | dept         | emp_id
----+--------------+--------
  1 | IT Billing   |      1
  2 | Engineering  |      2
  3 | Finance      |      7
  4 | Engineering  |      3
  5 | Finance      |      4
  6 | Engineering  |      5
  7 | Finance      |      6
(7 rows)

----

Now, following is the usage of *TABLE ALIAS* where we use C and D as aliases for COMPANY and DEPARTMENT tables, respectively −

[source]
----
testdb=# SELECT C.ID, C.NAME, C.AGE, D.DEPT
   FROM COMPANY AS C, DEPARTMENT AS D
   WHERE  C.ID = D.EMP_ID;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 id | name  | age |  dept
----+-------+-----+------------
  1 | Paul  |  32 | IT Billing
  2 | Allen |  25 | Engineering
  7 | James |  24 | Finance
  3 | Teddy |  23 | Engineering
  4 | Mark  |  25 | Finance
  5 | David |  27 | Engineering
  6 | Kim   |  22 | Finance
(7 rows)

----

Let us see an example for the usage of *COLUMN ALIAS* where COMPANY_ID is an alias of ID column and COMPANY_NAME is an alias of name column −

[source]
----
testdb=# SELECT C.ID AS COMPANY_ID, C.NAME AS COMPANY_NAME, C.AGE, D.DEPT
   FROM COMPANY AS C, DEPARTMENT AS D
   WHERE  C.ID = D.EMP_ID;

----

The above given PostgreSQL statement will produce the following result −

[source]
----
 company_id | company_name | age | dept
------------+--------------+-----+------------
      1     | Paul         |  32 | IT Billing
      2     | Allen        |  25 | Engineering
      7     | James        |  24 | Finance
      3     | Teddy        |  23 | Engineering
      4     | Mark         |  25 | Finance
      5     | David        |  27 | Engineering
      6     | Kim          |  22 | Finance
(7 rows)

----


== PostgreSQL - TRIGGERS

PostgreSQL *Triggers* are database callback functions, which are automatically performed/invoked when a specified database event occurs.

The following are important points about PostgreSQL triggers −

. PostgreSQL trigger can be specified to fire
Before the operation is attempted on a row (before constraints are checked and the INSERT, UPDATE or DELETE is attempted)
After the operation has completed (after constraints are checked and the INSERT, UPDATE, or DELETE has completed)
Instead of the operation (in the case of inserts, updates or deletes on a view)


. A trigger that is marked FOR EACH ROW is called once for every row that the operation modifies. In contrast, a trigger that is marked FOR EACH STATEMENT only executes once for any given operation, regardless of how many rows it modifies.


. Both, the WHEN clause and the trigger actions, may access elements of the row being inserted, deleted or updated using references of the form *NEW.column-name* and *OLD.column-name*, where column-name is the name of a column from the table that the trigger is associated with.


. If a WHEN clause is supplied, the PostgreSQL statements specified are only executed for rows for which the WHEN clause is true. If no WHEN clause is supplied, the PostgreSQL statements are executed for all rows.


. If multiple triggers of the same kind are defined for the same event, they will be fired in alphabetical order by name.


. The BEFORE, AFTER or INSTEAD OF keyword determines when the trigger actions will be executed relative to the insertion, modification or removal of the associated row.


. Triggers are automatically dropped when the table that they are associated with is dropped.


. The table to be modified must exist in the same database as the table or view to which the trigger is attached and one must use just *tablename*, not *database.tablename*.


. A CONSTRAINT option when specified creates a constraint trigger. This is the same as a regular trigger except that the timing of the trigger firing can be adjusted using SET CONSTRAINTS. Constraint triggers are expected to raise an exception when the constraints they implement are violated.



=== Syntax

The basic syntax of creating a *trigger* is as follows −

[source]
----
CREATE  TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name
ON table_name
[
 -- Trigger logic goes here....
];

----

Here, *event_name* could be INSERT, DELETE, UPDATE, and TRUNCATE database operation on the mentioned table *table_name*. You can optionally specify FOR EACH ROW after table name.

The following is the syntax of creating a trigger on an UPDATE operation on one or more specified columns of a table as follows −

[source]
----
CREATE  TRIGGER trigger_name [BEFORE|AFTER] UPDATE OF column_name
ON table_name
[
 -- Trigger logic goes here....
];

----


=== Example

Let us consider a case where we want to keep audit trial for every record being inserted in COMPANY table, which we will create newly as follows (Drop COMPANY table if you already have it).

[source]
----
testdb=# CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

----

To keep audit trial, we will create a new table called AUDIT where log messages will be inserted whenever there is an entry in COMPANY table for a new record −

[source]
----
testdb=# CREATE TABLE AUDIT(
   EMP_ID INT NOT NULL,
   ENTRY_DATE TEXT NOT NULL
);

----

Here, ID is the AUDIT record ID, and EMP_ID is the ID, which will come from COMPANY table, and DATE will keep timestamp when the record will be created in COMPANY table. So now, let us create a trigger on COMPANY table as follows −

[source]
----
testdb=# CREATE TRIGGER example_trigger AFTER INSERT ON COMPANY
FOR EACH ROW EXECUTE PROCEDURE auditlogfunc();

----

Where auditlogfunc() is a PostgreSQL *procedure* and has the following definition −

[source]
----
CREATE OR REPLACE FUNCTION auditlogfunc() RETURNS TRIGGER AS $example_table$
   BEGIN
      INSERT INTO AUDIT(EMP_ID, ENTRY_DATE) VALUES (new.ID, current_timestamp);
      RETURN NEW;
   END;
$example_table$ LANGUAGE plpgsql;

----

Now, we will start the actual work. Let us start inserting record in COMPANY table which should result in creating an audit log record in AUDIT table. So let us create one record in COMPANY table as follows −

[source]
----
testdb=# INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
VALUES (1, 'Paul', 32, 'California', 20000.00 );

----

This will create one record in COMPANY table, which is as follows −

[source]
----
 id | name | age | address      | salary
----+------+-----+--------------+--------
  1 | Paul |  32 | California   |  20000
----

Same time, one record will be created in AUDIT table. This record is the result of a trigger, which we have created on INSERT operation on COMPANY table. Similarly, you can create your triggers on UPDATE and DELETE operations based on your requirements.

[source]
----
 emp_id |          entry_date
--------+-------------------------------
      1 | 2013-05-05 15:49:59.968+05:30
(1 row)

----


=== Listing TRIGGERS

You can list down all the triggers in the current database from *pg_trigger* table as follows −

[source]
----
testdb=# SELECT * FROM pg_trigger;

----

The above given PostgreSQL statement will list down all triggers.

If you want to list the triggers on a particular table, then use AND clause with table name as follows −

[source]
----
testdb=# SELECT tgname FROM pg_trigger, pg_class WHERE tgrelid=pg_class.oid AND relname='company';

----

The above given PostgreSQL statement will also list down only one entry as follows −

[source]
----
     tgname
----

 example_trigger
(1 row)

----
=== Dropping TRIGGERS

The following is the DROP command, which can be used to drop an existing trigger −

[source]
----

[.iokays-translated-41bdde53783c3ed8e6b6fd8a69e9a7e5]
testdb=# DROP TRIGGER trigger_name;


[.iokays-original-41bdde53783c3ed8e6b6fd8a69e9a7e5]
testdb=# DROP TRIGGER trigger_name;

----
== PostgreSQL - INDEXES

Indexes are special lookup tables that the database search engine can use to speed up data retrieval. Simply put, an index is a pointer to data in a table. An index in a database is very similar to an index in the back of a book.

For example, if you want to reference all pages in a book that discusses a certain topic, you have to first refer to the index, which lists all topics alphabetically and then refer to one or more specific page numbers.

An index helps to speed up SELECT queries and WHERE clauses; however, it slows down data input, with UPDATE and INSERT statements. Indexes can be created or dropped with no effect on the data.

Creating an index involves the CREATE INDEX statement, which allows you to name the index, to specify the table and which column or columns to index, and to indicate whether the index is in ascending or descending order.

Indexes can also be unique, similar to the UNIQUE constraint, in that the index prevents duplicate entries in the column or combination of columns on which there's an index.


==== The CREATE INDEX Command

The basic syntax of *CREATE INDEX* is as follows −

[source]
----

[.iokays-translated-e9e839260b51f6bf58bc8d4f62ce5643]
在表名上创建索引 index_name;


[.iokays-original-e9e839260b51f6bf58bc8d4f62ce5643]
CREATE INDEX index_name ON table_name;

----
=== Index Types

PostgreSQL provides several index types: B-tree, Hash, GiST, SP-GiST and GIN. Each Index type uses a different algorithm that is best suited to different types of queries. By default, the CREATE INDEX command creates B-tree indexes, which fit the most common situations.


==== Single-Column Indexes

A single-column index is one that is created based on only one table column. The basic syntax is as follows −

[source]
----

[.iokays-translated-fe87241e4928137475c917db36e8c988]
在表名上创建索引 index_name (列名);


[.iokays-original-fe87241e4928137475c917db36e8c988]
CREATE INDEX index_name
ON table_name (column_name);

----
==== Multicolumn Indexes

A multicolumn index is defined on more than one column of a table. The basic syntax is as follows −

[source]
----

[.iokays-translated-92623e7b1d669df174c573c76583cc63]
在表名上创建索引 index_name (列1名,列2名);


[.iokays-original-92623e7b1d669df174c573c76583cc63]
CREATE INDEX index_name
ON table_name (column1_name, column2_name);

----
Whether to create a single-column index or a multicolumn index, take into consideration the column(s) that you may use very frequently in a query's WHERE clause as filter conditions.

Should there be only one column used, a single-column index should be the choice. Should there be two or more columns that are frequently used in the WHERE clause as filters, the multicolumn index would be the best choice.


==== Unique Indexes

Unique indexes are used not only for performance, but also for data integrity. A unique index does not allow any duplicate values to be inserted into the table. The basic syntax is as follows −

[source]
----

[.iokays-translated-2e7f3c6adc2f289dc5abfc7dd92a59c8]
在表名上创建唯一的索引 index_name (列名);


[.iokays-original-2e7f3c6adc2f289dc5abfc7dd92a59c8]
CREATE UNIQUE INDEX index_name
on table_name (column_name);

----
=== Partial Indexes

A partial index is an index built over a subset of a table; the subset is defined by a conditional expression (called the predicate of the partial index). The index contains entries only for those table rows that satisfy the predicate. The basic syntax is as follows −

[source]
----

[.iokays-translated-4a1c346dec153ff4621ccee07fd531b6]
在表名上创建索引 index_name (条件表达式);


[.iokays-original-4a1c346dec153ff4621ccee07fd531b6]
CREATE INDEX index_name
on table_name (conditional_expression);

----
=== Implicit Indexes

Implicit indexes are indexes that are automatically created by the database server when an object is created. Indexes are automatically created for primary key constraints and unique constraints.


==== Example

The following is an example where we will create an index on link:../postgresql/company.sql[COMPANY] table for salary column −

[source]
----

[id="_create_index_salary_index_on_company_salary"]
= CREATE INDEX salary_index ON COMPANY (salary);

----
Now, let us list down all the indices available on COMPANY table using *\d company* command.

[source]
----

[id="_d_company"]
= \d company

----
This will produce the following result, where company_pkey is an implicit index, which got created when the table was created.

[source]
----

       Table "public.company"
 Column  |     Type      | Modifiers
---------+---------------+-----------
 id      | integer       | not null
 name    | text          | not null
 age     | integer       | not null
 address | character(50) |
 salary  | real          |
Indexes:
    "company_pkey" PRIMARY KEY, btree (id)
    "salary_index" btree (salary)

----
You can list down the entire indexes database wide using the *\di* command −


=== The DROP INDEX Command

An index can be dropped using PostgreSQL *DROP* command. Care should be taken when dropping an index because performance may be slowed or improved.

The basic syntax is as follows −

[source]
----

[.iokays-translated-f74ca961a32103083b777cf9f8c815a8]
删除索引 index_name;


[.iokays-original-f74ca961a32103083b777cf9f8c815a8]
DROP INDEX index_name;

----
You can use following statement to delete previously created index −

[source]
----

[id="_drop_index_salary_index"]
= DROP INDEX salary_index;

----
=== When Should Indexes be Avoided?

Although indexes are intended to enhance a database's performance, there are times when they should be avoided. The following guidelines indicate when the use of an index should be reconsidered −

. Indexes should not be used on small tables.


. Tables that have frequent, large batch update or insert operations.


. Indexes should not be used on columns that contain a high number of NULL values.


. Columns that are frequently manipulated should not be indexed.



== PostgreSQL - ALTER TABLE Command

The PostgreSQL *ALTER TABLE* command is used to add, delete or modify columns in an existing table.

You would also use ALTER TABLE command to add and drop various constraints on an existing table.


=== Syntax

The basic syntax of *ALTER TABLE* to add a new column in an existing table is as follows −

[source]
----

[.iokays-translated-b33cac9dfd8e5b2d9331170a10d34e88]
在表名上添加列名数据类型;


[.iokays-original-b33cac9dfd8e5b2d9331170a10d34e88]
ALTER TABLE table_name ADD column_name datatype;

----
The basic syntax of ALTER TABLE to *DROP COLUMN* in an existing table is as follows −

[source]
----

[.iokays-translated-7a3159fe1645d169fbb4e8c3f68c6e06]
删除表名为列名;


[.iokays-original-7a3159fe1645d169fbb4e8c3f68c6e06]
ALTER TABLE table_name DROP COLUMN column_name;

----
The basic syntax of ALTER TABLE to change the *DATA TYPE* of a column in a table is as follows −

[source]
----

[.iokays-translated-e334fc937607f0b6bd0871942269b2c0]
在表名上编辑列名类型数据类型;


[.iokays-original-e334fc937607f0b6bd0871942269b2c0]
ALTER TABLE table_name ALTER COLUMN column_name TYPE datatype;

----
The basic syntax of ALTER TABLE to add a *NOT NULL* constraint to a column in a table is as follows −

[source]
----

[.iokays-translated-21d412787299ccf2b4fa62095ce40e4c]
在表名上修改列名数据类型不为空;


[.iokays-original-21d412787299ccf2b4fa62095ce40e4c]
ALTER TABLE table_name MODIFY column_name datatype NOT NULL;

----
The basic syntax of ALTER TABLE to *ADD UNIQUE CONSTRAINT* to a table is as follows −

[source]
----

[.iokays-translated-6c6848688c37664915b00ecbf5a60f5f]
在表名上添加约束 MyUniqueConstraint 唯一 (列1,列2...);


[.iokays-original-6c6848688c37664915b00ecbf5a60f5f]
ALTER TABLE table_name
ADD CONSTRAINT MyUniqueConstraint UNIQUE(column1, column2…​);

----
The basic syntax of ALTER TABLE to *ADD CHECK CONSTRAINT* to a table is as follows −

[source]
----

[.iokays-translated-b87a3ec1a2b0c2fa1a787dd06b5fb3a8]
在表名上添加约束 MyUniqueConstraint 检查 (条件);


[.iokays-original-b87a3ec1a2b0c2fa1a787dd06b5fb3a8]
ALTER TABLE table_name
ADD CONSTRAINT MyUniqueConstraint CHECK (CONDITION);

----
The basic syntax of ALTER TABLE to *ADD PRIMARY KEY* constraint to a table is as follows −

[source]
----

[.iokays-translated-8937ad50896a021211e4fb4b5ee5b0f6]
在表名上添加约束 MyPrimaryKey 主键 (列1,列2...);


[.iokays-original-8937ad50896a021211e4fb4b5ee5b0f6]
ALTER TABLE table_name
ADD CONSTRAINT MyPrimaryKey PRIMARY KEY (column1, column2…​);

----
The basic syntax of ALTER TABLE to *DROP CONSTRAINT* from a table is as follows −

[source]
----

[.iokays-translated-f9ba0e7cd3ae01c2f82c1462e6c091dd]
删除表名上的约束 MyUniqueConstraint;


[.iokays-original-f9ba0e7cd3ae01c2f82c1462e6c091dd]
ALTER TABLE table_name
DROP CONSTRAINT MyUniqueConstraint;

----
If you are using MySQL, the code is as follows −

[source]
----

[.iokays-translated-29c4d15031814e4c9958f9279b7672e4]
删除表名上的索引 MyUniqueConstraint;


[.iokays-original-29c4d15031814e4c9958f9279b7672e4]
ALTER TABLE table_name
DROP INDEX MyUniqueConstraint;

----
The basic syntax of ALTER TABLE to *DROP PRIMARY KEY* constraint from a table is as follows −

[source]
----

[.iokays-translated-05ce7709042296e9fb0a4789a5033411]
删除表名上的约束 MyPrimaryKey;


[.iokays-original-05ce7709042296e9fb0a4789a5033411]
ALTER TABLE table_name
DROP CONSTRAINT MyPrimaryKey;

----
If you are using MySQL, the code is as follows −

[source]
----

[.iokays-translated-17386b46f885990109fd30501c1918af]
删除表名上的主键;


[.iokays-original-17386b46f885990109fd30501c1918af]
ALTER TABLE table_name
DROP PRIMARY KEY;

----
=== Example

Consider our link:../postgresql/company.sql[COMPANY] table has the following records −

[source]
----

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000

----
The following is the example to ADD a new column in an existing table −

[source]
----

[.iokays-translated-01f80d64a7e8c7b7e1f79b7d8b2aea34]
testdb=# 在公司中添加性别 char(1);


[.iokays-original-01f80d64a7e8c7b7e1f79b7d8b2aea34]
testdb=# ALTER TABLE COMPANY ADD GENDER char(1);

----
Now, COMPANY table is changed and the following would be the output from SELECT statement −

[source]
----

 id | name  | age | address     | salary | gender
----+-------+-----+-------------+--------+--------
  1 | Paul  |  32 | California  |  20000 |
  2 | Allen |  25 | Texas       |  15000 |
  3 | Teddy |  23 | Norway      |  20000 |
  4 | Mark  |  25 | Rich-Mond   |  65000 |
  5 | David |  27 | Texas       |  85000 |
  6 | Kim   |  22 | South-Hall  |  45000 |
  7 | James |  24 | Houston     |  10000 |
(7 rows)

----
The following is the example to DROP gender column from existing table −

[source]
----

[.iokays-translated-3c29adb3e2543feeb96a54d541644ab7]
testdb=# 从公司中删除性别;


[.iokays-original-3c29adb3e2543feeb96a54d541644ab7]
testdb=# ALTER TABLE COMPANY DROP GENDER;

----
Now, COMPANY table is changed and the following would be the output from SELECT statement −

[source]
----

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000

----
== PostgreSQL - TRUNCATE TABLE Command

The PostgreSQL *TRUNCATE TABLE* command is used to delete complete data from an existing table. You can also use DROP TABLE command to delete complete table but it would remove complete table structure from the database and you would need to re-create this table once again if you wish to store some data.

It has the same effect as DELETE on each table, but since it does not actually scan the tables, it is faster. Furthermore, it reclaims disk space immediately, rather than requiring a subsequent VACUUM operation. This is most useful on large tables.


=== Syntax

The basic syntax of *TRUNCATE TABLE* is as follows −

[source]
----

[.iokays-translated-ee053ee09e51e901b5cb790b1978f899]
TRUNCATE TABLE tablename;


[.iokays-original-ee053ee09e51e901b5cb790b1978f899]
TRUNCATE TABLE  table_name;

----
=== Example

Consider the COMPANY table has the following records −

[source]
----

 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000
(7 rows)

----
The following is the example to truncate −

[source]
----

testdb=# TRUNCATE TABLE COMPANY;

----
Now, COMPANY table is truncated and the following would be the output of SELECT statement −

[source]
----

[.iokays-translated-bf29814b8ae676e5a1d7090897043654]
testdb=# SELECT * FROM CUSTOMERS; id | 名字 | 年龄 | 地址 | 薪资----(0 行)----


[.iokays-original-bf29814b8ae676e5a1d7090897043654]
testdb=# SELECT * FROM CUSTOMERS;
 id | name | age | address | salary
--------------------------------
(0 rows)

----
== PostgreSQL - VIEWS

Views are pseudo-tables. That is, they are not real tables; nevertheless appear as ordinary tables to SELECT. A view can represent a subset of a real table, selecting certain columns or certain rows from an ordinary table. A view can even represent joined tables. Because views are assigned separate permissions, you can use them to restrict table access so that the users see only specific rows or columns of a table.

A view can contain all rows of a table or selected rows from one or more tables. A view can be created from one or many tables, which depends on the written PostgreSQL query to create a view.

Views, which are kind of virtual tables, allow users to do the following −

. Structure data in a way that users or classes of users find natural or intuitive.


. Restrict access to the data such that a user can only see limited data instead of complete table.


. Summarize data from various tables, which can be used to generate reports.


Since views are not ordinary tables, you may not be able to execute a DELETE, INSERT, or UPDATE statement on a view. However, you can create a RULE to correct this problem of using DELETE, INSERT or UPDATE on a view.


=== Creating Views

The PostgreSQL views are created using the *CREATE VIEW* statement. The PostgreSQL views can be created from a single table, multiple tables, or another view.

The basic CREATE VIEW syntax is as follows −

[source]
----

[.iokays-translated-b506b9faffb326e1269f84772c5b82fe]
CREATE [TEMP | TEMPORARY] VIEW 视图名 ASSELECT 字段 1,字段 2...…​..从表名 WHERE [条件];


[.iokays-original-b506b9faffb326e1269f84772c5b82fe]
CREATE [TEMP | TEMPORARY] VIEW view_name AS
SELECT column1, column2…​..
FROM table_name
WHERE [condition];

----
You can include multiple tables in your SELECT statement in very similar way as you use them in normal PostgreSQL SELECT query. If the optional TEMP or TEMPORARY keyword is present, the view will be created in the temporary space. Temporary views are automatically dropped at the end of the current session.


==== Example

Consider, the link:../postgresql/company.sql[COMPANY] table is having the following records −

[source]
----

 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000

----
Now, following is an example to create a view from COMPANY table. This view would be used to have only few columns from COMPANY table −

[source]
----

[.iokays-translated-e89bb7786ec8d69717b07ba381bd990e]
testdb=# CREATE VIEW COMPANY_VIEW ASSELECT ID、NAME、AGEFROM COMPANY;


[.iokays-original-e89bb7786ec8d69717b07ba381bd990e]
testdb=# CREATE VIEW COMPANY_VIEW AS
SELECT ID, NAME, AGE
FROM  COMPANY;

----
Now, you can query COMPANY_VIEW in a similar way as you query an actual table. Following is the example −

[source]
----

testdb=# SELECT * FROM COMPANY_VIEW;

----
This would produce the following result −

[source]
----

 id | name  | age
----+-------+-----
  1 | Paul  |  32
  2 | Allen |  25
  3 | Teddy |  23
  4 | Mark  |  25
  5 | David |  27
  6 | Kim   |  22
  7 | James |  24
(7 rows)

----
=== Dropping Views

To drop a view, simply use the DROP VIEW statement with the *view_name*. The basic DROP VIEW syntax is as follows −

[source]
----

[.iokays-translated-8901e41905ea47398ba8ac24f12bfd44]
testdb=# DROP VIEW 视图名;


[.iokays-original-8901e41905ea47398ba8ac24f12bfd44]
testdb=# DROP VIEW view_name;

----
The following command will delete COMPANY_VIEW view, which we created in the last section −

[source]
----

testdb=# DROP VIEW COMPANY_VIEW;

----
== PostgreSQL - TRANSACTIONS

A transaction is a unit of work that is performed against a database. Transactions are units or sequences of work accomplished in a logical order, whether in a manual fashion by a user or automatically by some sort of a database program.

A transaction is the propagation of one or more changes to the database. For example, if you are creating a record, updating a record, or deleting a record from the table, then you are performing transaction on the table. It is important to control transactions to ensure data integrity and to handle database errors.

Practically, you will club many PostgreSQL queries into a group and you will execute all of them together as a part of a transaction.


==== Properties of Transactions

Transactions have the following four standard properties, usually referred to by the acronym ACID −

. *Atomicity* − Ensures that all operations within the work unit are completed successfully; otherwise, the transaction is aborted at the point of failure and previous operations are rolled back to their former state.


. *Consistency* − Ensures that the database properly changes states upon a successfully committed transaction.


. *Isolation* − Enables transactions to operate independently of and transparent to each other.


. *Durability* − Ensures that the result or effect of a committed transaction persists in case of a system failure.



=== Transaction Control

The following commands are used to control transactions −

. *BEGIN TRANSACTION* − To start a transaction.


. *COMMIT* − To save the changes, alternatively you can use *END TRANSACTION* command.


. *ROLLBACK* − To rollback the changes.


Transactional control commands are only used with the DML commands INSERT, UPDATE and DELETE only. They cannot be used while creating tables or dropping them because these operations are automatically committed in the database.


==== The BEGIN TRANSACTION Command

Transactions can be started using BEGIN TRANSACTION or simply BEGIN command. Such transactions usually persist until the next COMMIT or ROLLBACK command is encountered. But a transaction will also ROLLBACK if the database is closed or if an error occurs.

The following is the simple syntax to start a transaction −

[source]
----

BEGIN;

[.iokays-translated-e81c4e4f2b7b93b481e13a8553c2ae1b]
或


[.iokays-original-e81c4e4f2b7b93b481e13a8553c2ae1b]
or

BEGIN TRANSACTION;

----
=== The COMMIT Command

The COMMIT command is the transactional command used to save changes invoked by a transaction to the database.

The COMMIT command saves all transactions to the database since the last COMMIT or ROLLBACK command.

The syntax for COMMIT command is as follows −

[source]
----

COMMIT;

[.iokays-translated-e81c4e4f2b7b93b481e13a8553c2ae1b]
或


[.iokays-original-e81c4e4f2b7b93b481e13a8553c2ae1b]
or

END TRANSACTION;

----
=== The ROLLBACK Command

The ROLLBACK command is the transactional command used to undo transactions that have not already been saved to the database.

The ROLLBACK command can only be used to undo transactions since the last COMMIT or ROLLBACK command was issued.

The syntax for ROLLBACK command is as follows −

[source]
----

ROLLBACK;

----
=== Example

Consider the link:../postgresql/company.sql[COMPANY] table is having the following records −

[source]
----

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000

----
Now, let us start a transaction and delete records from the table having age = 25 and finally we use ROLLBACK command to undo all the changes.

[source]
----

[.iokays-translated-74ee9c0acfcd59da0457b742ff8cc8d2]
testdb=# BEGIN;DELETE FROM COMPANY WHERE AGE = 25;ROLLBACK;


[.iokays-original-74ee9c0acfcd59da0457b742ff8cc8d2]
testdb=# BEGIN;
DELETE FROM COMPANY WHERE AGE = 25;
ROLLBACK;

----
If you will check COMPANY table is still having the following records −

[source]
----

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000

----
Now, let us start another transaction and delete records from the table having age = 25 and finally we use COMMIT command to commit all the changes.

[source]
----

[.iokays-translated-45713944806b2c4d7dfb54d760ac4e4a]
testdb=# BEGIN;DELETE FROM COMPANY WHERE AGE = 25;COMMIT;


[.iokays-original-45713944806b2c4d7dfb54d760ac4e4a]
testdb=# BEGIN;
DELETE FROM COMPANY WHERE AGE = 25;
COMMIT;

----
If you will check the COMPANY table, it still has the following records −

[source]
----

 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  3 | Teddy |  23 | Norway     |  20000
  5 | David |  27 | Texas      |  85000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000
(5 rows)

----
== PostgreSQL - LOCKS

Locks or Exclusive Locks or Write Locks prevent users from modifying a row or an entire table. Rows modified by UPDATE and DELETE are then exclusively locked automatically for the duration of the transaction. This prevents other users from changing the row until the transaction is either committed or rolled back.

The only time when users must wait for other users is when they are trying to modify the same row. If they modify different rows, no waiting is necessary. SELECT queries never have to wait.

The database performs locking automatically. In certain cases, however, locking must be controlled manually. Manual locking can be done by using the LOCK command. It allows specification of a transaction's lock type and scope.


==== Syntax for LOCK command

The basic syntax for LOCK command is as follows −

[source]
----

[.iokays-translated-15bf248faf6ddc6a92bacf78a1118da1]
LOCK [ TABLE ]名称 in锁定模式


[.iokays-original-15bf248faf6ddc6a92bacf78a1118da1]
LOCK [ TABLE ]
name
 IN
lock_mode

----
. *name* − The name (optionally schema-qualified) of an existing table to lock. If ONLY is specified before the table name, only that table is locked. If ONLY is not specified, the table and all its descendant tables (if any) are locked.


. *lock_mode* − The lock mode specifies which locks this lock conflicts with. If no lock mode is specified, then ACCESS EXCLUSIVE, the most restrictive mode, is used. Possible values are: ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE.



=== DeadLocks

Deadlocks can occur when two transactions are waiting for each other to finish their operations. While PostgreSQL can detect them and end them with a ROLLBACK, deadlocks can still be inconvenient. To prevent your applications from running into this problem, make sure to design them in such a way that they will lock objects in the same order.


=== Advisory Locks

PostgreSQL provides means for creating locks that have application-defined meanings. These are called advisory locks. As the system does not enforce their use, it is up to the application to use them correctly. Advisory locks can be useful for locking strategies that are an awkward fit for the MVCC model.

For example, a common use of advisory locks is to emulate pessimistic locking strategies typical of the so-called "flat file" data management systems. While a flag stored in a table could be used for the same purpose, advisory locks are faster, avoid table bloat, and are automatically cleaned up by the server at the end of the session.


==== Example

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----

[.iokays-translated-ca1d8dad123084b8c51d70b555a2a923]
testdb# select * from COMPANY; id | 名字 | 年龄 | 地址 | 薪资---- 1 | 保罗 | 32 | 加利福尼亚 | 20000 2 | 艾伦 | 25 | 得克萨斯 | 15000 3 | 泰迪 | 23 | 挪威 | 20000 4 | 马克 | 25 | 列治文 | 65000 5 | 大卫 | 27 | 得克萨斯 | 85000 6 | 金 | 22 | 南厅 | 45000 7 | 詹姆斯 | 24 | 休斯顿 | 10000(7 行)----


[.iokays-original-ca1d8dad123084b8c51d70b555a2a923]
testdb# select * from COMPANY;
 id | name  | age | address   | salary
-----------------------------------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----
The following example locks the COMPANY table within the testdb database in ACCESS EXCLUSIVE mode. The LOCK statement works only in a transaction mode −

[source]
----

[.iokays-translated-4a0d59c0873d754adb10556b277507d9]
testdb=#BEGIN;LOCK TABLE company1 IN ACCESS EXCLUSIVE MODE;


[.iokays-original-4a0d59c0873d754adb10556b277507d9]
testdb=#BEGIN;
LOCK TABLE company1 IN ACCESS EXCLUSIVE MODE;

----
The above given PostgreSQL statement will produce the following result −

[source]
----

LOCK TABLE

----
The above message indicates that the table is locked until the transaction ends and to finish the transaction you will have to either rollback or commit the transaction.


== PostgreSQL - Sub Queries

A subquery or Inner query or Nested query is a query within another PostgreSQL query and embedded within the WHERE clause.

A subquery is used to return data that will be used in the main query as a condition to further restrict the data to be retrieved.

Subqueries can be used with the SELECT, INSERT, UPDATE and DELETE statements along with the operators like =, <, >, >=, <=, IN, etc.

There are a few rules that subqueries must follow −

. Subqueries must be enclosed within parentheses.


. A subquery can have only one column in the SELECT clause, unless multiple columns are in the main query for the subquery to compare its selected columns.


. An ORDER BY cannot be used in a subquery, although the main query can use an ORDER BY. The GROUP BY can be used to perform the same function as the ORDER BY in a subquery.


. Subqueries that return more than one row can only be used with multiple value operators, such as the IN, EXISTS, NOT IN, ANY/SOME, ALL operator.


. The BETWEEN operator cannot be used with a subquery; however, the BETWEEN can be used within the subquery.



=== Subqueries with the SELECT Statement

Subqueries are most frequently used with the SELECT statement. The basic syntax is as follows −

[source]
----

[.iokays-translated-f8084699487320613120d9a9b759b057]
SELECT column_name [, column_name ] FROM table1 [, table2 ] WHERE column_name OPERATOR (SELECT column_name [, column_name ] FROM table1 [, table2 ] [WHERE])


[.iokays-original-f8084699487320613120d9a9b759b057]
SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
      (SELECT column_name [, column_name ]
      FROM table1 [, table2 ]
      [WHERE])

----
==== Example

Consider the link:../postgresql/company.sql[COMPANY] table having the following records −

[source]
----

 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----
Now, let us check the following sub-query with SELECT statement −

[source]
----

[.iokays-translated-1f9d7882ece214078e1e9ee7bee0d35b]
testdb=# SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY WHERE SALARY > 45000);


[.iokays-original-1f9d7882ece214078e1e9ee7bee0d35b]
testdb=# SELECT *
   FROM COMPANY
   WHERE ID IN (SELECT ID
      FROM COMPANY
      WHERE SALARY > 45000) ;

----
This would produce the following result −

[source]
----

 id | name  | age |  address    | salary
----+-------+-----+-------------+--------
  4 | Mark  |  25 | Rich-Mond   |  65000
  5 | David |  27 | Texas       |  85000
(2 rows)

----
=== Subqueries with the INSERT Statement

Subqueries also can be used with INSERT statements. The INSERT statement uses the data returned from the subquery to insert into another table. The selected data in the subquery can be modified with any of the character, date, or number functions.

The basic syntax is as follows −

[source]
----

[.iokays-translated-5203a17506f48359c63836cdf73594bd]
INSERT INTO table_name [(column1 [, column2])] SELECT [*|column1 [, column2]] FROM table1 [, table2] [WHERE VALUE OPERATOR];


[.iokays-original-5203a17506f48359c63836cdf73594bd]
INSERT INTO table_name [ (column1 [, column2 ]) ]
   SELECT [ *|column1 [, column2 ] ]
   FROM table1 [, table2 ]
   [ WHERE VALUE OPERATOR ]

----
==== Example

Consider a table COMPANY_BKP, with similar structure as COMPANY table and can be created using the same CREATE TABLE using COMPANY_BKP as the table name. Now, to copy complete COMPANY table into COMPANY_BKP, following is the syntax −

[source]
----

[.iokays-translated-0fa64307dee8b48b50b142cf54d700b2]
testdb=# INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY);


[.iokays-original-0fa64307dee8b48b50b142cf54d700b2]
testdb=# INSERT INTO COMPANY_BKP
   SELECT * FROM COMPANY
   WHERE ID IN (SELECT ID
      FROM COMPANY) ;

----
=== Subqueries with the UPDATE Statement

The subquery can be used in conjunction with the UPDATE statement. Either single or multiple columns in a table can be updated when using a subquery with the UPDATE statement.

The basic syntax is as follows −

[source]
----

[.iokays-translated-78c763848ab332c2421cc3981b73c0e5]
UPDATE table SET column_name = new_value [WHERE OPERATOR [VALUE] (SELECT COLUMN_NAME FROM TABLE_NAME) [WHERE)];


[.iokays-original-78c763848ab332c2421cc3981b73c0e5]
UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

----
==== Example

Assuming, we have COMPANY_BKP table available, which is backup of the COMPANY table.

The following example updates SALARY by 0.50 times in the COMPANY table for all the customers, whose AGE is greater than or equal to 27 −

[source]
----

[.iokays-translated-c48a90655df2a1cd231442da640654db]
testdb=# UPDATE COMPANY SET SALARY = SALARY * 0.50 WHERE AGE IN (SELECT AGE FROM COMPANY_BKP WHERE AGE >= 27);


[.iokays-original-c48a90655df2a1cd231442da640654db]
testdb=# UPDATE COMPANY
   SET SALARY = SALARY * 0.50
   WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
      WHERE AGE >= 27 );

----
This would affect two rows and finally the COMPANY table would have the following records −

[source]
----

 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  2 | Allen |  25 | Texas       |  15000
  3 | Teddy |  23 | Norway      |  20000
  4 | Mark  |  25 | Rich-Mond   |  65000
  6 | Kim   |  22 | South-Hall  |  45000
  7 | James |  24 | Houston     |  10000
  1 | Paul  |  32 | California  |  10000
  5 | David |  27 | Texas       |  42500
(7 rows)

----
=== Subqueries with the DELETE Statement

The subquery can be used in conjunction with the DELETE statement like with any other statements mentioned above.

The basic syntax is as follows −

[source]
----

[.iokays-translated-4d3132b9ba638fab1b5a1e42c572c5f2]
DELETE FROM TABLE_NAME [WHERE OPERATOR [VALUE] (SELECT COLUMN_NAME FROM TABLE_NAME) [WHERE)];


[.iokays-original-4d3132b9ba638fab1b5a1e42c572c5f2]
DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

----
==== Example

Assuming, we have COMPANY_BKP table available, which is a backup of the COMPANY table.

The following example deletes records from the COMPANY table for all the customers, whose AGE is greater than or equal to 27 −

[source]
----

[.iokays-translated-ae213da679f6e68ebb81b763e1dea92a]
testdb=# DELETE FROM COMPANY WHERE AGE IN (SELECT AGE FROM COMPANY_BKP WHERE AGE > 27);


[.iokays-original-ae213da679f6e68ebb81b763e1dea92a]
testdb=# DELETE FROM COMPANY
   WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
      WHERE AGE > 27 );

----
This would affect two rows and finally the COMPANY table would have the following records −

[source]
----

 id | name  | age | address     | salary
----+-------+-----+-------------+--------
  2 | Allen |  25 | Texas       |  15000
  3 | Teddy |  23 | Norway      |  20000
  4 | Mark  |  25 | Rich-Mond   |  65000
  6 | Kim   |  22 | South-Hall  |  45000
  7 | James |  24 | Houston     |  10000
  5 | David |  27 | Texas       |  42500
(6 rows)

----
== PostgreSQL - AUTO INCREMENT

PostgreSQL has the data types smallserial, serial and bigserial; these are not true types, but merely a notational convenience for creating unique identifier columns. These are similar to AUTO_INCREMENT property supported by some other databases.

If you wish a serial column to have a unique constraint or be a primary key, it must now be specified, just like any other data type.

The type name serial creates an integer columns. The type name bigserial creates a bigint column. bigserial should be used if you anticipate the use of more than 231 identifiers over the lifetime of the table. The type name smallserial creates a smallint column.


=== Syntax

The basic usage of *SERIAL* dataype is as follows −

[source]
----

[.iokays-translated-8850aad70d19aee4c18d4c974782f6cd]
CREATE TABLE tablename (colname SERIAL);


[.iokays-original-8850aad70d19aee4c18d4c974782f6cd]
CREATE TABLE tablename (
   colname SERIAL
);

----
=== Example

Consider the COMPANY table to be created as follows −

[source]
----

[.iokays-translated-6b78e738e1493bf3f68fa2c5df743339]
testdb=# CREATE TABLE COMPANY (ID SERIAL PRIMARY KEY, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL);


[.iokays-original-6b78e738e1493bf3f68fa2c5df743339]
testdb=# CREATE TABLE COMPANY(
   ID  SERIAL PRIMARY KEY,
   NAME           TEXT      NOT NULL,
   AGE            INT       NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

----
Now, insert the following records into table COMPANY −

[source]
----

[.iokays-translated-6de1c17d7ac727a5ad20e659e7bf297d]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('Paul', 32, 'California', 20000.00);


[.iokays-original-6de1c17d7ac727a5ad20e659e7bf297d]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'Paul', 32, 'California', 20000.00 );

[.iokays-translated-9569d3737a2ff6a3a73de8a962413fc9]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('Allen', 25, 'Texas', 15000.00);


[.iokays-original-9569d3737a2ff6a3a73de8a962413fc9]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ('Allen', 25, 'Texas', 15000.00 );

[.iokays-translated-ab28de34fca97dc75c8d21297da71af8]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('Teddy', 23, 'Norway', 20000.00);


[.iokays-original-ab28de34fca97dc75c8d21297da71af8]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ('Teddy', 23, 'Norway', 20000.00 );

[.iokays-translated-3721aec068d260404df18c3a03654685]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('Mark', 25, 'Rich-Mond ', 65000.00);


[.iokays-original-3721aec068d260404df18c3a03654685]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'Mark', 25, 'Rich-Mond ', 65000.00 );

[.iokays-translated-1435ac435bd491723969e22fa69eae56]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('David', 27, 'Texas', 85000.00);


[.iokays-original-1435ac435bd491723969e22fa69eae56]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'David', 27, 'Texas', 85000.00 );

[.iokays-translated-02107249397cdb1a0eaf18172a9a6d0e]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('Kim', 22, 'South-Hall', 45000.00);


[.iokays-original-02107249397cdb1a0eaf18172a9a6d0e]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'Kim', 22, 'South-Hall', 45000.00 );

[.iokays-translated-95ae8a946185574916b6454038c67f06]
INSERT INTO COMPANY (NAME, AGE, ADDRESS, SALARY) VALUES ('James', 24, 'Houston', 10000.00);


[.iokays-original-95ae8a946185574916b6454038c67f06]
INSERT INTO COMPANY (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'James', 24, 'Houston', 10000.00 );

----
This will insert seven tuples into the table COMPANY and COMPANY will have the following records −

[source]
----

 id | name  | age | address    | salary
----+-------+-----+------------+--------
  1 | Paul  |  32 | California |  20000
  2 | Allen |  25 | Texas      |  15000
  3 | Teddy |  23 | Norway     |  20000
  4 | Mark  |  25 | Rich-Mond  |  65000
  5 | David |  27 | Texas      |  85000
  6 | Kim   |  22 | South-Hall |  45000
  7 | James |  24 | Houston    |  10000

----
== PostgreSQL - PRIVILEGES

Whenever an object is created in a database, an owner is assigned to it. The owner is usually the one who executed the creation statement. For most kinds of objects, the initial state is that only the owner (or a superuser) can modify or delete the object. To allow other roles or users to use it, privileges or permission must be granted.

Different kinds of privileges in PostgreSQL are −

. SELECT,

. INSERT,

. UPDATE,

. DELETE,

. TRUNCATE,

. REFERENCES,

. TRIGGER,

. CREATE,

. CONNECT,

. TEMPORARY,

. EXECUTE, and

. USAGE

Depending on the type of the object (table, function, etc.,), privileges are applied to the object. To assign privileges to the users, the GRANT command is used.


=== Syntax for GRANT

Basic syntax for GRANT command is as follows −

[source]
----

[.iokays-translated-365caa00b6af2340cbc809b3717e309b]
GRANT privilege [, …] ON object [, …] TO {PUBLIC | GROUP group | username};


[.iokays-original-365caa00b6af2340cbc809b3717e309b]
GRANT privilege [, …​]
ON object [, …​]
TO { PUBLIC | GROUP group | username }

----
. *privilege* − values could be: SELECT, INSERT, UPDATE, DELETE, RULE, ALL.


. *object* − The name of an object to which to grant access. The possible objects are: table, view, sequence


. *PUBLIC* − A short form representing all users.


. GROUP *group* − A group to whom to grant privileges.


. *username* − The name of a user to whom to grant privileges. PUBLIC is a short form representing all users.


The privileges can be revoked using the REVOKE command.


=== Syntax for REVOKE

Basic syntax for REVOKE command is as follows −

[source]
----

[.iokays-translated-4da0aea66788c1c2884f758a36ad53a1]
REVOKE privilege [, …] ON object [, …] FROM {PUBLIC | GROUP groupname | username};


[.iokays-original-4da0aea66788c1c2884f758a36ad53a1]
REVOKE privilege [, …​]
ON object [, …​]
FROM { PUBLIC | GROUP groupname | username }

----
. *privilege* − values could be: SELECT, INSERT, UPDATE, DELETE, RULE, ALL.


. *object* − The name of an object to which to grant access. The possible objects are: table, view, sequence


. *PUBLIC* − A short form representing all users.


. GROUP *group* − A group to whom to grant privileges.


. *username* − The name of a user to whom to grant privileges. PUBLIC is a short form representing all users.



=== Example

To understand the privileges, let us first create a USER as follows −

[source]
----

[.iokays-translated-6a396a1ca58203a15bff22e5620757e4]
testdb=# CREATE USER manisha WITH PASSWORD 'password';CREATE ROLE


[.iokays-original-6a396a1ca58203a15bff22e5620757e4]
testdb=# CREATE USER manisha WITH PASSWORD 'password';
CREATE ROLE

----
The message CREATE ROLE indicates that the USER "manisha" is created.

Consider the table link:../postgresql/company.sql[COMPANY] having records as follows −

[source]
----

[.iokays-translated-ca1d8dad123084b8c51d70b555a2a923]
testdb# select * from COMPANY; id | 名字 | 年龄 | 地址 | 薪资---- 1 | 保罗 | 32 | 加利福尼亚 | 20000 2 | 艾伦 | 25 | 得克萨斯 | 15000 3 | 泰迪 | 23 | 挪威 | 20000 4 | 马克 | 25 | 列治文 | 65000 5 | 大卫 | 27 | 得克萨斯 | 85000 6 | 金 | 22 | 南厅 | 45000 7 | 詹姆斯 | 24 | 休斯顿 | 10000(7 行)----


[.iokays-original-ca1d8dad123084b8c51d70b555a2a923]
testdb# select * from COMPANY;
 id | name  | age | address   | salary
-----------------------------------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----
Next, let us grant all privileges on a table COMPANY to the user "manisha" as follows −

[source]
----

[.iokays-translated-c4d98efbbc31666769705663427fa876]
testdb=# GRANT ALL ON COMPANY TO manisha;GRANT


[.iokays-original-c4d98efbbc31666769705663427fa876]
testdb=# GRANT ALL ON COMPANY TO manisha;
GRANT

----
The message GRANT indicates that all privileges are assigned to the USER.

Next, let us revoke the privileges from the USER "manisha" as follows −

[source]
----

[.iokays-translated-0362db6a5c76ae75a66f7a963e6c8548]
testdb=# REVOKE ALL ON COMPANY FROM manisha;REVOKE


[.iokays-original-0362db6a5c76ae75a66f7a963e6c8548]
testdb=# REVOKE ALL ON COMPANY FROM manisha;
REVOKE

----
The message REVOKE indicates that all privileges are revoked from the USER.

You can even delete the user as follows −

[source]
----

[.iokays-translated-47daeccf88f106318822f0f847523f65]
testdb=# DROP USER manisha;DROP ROLE


[.iokays-original-47daeccf88f106318822f0f847523f65]
testdb=# DROP USER manisha;
DROP ROLE

----
The message DROP ROLE indicates USER ‘Manisha’ is deleted from the database.


== PostgreSQL - DATE/TIME Functions and Operators

We had discussed about the Date/Time data types in the chapter link:../postgresql/postgresql_data_types.html[Data Types]. Now, let us see the Date/Time operators and Functions.

The following table lists the behaviors of the basic arithmetic operators −
[%autowidth]
|===

|Operator|Example|Result
|+|date '2001-09-28' + integer '7'|date '2001-10-05'
|+|date '2001-09-28' + interval '1 hour'|timestamp '2001-09-28 01:00:00'
|+|date '2001-09-28' + time '03:00'|timestamp '2001-09-28 03:00:00'
|+|interval '1 day' + interval '1 hour'|interval '1 day 01:00:00'
|+|timestamp '2001-09-28 01:00' + interval '23 hours'|timestamp '2001-09-29 00:00:00'
|+|time '01:00' + interval '3 hours'|time '04:00:00'
|-|- interval '23 hours'|interval '-23:00:00'
|-|date '2001-10-01' - date '2001-09-28'|integer '3' (days)
|-|date '2001-10-01' - integer '7'|date '2001-09-24'
|-|date '2001-09-28' - interval '1 hour'|timestamp '2001-09-27 23:00:00'
|-|time '05:00' - time '03:00'|interval '02:00:00'
|-|time '05:00' - interval '2 hours'|time '03:00:00'
|-|timestamp '2001-09-28 23:00' - interval '23 hours'|timestamp '2001-09-28 00:00:00'
|-|interval '1 day' - interval '1 hour'|interval '1 day -01:00:00'
|-|timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'|interval '1 day 15:00:00'
|*|900 * interval '1 second'|interval '00:15:00'
|*|21 * interval '1 day'|interval '21 days'
|*|double precision '3.5' * interval '1 hour'|interval '03:30:00'
|/|interval '1 hour' / double precision '1.5'|interval '00:40:00'
|===

The following is the list of all important Date and Time related functions available.
[%autowidth]
|===

|S. No.|Function & Description
|1|link:../postgresql/postgresql_date_time.htm#function_age[AGE()]Subtract arguments

|2|link:../postgresql/postgresql_date_time.htm#function_currentdatetime[CURRENT DATE/TIME()]Current date and time

|3|link:../postgresql/postgresql_date_time.htm#function_datepart[DATE_PART()]Get subfield (equivalent to extract)

|4|link:../postgresql/postgresql_date_time.htm#function_extract[EXTRACT()]Get subfield

|5|link:../postgresql/postgresql_date_time.htm#function_isfinite[ISFINITE()]Test for finite date, time and interval (not +/-infinity)

|6|link:../postgresql/postgresql_date_time.htm#function_justify[JUSTIFY]Adjust interval

|===


=== AGE(timestamp, timestamp), AGE(timestamp)
[%autowidth]
|===

|S. No.|Function & Description
|1|*AGE(timestamp, timestamp)*
When invoked with the TIMESTAMP form of the second argument, AGE() subtract arguments, producing a "symbolic" result that uses years and months and is of type INTERVAL.

|2|*AGE(timestamp)*
When invoked with only the TIMESTAMP as argument, AGE() subtracts from the current_date (at midnight).

|===

Example of the function AGE(timestamp, timestamp) is −

[source]
----

testdb=# SELECT AGE(timestamp '2001-04-10', timestamp '1957-06-13');

----
The above given PostgreSQL statement will produce the following result −

[source]
----

age

----
 43 years 9 mons 27 days

----

Example of the function AGE(timestamp) is −

[source]
----
testdb=# select age(timestamp '1957-06-13');

----

The above given PostgreSQL statement will produce the following result −

[source]
----
           age
--------------------------
 55 years 10 mons 22 days

----


=== CURRENT DATE/TIME()

PostgreSQL provides a number of functions that return values related to the current date and time. Following are some functions −
[%autowidth]
|===

|S. No.|Function & Description
|1|*CURRENT_DATE*
Delivers current date.

|2|*CURRENT_TIME*
Delivers values with time zone.

|3|*CURRENT_TIMESTAMP*
Delivers values with time zone.

|4|*CURRENT_TIME(precision)*
Optionally takes a precision parameter, which causes the result to be rounded to that many fractional digits in the seconds field.

|5|*CURRENT_TIMESTAMP(precision)*
Optionally takes a precision parameter, which causes the result to be rounded to that many fractional digits in the seconds field.

|6|*LOCALTIME*
Delivers values without time zone.

|7|*LOCALTIMESTAMP*
Delivers values without time zone.

|8|*LOCALTIME(precision)*
Optionally takes a precision parameter, which causes the result to be rounded to that many fractional digits in the seconds field.

|9|*LOCALTIMESTAMP(precision)*
Optionally takes a precision parameter, which causes the result to be rounded to that many fractional digits in the seconds field.

|===

Examples using the functions from the table above −

[source]
----
testdb=# SELECT CURRENT_TIME;
       timetz
--------------------
 08:01:34.656+05:30
(1 row)


testdb=# SELECT CURRENT_DATE;
    date
------------
 2013-05-05
(1 row)


testdb=# SELECT CURRENT_TIMESTAMP;
              now
 2013-05-05 08:01:45.375+05:30
(1 row)

testdb=# SELECT CURRENT_TIMESTAMP(2); timestamptz

 2013-05-05 08:01:50.89+05:30
(1 row)


testdb=# SELECT LOCALTIMESTAMP;
       timestamp
------------------------
 2013-05-05 08:01:55.75
(1 row)

----

PostgreSQL also provides functions that return the start time of the current statement, as well as the actual current time at the instant the function is called. These functions are −
[%autowidth]
|===

|S. No.|Function & Description
|1|*transaction_timestamp()*
It is equivalent to CURRENT_TIMESTAMP, but is named to clearly reflect what it returns.

|2|*statement_timestamp()*
It returns the start time of the current statement.

|3|*clock_timestamp()*
It returns the actual current time, and therefore its value changes even within a single SQL command.

|4|*timeofday()*
It returns the actual current time, but as a formatted text string rather than a timestamp with time zone value.

|5|*now()*
It is a traditional PostgreSQL equivalent to transaction_timestamp().

|===


=== DATE_PART(text, timestamp), DATE_PART(text, interval), DATE_TRUNC(text, timestamp)
[%autowidth]
|===

|S. No.|Function & Description
|1|*DATE_PART('field', source)*
These functions get the subfields. The field parameter needs to be a string value, not a name.
The valid field names are: century, day, decade, dow, doy, epoch, hour, isodow, isoyear, microseconds, millennium, milliseconds, minute, month, quarter, second, timezone, timezone_hour, timezone_minute, week, year.

|2|*DATE_TRUNC('field', source)*
This function is conceptually similar to the trunc function for numbers. source is a value expression of type timestamp or interval. field selects to which precision to truncate the input value. The return value is of type timestamp or interval.
The valid values for field are : microseconds, milliseconds, second, minute, hour, day, week, month, quarter, year, decade, century, millennium

|===

The following are examples for DATE_PART('field', source) functions −

[source]
----
testdb=# SELECT date_part('day', TIMESTAMP '2001-02-16 20:38:40');
 date_part
-----------
        16
(1 row)


testdb=# SELECT date_part('hour', INTERVAL '4 hours 3 minutes');
 date_part
-----------
         4
(1 row)

----

The following are examples for DATE_TRUNC('field', source) functions −

[source]
----
testdb=# SELECT date_trunc('hour', TIMESTAMP '2001-02-16 20:38:40');
     date_trunc
---------------------
 2001-02-16 20:00:00
(1 row)


testdb=# SELECT date_trunc('year', TIMESTAMP '2001-02-16 20:38:40');
     date_trunc
---------------------
 2001-01-01 00:00:00
(1 row)

----


=== EXTRACT(field from timestamp), EXTRACT(field from interval)

The *EXTRACT(field FROM source)* function retrieves subfields such as year or hour from date/time values. The source must be a value expression of type timestamp, time, or interval. The field is an identifier or string that selects what field to extract from the source value. The EXTRACT function returns values of type double precision.

The following are valid field names (similar to DATE_PART function field names): century, day, decade, dow, doy, epoch, hour, isodow, isoyear, microseconds, millennium, milliseconds, minute, month, quarter, second, timezone, timezone_hour, timezone_minute, week, year.

The following are examples of EXTRACT('field', source) functions −

[source]
----
testdb=# SELECT EXTRACT(CENTURY FROM TIMESTAMP '2000-12-16 12:21:13');
 date_part
-----------
        20
(1 row)


testdb=# SELECT EXTRACT(DAY FROM TIMESTAMP '2001-02-16 20:38:40');
 date_part
-----------
        16
(1 row)

----


=== ISFINITE(date), ISFINITE(timestamp), ISFINITE(interval)
[%autowidth]
|===

|S. No.|Function & Description
|1|*ISFINITE(date)*
Tests for finite date.

|2|*ISFINITE(timestamp)*
Tests for finite time stamp.

|3|*ISFINITE(interval)*
Tests for finite interval.

|===

The following are the examples of the ISFINITE() functions −

[source]
----
testdb=# SELECT isfinite(date '2001-02-16');
 isfinite
----------
 t
(1 row)


testdb=# SELECT isfinite(timestamp '2001-02-16 21:28:30');
 isfinite
----------
 t
(1 row)


testdb=# SELECT isfinite(interval '4 hours');
 isfinite
----------
 t
(1 row)

----


=== JUSTIFY_DAYS(interval), JUSTIFY_HOURS(interval), JUSTIFY_INTERVAL(interval)
[%autowidth]
|===

|S. No.|Function & Description
|1|*JUSTIFY_DAYS(interval)*
Adjusts interval so 30-day time periods are represented as months. Return the *interval* type

|2|*JUSTIFY_HOURS(interval)*
Adjusts interval so 24-hour time periods are represented as days. Return the *interval* type

|3|*JUSTIFY_INTERVAL(interval)*
Adjusts interval using JUSTIFY_DAYS and JUSTIFY_HOURS, with additional sign adjustments. Return the *interval* type

|===

The following are the examples for the ISFINITE() functions −

[source]
----
testdb=# SELECT justify_days(interval '35 days');
 justify_days
--------------
 1 mon 5 days
(1 row)


testdb=# SELECT justify_hours(interval '27 hours');
 justify_hours
----------------
 1 day 03:00:00
(1 row)


testdb=# SELECT justify_interval(interval '1 mon -1 hour');
 justify_interval
------------------
 29 days 23:00:00
(1 row)

----


== PostgreSQL - Functions

PostgreSQL *functions*, also known as Stored Procedures, allow you to carry out operations that would normally take several queries and round trips in a single function within the database. Functions allow database reuse as other applications can interact directly with your stored procedures instead of a middle-tier or duplicating code.

Functions can be created in a language of your choice like SQL, PL/pgSQL, C, Python, etc.


=== Syntax

The basic syntax to create a function is as follows −

[source]
----
CREATE [OR REPLACE] FUNCTION function_name (arguments)
RETURNS return_datatype AS $variable_name$
   DECLARE
      declaration;
      [...]
   BEGIN
      < function_body >
      [...]
      RETURN { variable_name | value }
   END; LANGUAGE plpgsql;

----

Where,

. *function-name* specifies the name of the function.


. [OR REPLACE] option allows modifying an existing function.


. The function must contain a *return* statement.


. *RETURN* clause specifies that data type you are going to return from the function. The *return_datatype* can be a base, composite, or domain type, or can reference the type of a table column.


. *function-body* contains the executable part.


. The AS keyword is used for creating a standalone function.


. *plpgsql* is the name of the language that the function is implemented in. Here, we use this option for PostgreSQL, it Can be SQL, C, internal, or the name of a user-defined procedural language. For backward compatibility, the name can be enclosed by single quotes.



=== Example

The following example illustrates creating and calling a standalone function. This function returns the total number of records in the COMPANY table. We will use the link:../postgresql/company.sql[COMPANY] table, which has the following records −

[source]
----
testdb# select * from COMPANY;
 id | name  | age | address   | salary
----+-------+-----+-----------+--------
  1 | Paul  |  32 | California|  20000
  2 | Allen |  25 | Texas     |  15000
  3 | Teddy |  23 | Norway    |  20000
  4 | Mark  |  25 | Rich-Mond |  65000
  5 | David |  27 | Texas     |  85000
  6 | Kim   |  22 | South-Hall|  45000
  7 | James |  24 | Houston   |  10000
(7 rows)

----

Function totalRecords() is as follows −

[source]
----
CREATE OR REPLACE FUNCTION totalRecords ()
RETURNS integer AS $total$
declare
	total integer;
BEGIN
   SELECT count(*) into total FROM COMPANY;
   RETURN total;
END;
$total$ LANGUAGE plpgsql;

----

When the above query is executed, the result would be −

[source]
----
testdb# CREATE FUNCTION

----

Now, let us execute a call to this function and check the records in the COMPANY table

[source]
----
testdb=# select totalRecords();

----

When the above query is executed, the result would be −

[source]
----
 totalrecords
--------------
      7
(1 row)

----


== PostgreSQL - Useful Functions

PostgreSQL built-in functions, also called as Aggregate functions, are used for performing processing on string or numeric data.

The following is the list of all general-purpose PostgreSQL built-in functions −

. link:../postgresql/postgresql_count_function.html[PostgreSQL COUNT Function] − The PostgreSQL COUNT aggregate function is used to count the number of rows in a database table.


. link:../postgresql/postgresql_max_function.html[PostgreSQL MAX Function] − The PostgreSQL MAX aggregate function allows us to select the highest (maximum) value for a certain column.


. link:../postgresql/postgresql_min_function.html[PostgreSQL MIN Function] − The PostgreSQL MIN aggregate function allows us to select the lowest (minimum) value for a certain column.


. link:../postgresql/postgresql_avg_function.html[PostgreSQL AVG Function] − The PostgreSQL AVG aggregate function selects the average value for certain table column.


. link:../postgresql/postgresql_sum_function.html[PostgreSQL SUM Function] − The PostgreSQL SUM aggregate function allows selecting the total for a numeric column.


. link:../postgresql/postgresql_array_functions.html[PostgreSQL ARRAY Functions] − The PostgreSQL ARRAY aggregate function puts input values, including nulls, concatenated into an array.


. link:../postgresql/postgresql_numeric_functions.html[PostgreSQL Numeric Functions] − Complete list of PostgreSQL functions required to manipulate numbers in SQL.


. link:../postgresql/postgresql_string_functions.html[PostgreSQL String Functions] − Complete list of PostgreSQL functions required to manipulate strings in PostgreSQL.



== PostgreSQL - C/C++ Interface

This tutorial is going to use *libpqxx* library, which is the official C++ client API for PostgreSQL. The source code for libpqxx is available under the BSD license, so you are free to download it, pass it on to others, change it, sell it, include it in your own code, and share your changes with anyone you choose.


=== Installation

The the latest version of libpqxx is available to be downloaded from the link link:https://pqxx.org/libpqxx/[Download Libpqxx]. So download the latest version and follow the following steps −

[source]
----
wget http://pqxx.org/download/software/libpqxx/libpqxx-4.0.tar.gz
tar xvfz libpqxx-4.0.tar.gz
cd libpqxx-4.0
./configure
make
make install

----

Before you start using C/C++ PostgreSQL interface, find the *pg_hba.conf* file in your PostgreSQL installation directory and add the following line −

[source]
----
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5

----

You can start/restart postgres server in case it is not running using the following command −

[source]
----
[root@host]# service postgresql restart
Stopping postgresql service:                               [  OK  ]
Starting postgresql service:                               [  OK  ]

----


=== C/C++ Interface APIs

The following are important interface routines which can sufice your requirement to work with PostgreSQL database from your C/C++ program. If you are looking for a more sophisticated application then you can look into the libpqxx official documentation, or you can use commercially available APIs.
[%autowidth]
|===

|S. No.|API & Description
|1|*pqxx::connection C( const std::string & dbstring )*
This is a typedef which will be used to connect to the database. Here, dbstring provides required parameters to connect to the datbase, for example *dbname = testdb user = postgres password=pass123 hostaddr=127.0.0.1 port=5432*.
If connection is setup successfully then it creates C with connection object which provides various useful function public function.

|2|*C.is_open()*
The method is_open() is a public method of connection object and returns boolean value. If connection is active, then this method returns true otherwise it returns false.

|3|*C.disconnect()*
This method is used to disconnect an opened database connection.

|4|*pqxx::work W( C )*
This is a typedef which will be used to create a transactional object using connection C, which ultimately will be used to execute SQL statements in transactional mode.
If transaction object gets created successfully, then it is assigned to variable W which will be used to access public methods related to transactional object.

|5|*W.exec(const std::string & sql)*
This public method from transactional object will be used to execute SQL statement.


|6|*W.commit()*
This public method from transactional object will be used to commit the transaction.


|7|*W.abort()*
This public method from transactional object will be used to rollback the transaction.


|8|*pqxx::nontransaction N( C )*
This is a typedef which will be used to create a non-transactional object using connection C, which ultimately will be used to execute SQL statements in non-transactional mode.
If transaction object gets created successfully, then it is assigned to variable N which will be used to access public methods related to non-transactional object.

|9|*N.exec(const std::string & sql)*
This public method from non-transactional object will be used to execute SQL statement and returns a result object which is actually an interator holding all the returned records.

|===


=== Connecting To Database

The following C code segment shows how to connect to an existing database running on local machine at port 5432. Here, I used backslash \ for line continuation.

[source]
----
#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
   try {
      connection C("dbname = testdb user = postgres password = cohondob \
      hostaddr = 127.0.0.1 port = 5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }
      C.disconnect ();
   } catch (const std::exception &e) {
      cerr << e.what() << std::endl;
      return 1;
   }
}

----

Now, let us compile and run the above program to connect to our database *testdb*, which is already available in your schema and can be accessed using user postgres and password pass123.

You can use the user ID and password based on your database setting. Remember to keep the -lpqxx and -lpq in the given order! Otherwise, the linker will complain bitterly about the missing functions with names starting with "PQ."

[source]
----
$g++ test.cpp -lpqxx -lpq
$./a.out
Opened database successfully: testdb

----


=== Create a Table

The following C code segment will be used to create a table in previously created database −

[source]
----
#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
   char * sql;

   try {
      connection C("dbname = testdb user = postgres password = cohondob \
      hostaddr = 127.0.0.1 port = 5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }

      /* Create SQL statement */
      sql = "CREATE TABLE COMPANY("  \
      "ID INT PRIMARY KEY     NOT NULL," \
      "NAME           TEXT    NOT NULL," \
      "AGE            INT     NOT NULL," \
      "ADDRESS        CHAR(50)," \
      "SALARY         REAL );";

      /* Create a transactional object. */
      work W(C);

      /* Execute SQL query */
      W.exec( sql );
      W.commit();
      cout << "Table created successfully" << endl;
      C.disconnect ();
   } catch (const std::exception &e) {
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}

----

When the above given program is compiled and executed, it will create COMPANY table in your testdb database and will display the following statements −

[source]
----
Opened database successfully: testdb
Table created successfully

----


=== INSERT Operation

The following C code segment shows how we can create records in our COMPANY table created in above example −

[source]
----
#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
   char * sql;

   try {
      connection C("dbname = testdb user = postgres password = cohondob \
      hostaddr = 127.0.0.1 port = 5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }

      /* Create SQL statement */
      sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
         "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
         "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
         "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
         "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
         "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
         "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
         "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

      /* Create a transactional object. */
      work W(C);

      /* Execute SQL query */
      W.exec( sql );
      W.commit();
      cout << "Records created successfully" << endl;
      C.disconnect ();
   } catch (const std::exception &e) {
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}

----

When the above given program is compiled and executed, it will create given records in COMPANY table and will display the following two lines −

[source]
----
Opened database successfully: testdb
Records created successfully

----


=== SELECT Operation

The following C code segment shows how we can fetch and display records from our COMPANY table created in above example −

[source]
----
#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
   char * sql;

   try {
      connection C("dbname = testdb user = postgres password = cohondob \
      hostaddr = 127.0.0.1 port = 5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }

      /* Create SQL statement */
      sql = "SELECT * from COMPANY";

      /* Create a non-transactional object. */
      nontransaction N(C);

      /* Execute SQL query */
      result R( N.exec( sql ));

      /* List down all the records */
      for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
         cout << "ID = " << c[0].as<int>() << endl;
         cout << "Name = " << c[1].as<string>() << endl;
         cout << "Age = " << c[2].as<int>() << endl;
         cout << "Address = " << c[3].as<string>() << endl;
         cout << "Salary = " << c[4].as<float>() << endl;
      }
      cout << "Operation done successfully" << endl;
      C.disconnect ();
   } catch (const std::exception &e) {
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}

----

When the above given program is compiled and executed, it will produce the following result −

[source]
----
Opened database successfully: testdb
ID = 1
Name = Paul
Age = 32
Address = California
Salary = 20000
ID = 2
Name = Allen
Age = 25
Address = Texas
Salary = 15000
ID = 3
Name = Teddy
Age = 23
Address = Norway
Salary = 20000
ID = 4
Name = Mark
Age = 25
Address = Rich-Mond
Salary = 65000
Operation done successfully

----


=== UPDATE Operation

The following C code segment shows how we can use the UPDATE statement to update any record and then fetch and display updated records from our COMPANY table −

[source]
----
#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
   char * sql;

   try {
      connection C("dbname = testdb user = postgres password = cohondob \
      hostaddr = 127.0.0.1 port = 5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }

      /* Create a transactional object. */
      work W(C);
      /* Create  SQL UPDATE statement */
      sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1";
      /* Execute SQL query */
      W.exec( sql );
      W.commit();
      cout << "Records updated successfully" << endl;

      /* Create SQL SELECT statement */
      sql = "SELECT * from COMPANY";

      /* Create a non-transactional object. */
      nontransaction N(C);

      /* Execute SQL query */
      result R( N.exec( sql ));

      /* List down all the records */
      for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
         cout << "ID = " << c[0].as<int>() << endl;
         cout << "Name = " << c[1].as<string>() << endl;
         cout << "Age = " << c[2].as<int>() << endl;
         cout << "Address = " << c[3].as<string>() << endl;
         cout << "Salary = " << c[4].as<float>() << endl;
      }
      cout << "Operation done successfully" << endl;
      C.disconnect ();
   } catch (const std::exception &e) {
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}

----

When the above given program is compiled and executed, it will produce the following result −

[source]
----
Opened database successfully: testdb
Records updated successfully
ID = 2
Name = Allen
Age = 25
Address = Texas
Salary = 15000
ID = 3
Name = Teddy
Age = 23
Address = Norway
Salary = 20000
ID = 4
Name = Mark
Age = 25
Address = Rich-Mond
Salary = 65000
ID = 1
Name = Paul
Age = 32
Address = California
Salary = 25000
Operation done successfully

----


=== DELETE Operation

The following C code segment shows how we can use the DELETE statement to delete any record and then fetch and display remaining records from our COMPANY table −

[source]
----
#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

int main(int argc, char* argv[]) {
   char * sql;

   try {
      connection C("dbname = testdb user = postgres password = cohondob \
      hostaddr = 127.0.0.1 port = 5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }

      /* Create a transactional object. */
      work W(C);
      /* Create  SQL DELETE statement */
      sql = "DELETE from COMPANY where ID = 2";
      /* Execute SQL query */
      W.exec( sql );
      W.commit();
      cout << "Records deleted successfully" << endl;

      /* Create SQL SELECT statement */
      sql = "SELECT * from COMPANY";

      /* Create a non-transactional object. */
      nontransaction N(C);

      /* Execute SQL query */
      result R( N.exec( sql ));

      /* List down all the records */
      for (result::const_iterator c = R.begin(); c != R.end(); ++c) {
         cout << "ID = " << c[0].as<int>() << endl;
         cout << "Name = " << c[1].as<string>() << endl;
         cout << "Age = " << c[2].as<int>() << endl;
         cout << "Address = " << c[3].as<string>() << endl;
         cout << "Salary = " << c[4].as<float>() << endl;
      }
      cout << "Operation done successfully" << endl;
      C.disconnect ();
   } catch (const std::exception &e) {
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}

----

When the above given program is compiled and executed, it will produce the following result −

[source]
----
Opened database successfully: testdb
Records deleted successfully
ID = 3
Name = Teddy
Age = 23
Address = Norway
Salary = 20000
ID = 4
Name = Mark
Age = 25
Address = Rich-Mond
Salary = 65000
ID = 1
Name = Paul
Age = 32
Address = California
Salary = 25000
Operation done successfully

----


== PostgreSQL - JAVA Interface


=== Installation

Before we start using PostgreSQL in our Java programs, we need to make sure that we have PostgreSQL JDBC and Java set up on the machine. You can check Java tutorial for Java installation on your machine. Now let us check how to set up PostgreSQL JDBC driver.

. Download the latest version of postgresql-(VERSION).jdbc.jar from link:https://jdbc.postgresql.org/download/[postgresql-jdbc] repository.


. Add downloaded jar file postgresql-(VERSION).jdbc.jar in your class path, or you can use it along with -classpath option as explained below in the examples.


The following section assumes you have little knowledge about Java JDBC concepts. If you do not have, then it is suggested to spent half and hour with link:../jdbc/jdbc-create-database.html[JDBC Tutorial] to become comfortable with concepts explained below.


=== Connecting To Database

The following Java code shows how to connect to an existing database. If the database does not exist, then it will be created and finally a database object will be returned.

[source]
----
import java.sql.Connection;
import java.sql.DriverManager;

public class PostgreSQLJDBC {
   public static void main(String args[]) {
      Connection c = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "postgres", "123");
      } catch (Exception e) {
         e.printStackTrace();
         System.err.println(e.getClass().getName()+": "+e.getMessage());
         System.exit(0);
      }
      System.out.println("Opened database successfully");
   }
}

----

Before you compile and run above program, find *pg_hba.conf* file in your PostgreSQL installation directory and add the following line −

[source]
----
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5

----

You can start/restart the postgres server in case it is not running using the following command −

[source]
----
[root@host]# service postgresql restart
Stopping postgresql service:                               [  OK  ]
Starting postgresql service:                               [  OK  ]

----

Now, let us compile and run the above program to connect with testdb. Here, we are using *postgres* as user ID and *123* as password to access the database. You can change this as per your database configuration and setup. We are also assuming current version of JDBC driver *postgresql-9.2-1002.jdbc3.jar* is available in the current path.

[source]
----
C:\JavaPostgresIntegration>javac PostgreSQLJDBC.java
C:\JavaPostgresIntegration>java -cp c:\tools\postgresql-9.2-1002.jdbc3.jar;C:\JavaPostgresIntegration PostgreSQLJDBC
Open database successfully

----


=== Create a Table

The following Java program will be used to create a table in previously opened database. Make sure you do not have this table already in your target database.

[source]
----
import java.sql.*;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;


public class PostgreSQLJDBC {
   public static void main( String args[] ) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         System.out.println("Opened database successfully");

         stmt = c.createStatement();
         String sql = "CREATE TABLE COMPANY " +
            "(ID INT PRIMARY KEY     NOT NULL," +
            " NAME           TEXT    NOT NULL, " +
            " AGE            INT     NOT NULL, " +
            " ADDRESS        CHAR(50), " +
            " SALARY         REAL)";
         stmt.executeUpdate(sql);
         stmt.close();
         c.close();
      } catch ( Exception e ) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Table created successfully");
   }
}

----

When a program is compiled and executed, it will create the COMPANY table in *testdb* database and will display the following two lines −

[source]
----
Opened database successfully
Table created successfully

----


=== INSERT Operation

The following Java program shows how we can create records in our COMPANY table created in above example −

[source]
----
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class PostgreSQLJDBC {
   public static void main(String args[]) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         c.setAutoCommit(false);
         System.out.println("Opened database successfully");

         stmt = c.createStatement();
         String sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (1, 'Paul', 32, 'California', 20000.00 );";
         stmt.executeUpdate(sql);

         sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (2, 'Allen', 25, 'Texas', 15000.00 );";
         stmt.executeUpdate(sql);

         sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );";
         stmt.executeUpdate(sql);

         sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "
            + "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
         stmt.executeUpdate(sql);

         stmt.close();
         c.commit();
         c.close();
      } catch (Exception e) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Records created successfully");
   }
}

----

When the above program is compiled and executed, it will create given records in COMPANY table and will display the following two lines −

[source]
----
Opened database successfully
Records created successfully

----


=== SELECT Operation

The following Java program shows how we can fetch and display records from our COMPANY table created in above example −

[source]
----
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class PostgreSQLJDBC {
   public static void main( String args[] ) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         c.setAutoCommit(false);
         System.out.println("Opened database successfully");

         stmt = c.createStatement();
         ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" );
         while ( rs.next() ) {
            int id = rs.getInt("id");
            String  name = rs.getString("name");
            int age  = rs.getInt("age");
            String  address = rs.getString("address");
            float salary = rs.getFloat("salary");
            System.out.println( "ID = " + id );
            System.out.println( "NAME = " + name );
            System.out.println( "AGE = " + age );
            System.out.println( "ADDRESS = " + address );
            System.out.println( "SALARY = " + salary );
            System.out.println();
         }
         rs.close();
         stmt.close();
         c.close();
      } catch ( Exception e ) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Operation done successfully");
   }
}

----

When the program is compiled and executed, it will produce the following result −

[source]
----
Opened database successfully
ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 20000.0

ID = 2
NAME = Allen
AGE = 25
ADDRESS = Texas
SALARY = 15000.0

ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0

ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0

Operation done successfully

----


=== UPDATE Operation

The following Java code shows how we can use the UPDATE statement to update any record and then fetch and display updated records from our COMPANY table −

[source]
----
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class PostgreSQLJDBC {
   public static void main( String args[] ) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         c.setAutoCommit(false);
         System.out.println("Opened database successfully");

         stmt = c.createStatement();
         String sql = "UPDATE COMPANY set SALARY = 25000.00 where ID=1;";
         stmt.executeUpdate(sql);
         c.commit();

         ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" );
         while ( rs.next() ) {
            int id = rs.getInt("id");
            String  name = rs.getString("name");
            int age  = rs.getInt("age");
            String  address = rs.getString("address");
            float salary = rs.getFloat("salary");
            System.out.println( "ID = " + id );
            System.out.println( "NAME = " + name );
            System.out.println( "AGE = " + age );
            System.out.println( "ADDRESS = " + address );
            System.out.println( "SALARY = " + salary );
            System.out.println();
         }
         rs.close();
         stmt.close();
         c.close();
      } catch ( Exception e ) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Operation done successfully");
   }
}

----

When the program is compiled and executed, it will produce the following result −

[source]
----
Opened database successfully
ID = 2
NAME = Allen
AGE = 25
ADDRESS = Texas
SALARY = 15000.0

ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0

ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0

ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 25000.0

Operation done successfully

----


=== DELETE Operation

The following Java code shows how we can use the DELETE statement to delete any record and then fetch and display remaining records from our COMPANY table −

[source]
----
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class PostgreSQLJDBC6 {
   public static void main( String args[] ) {
      Connection c = null;
      Statement stmt = null;
      try {
         Class.forName("org.postgresql.Driver");
         c = DriverManager
            .getConnection("jdbc:postgresql://localhost:5432/testdb",
            "manisha", "123");
         c.setAutoCommit(false);
         System.out.println("Opened database successfully");

         stmt = c.createStatement();
         String sql = "DELETE from COMPANY where ID = 2;";
         stmt.executeUpdate(sql);
         c.commit();

         ResultSet rs = stmt.executeQuery( "SELECT * FROM COMPANY;" );
         while ( rs.next() ) {
            int id = rs.getInt("id");
            String  name = rs.getString("name");
            int age  = rs.getInt("age");
            String  address = rs.getString("address");
            float salary = rs.getFloat("salary");
            System.out.println( "ID = " + id );
            System.out.println( "NAME = " + name );
            System.out.println( "AGE = " + age );
            System.out.println( "ADDRESS = " + address );
            System.out.println( "SALARY = " + salary );
            System.out.println();
         }
         rs.close();
         stmt.close();
         c.close();
      } catch ( Exception e ) {
         System.err.println( e.getClass().getName()+": "+ e.getMessage() );
         System.exit(0);
      }
      System.out.println("Operation done successfully");
   }
}

----

When the program is compiled and executed, it will produce the following result −

[source]
----
Opened database successfully
ID = 3
NAME = Teddy
AGE = 23
ADDRESS = Norway
SALARY = 20000.0

ID = 4
NAME = Mark
AGE = 25
ADDRESS = Rich-Mond
SALARY = 65000.0

ID = 1
NAME = Paul
AGE = 32
ADDRESS = California
SALARY = 25000.0
Operation done successfully

----


== PostgreSQL - PHP Interface


=== Installation

The PostgreSQL extension is enabled by default in the latest releases of PHP 5.3.x. It is possible to disable it by using *--without-pgsql* at compile time. Still you can use yum command to install PHP -PostgreSQL interface −

[source]
----
yum install php-pgsql

----

Before you start using the PHP PostgreSQL interface, find the *pg_hba.conf* file in your PostgreSQL installation directory and add the following line −

[source]
----
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5

----

You can start/restart the postgres server, in case it is not running, using the following command −

[source]
----
[root@host]# service postgresql restart
Stopping postgresql service:                               [  OK  ]
Starting postgresql service:                               [  OK  ]

----

Windows users must enable php_pgsql.dll in order to use this extension. This DLL is included with Windows distributions in the latest releases of PHP 5.3.x

For detailed installation instructions, kindly check our PHP tutorial and its official website.


=== PHP Interface APIs

The following are important PHP routines, which can suffice your requirement to work with PostgreSQL database from your PHP program. If you are looking for a more sophisticated application, then you can look into the PHP official documentation.
[%autowidth]
|===

|S. No.|API & Description
|1|*resource pg_connect ( string $connection_string [, int $connect_type ] )*
This opens a connection to a PostgreSQL database specified by the connection_string.
If PGSQL_CONNECT_FORCE_NEW is passed as connect_type, then a new connection is created in case of a second call to pg_connect(), even if the connection_string is identical to an existing connection.

|2|*bool pg_connection_reset ( resource $connection )*
This routine resets the connection. It is useful for error recovery. Returns TRUE on success or FALSE on failure.

|3|*int pg_connection_status ( resource $connection )*
This routine returns the status of the specified connection. Returns PGSQL_CONNECTION_OK or PGSQL_CONNECTION_BAD.

|4|*string pg_dbname ([ resource $connection ] )*
This routine returns the name of the database that the given PostgreSQL connection resource.

|5|*resource pg_prepare ([ resource $connection ], string $stmtname, string $query )*
This submits a request to create a prepared statement with the given parameters and waits for completion.

|6|*resource pg_execute ([ resource $connection ], string $stmtname, array $params )*
This routine sends a request to execute a prepared statement with given parameters and waits for the result.

|7|*resource pg_query ([ resource $connection ], string $query )*
This routine executes the query on the specified database connection.

|8|*array pg_fetch_row ( resource $result [, int $row ] )*
This routine fetches one row of data from the result associated with the specified result resource.

|9|*array pg_fetch_all ( resource $result )*
This routine returns an array that contains all rows (records) in the result resource.

|10|*int pg_affected_rows ( resource $result )*
This routine returns the number of rows affected by INSERT, UPDATE, and DELETE queries.

|11|*int pg_num_rows ( resource $result )*
This routine returns the number of rows in a PostgreSQL result resource for example number of rows returned by SELECT statement.

|12|*bool pg_close ([ resource $connection ] )*
This routine closes the non-persistent connection to a PostgreSQL database associated with the given connection resource.

|13|*string pg_last_error ([ resource $connection ] )*
This routine returns the last error message for a given connection.

|14|*string pg_escape_literal ([ resource $connection ], string $data )*
This routine escapes a literal for insertion into a text field.

|15|*string pg_escape_string ([ resource $connection ], string $data )*
This routine escapes a string for querying the database.

|===


=== Connecting to Database

The following PHP code shows how to connect to an existing database on a local machine and finally a database connection object will be returned.

[source]
----
<?php
   $host        = "host = 127.0.0.1";
   $port        = "port = 5432";
   $dbname      = "dbname = testdb";
   $credentials = "user = postgres password=pass123";

   $db = pg_connect( "$host $port $dbname $credentials"  );
   if(!$db) {
      echo "Error : Unable to open database\n";
   } else {
      echo "Opened database successfully\n";
   }
?>

----

Now, let us run the above given program to open our database *testdb*: if the database is successfully opened, then it will give the following message −

[source]
----
Opened database successfully

----


=== Create a Table

The following PHP program will be used to create a table in a previously created database −

[source]
----
<?php
   $host        = "host = 127.0.0.1";
   $port        = "port = 5432";
   $dbname      = "dbname = testdb";
   $credentials = "user = postgres password=pass123";

   $db = pg_connect( "$host $port $dbname $credentials"  );
   if(!$db) {
      echo "Error : Unable to open database\n";
   } else {
      echo "Opened database successfully\n";
   }

   $sql =<<<EOF
      CREATE TABLE COMPANY
      (ID INT PRIMARY KEY     NOT NULL,
      NAME           TEXT    NOT NULL,
      AGE            INT     NOT NULL,
      ADDRESS        CHAR(50),
      SALARY         REAL);
EOF;

   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
   } else {
      echo "Table created successfully\n";
   }
   pg_close($db);
?>

----

When the above given program is executed, it will create COMPANY table in your *testdb* and it will display the following messages −

[source]
----
Opened database successfully
Table created successfully

----


=== INSERT Operation

The following PHP program shows how we can create records in our COMPANY table created in above example −

[source]
----
<?php
   $host        = "host=127.0.0.1";
   $port        = "port=5432";
   $dbname      = "dbname = testdb";
   $credentials = "user = postgres password=pass123";

   $db = pg_connect( "$host $port $dbname $credentials"  );
   if(!$db) {
      echo "Error : Unable to open database\n";
   } else {
      echo "Opened database successfully\n";
   }

   $sql =<<<EOF
      INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
      VALUES (1, 'Paul', 32, 'California', 20000.00 );

      INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
      VALUES (2, 'Allen', 25, 'Texas', 15000.00 );

      INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
      VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );

      INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
      VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );
EOF;

   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
   } else {
      echo "Records created successfully\n";
   }
   pg_close($db);
?>

----

When the above given program is executed, it will create the given records in COMPANY table and will display the following two lines −

[source]
----
Opened database successfully
Records created successfully

----


=== SELECT Operation

The following PHP program shows how we can fetch and display records from our COMPANY table created in above example −

[source]
----
<?php
   $host        = "host = 127.0.0.1";
   $port        = "port = 5432";
   $dbname      = "dbname = testdb";
   $credentials = "user = postgres password=pass123";

   $db = pg_connect( "$host $port $dbname $credentials"  );
   if(!$db) {
      echo "Error : Unable to open database\n";
   } else {
      echo "Opened database successfully\n";
   }

   $sql =<<<EOF
      SELECT * from COMPANY;
EOF;

   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
      exit;
   }
   while($row = pg_fetch_row($ret)) {
      echo "ID = ". $row[0] . "\n";
      echo "NAME = ". $row[1] ."\n";
      echo "ADDRESS = ". $row[2] ."\n";
      echo "SALARY =  ".$row[4] ."\n\n";
   }
   echo "Operation done successfully\n";
   pg_close($db);
?>

----

When the above given program is executed, it will produce the following result. Keep a note that fields are returned in the sequence they were used while creating table.

[source]
----
Opened database successfully
ID = 1
NAME = Paul
ADDRESS = California
SALARY =  20000

ID = 2
NAME = Allen
ADDRESS = Texas
SALARY =  15000

ID = 3
NAME = Teddy
ADDRESS = Norway
SALARY =  20000

ID = 4
NAME = Mark
ADDRESS = Rich-Mond
SALARY =  65000

Operation done successfully

----


=== UPDATE Operation

The following PHP code shows how we can use the UPDATE statement to update any record and then fetch and display updated records from our COMPANY table −

[source]
----
<?php
   $host        = "host=127.0.0.1";
   $port        = "port=5432";
   $dbname      = "dbname = testdb";
   $credentials = "user = postgres password=pass123";

   $db = pg_connect( "$host $port $dbname $credentials"  );
   if(!$db) {
      echo "Error : Unable to open database\n";
   } else {
      echo "Opened database successfully\n";
   }
   $sql =<<<EOF
      UPDATE COMPANY set SALARY = 25000.00 where ID=1;
EOF;
   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
      exit;
   } else {
      echo "Record updated successfully\n";
   }

   $sql =<<<EOF
      SELECT * from COMPANY;
EOF;

   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
      exit;
   }
   while($row = pg_fetch_row($ret)) {
      echo "ID = ". $row[0] . "\n";
      echo "NAME = ". $row[1] ."\n";
      echo "ADDRESS = ". $row[2] ."\n";
      echo "SALARY =  ".$row[4] ."\n\n";
   }
   echo "Operation done successfully\n";
   pg_close($db);
?>

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
Record updated successfully
ID = 2
NAME = Allen
ADDRESS = 25
SALARY =  15000

ID = 3
NAME = Teddy
ADDRESS = 23
SALARY =  20000

ID = 4
NAME = Mark
ADDRESS = 25
SALARY =  65000

ID = 1
NAME = Paul
ADDRESS = 32
SALARY =  25000

Operation done successfully

----


=== DELETE Operation

The following PHP code shows how we can use the DELETE statement to delete any record and then fetch and display the remaining records from our COMPANY table −

[source]
----
<?php
   $host        = "host = 127.0.0.1";
   $port        = "port = 5432";
   $dbname      = "dbname = testdb";
   $credentials = "user = postgres password=pass123";

   $db = pg_connect( "$host $port $dbname $credentials"  );
   if(!$db) {
      echo "Error : Unable to open database\n";
   } else {
      echo "Opened database successfully\n";
   }
   $sql =<<<EOF
      DELETE from COMPANY where ID=2;
EOF;
   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
      exit;
   } else {
      echo "Record deleted successfully\n";
   }

   $sql =<<<EOF
      SELECT * from COMPANY;
EOF;

   $ret = pg_query($db, $sql);
   if(!$ret) {
      echo pg_last_error($db);
      exit;
   }
   while($row = pg_fetch_row($ret)) {
      echo "ID = ". $row[0] . "\n";
      echo "NAME = ". $row[1] ."\n";
      echo "ADDRESS = ". $row[2] ."\n";
      echo "SALARY =  ".$row[4] ."\n\n";
   }
   echo "Operation done successfully\n";
   pg_close($db);
?>

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
Record deleted successfully
ID = 3
NAME = Teddy
ADDRESS = 23
SALARY =  20000

ID = 4
NAME = Mark
ADDRESS = 25
SALARY =  65000

ID = 1
NAME = Paul
ADDRESS = 32
SALARY =  25000

Operation done successfully

----


== PostgreSQL - Perl Interface


=== Installation

The PostgreSQL can be integrated with Perl using Perl DBI module, which is a database access module for the Perl programming language. It defines a set of methods, variables and conventions that provide a standard database interface.

Here are simple steps to install DBI module on your Linux/Unix machine −

[source]
----
$ wget http://search.cpan.org/CPAN/authors/id/T/TI/TIMB/DBI-1.625.tar.gz
$ tar xvfz DBI-1.625.tar.gz
$ cd DBI-1.625
$ perl Makefile.PL
$ make
$ make install

----

If you need to install SQLite driver for DBI, then it can be installed as follows −

[source]
----
$ wget http://search.cpan.org/CPAN/authors/id/T/TU/TURNSTEP/DBD-Pg-2.19.3.tar.gz
$ tar xvfz DBD-Pg-2.19.3.tar.gz
$ cd DBD-Pg-2.19.3
$ perl Makefile.PL
$ make
$ make install

----

Before you start using Perl PostgreSQL interface, find the *pg_hba.conf* file in your PostgreSQL installation directory and add the following line −

[source]
----
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5

----

You can start/restart the postgres server, in case it is not running, using the following command −

[source]
----
[root@host]# service postgresql restart
Stopping postgresql service:                               [  OK  ]
Starting postgresql service:                               [  OK  ]

----


=== DBI Interface APIs

Following are the important DBI routines, which can suffice your requirement to work with SQLite database from your Perl program. If you are looking for a more sophisticated application, then you can look into Perl DBI official documentation.
[%autowidth]
|===

|S. No.|API & Description
|1|*DBI→connect($data_source, "userid", "password", \%attr)*
Establishes a database connection, or session, to the requested $data_source. Returns a database handle object if the connection succeeds.
Datasource has the form like : *DBI:Pg:dbname=$database;host=127.0.0.1;port=5432* Pg is PostgreSQL driver name and testdb is the name of database.

|2|*$dbh→do($sql)*
This routine prepares and executes a single SQL statement. Returns the number of rows affected or undef on error. A return value of -1 means the number of rows is not known, not applicable, or not available. Here $dbh is a handle returned by DBI→connect() call.

|3|*$dbh→prepare($sql)*
This routine prepares a statement for later execution by the database engine and returns a reference to a statement handle object.

|4|*$sth→execute()*
This routine performs whatever processing is necessary to execute the prepared statement. An undef is returned if an error occurs. A successful execute always returns true regardless of the number of rows affected. Here $sth is a statement handle returned by $dbh→prepare($sql) call.

|5|*$sth→fetchrow_array()*
This routine fetches the next row of data and returns it as a list containing the field values. Null fields are returned as undef values in the list.

|6|*$DBI::err*
This is equivalent to $h→err, where $h is any of the handle types like $dbh, $sth, or $drh. This returns native database engine error code from the last driver method called.

|7|*$DBI::errstr*
This is equivalent to $h→errstr, where $h is any of the handle types like $dbh, $sth, or $drh. This returns the native database engine error message from the last DBI method called.

|8|*$dbh->disconnect()*
This routine closes a database connection previously opened by a call to DBI→connect().

|===


=== Connecting to Database

The following Perl code shows how to connect to an existing database. If the database does not exist, then it will be created and finally a database object will be returned.

[source]
----
#!/usr/bin/perl

use DBI;
use strict;

my $driver  = "Pg";
my $database = "testdb";
my $dsn = "DBI:$driver:dbname = $database;host = 127.0.0.1;port = 5432";
my $userid = "postgres";
my $password = "pass123";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;

print "Opened database successfully\n";

----

Now, let us run the above given program to open our database *testdb*; if the database is successfully opened then it will give the following message −

[source]
----
Open database successfully

----


=== Create a Table

The following Perl program will be used to create a table in previously created database −

[source]
----
#!/usr/bin/perl

use DBI;
use strict;

my $driver   = "Pg";
my $database = "testdb";
my $dsn = "DBI:$driver:dbname=$database;host=127.0.0.1;port=5432";
my $userid = "postgres";
my $password = "pass123";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;
print "Opened database successfully\n";

my $stmt = qq(CREATE TABLE COMPANY
      (ID INT PRIMARY KEY     NOT NULL,
      NAME           TEXT    NOT NULL,
      AGE            INT     NOT NULL,
      ADDRESS        CHAR(50),
      SALARY         REAL););
my $rv = $dbh->do($stmt);
if($rv < 0) {
   print $DBI::errstr;
} else {
   print "Table created successfully\n";
}
$dbh->disconnect();

----

When the above given program is executed, it will create COMPANY table in your *testdb* and it will display the following messages −

[source]
----
Opened database successfully
Table created successfully

----


=== INSERT Operation

The following Perl program shows how we can create records in our COMPANY table created in above example −

[source]
----
#!/usr/bin/perl

use DBI;
use strict;

my $driver   = "Pg";
my $database = "testdb";
my $dsn = "DBI:$driver:dbname = $database;host = 127.0.0.1;port = 5432";
my $userid = "postgres";
my $password = "pass123";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;
print "Opened database successfully\n";

my $stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
   VALUES (1, 'Paul', 32, 'California', 20000.00 ));
my $rv = $dbh->do($stmt) or die $DBI::errstr;

$stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
   VALUES (2, 'Allen', 25, 'Texas', 15000.00 ));
$rv = $dbh->do($stmt) or die $DBI::errstr;

$stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
   VALUES (3, 'Teddy', 23, 'Norway', 20000.00 ));
$rv = $dbh->do($stmt) or die $DBI::errstr;

$stmt = qq(INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)
   VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 ););
$rv = $dbh->do($stmt) or die $DBI::errstr;

print "Records created successfully\n";
$dbh->disconnect();

----

When the above given program is executed, it will create given records in COMPANY table and will display the following two lines −

[source]
----
Opened database successfully
Records created successfully

----


=== SELECT Operation

The following Perl program shows how we can fetch and display records from our COMPANY table created in above example −

[source]
----
#!/usr/bin/perl

use DBI;
use strict;

my $driver   = "Pg";
my $database = "testdb";
my $dsn = "DBI:$driver:dbname = $database;host = 127.0.0.1;port = 5432";
my $userid = "postgres";
my $password = "pass123";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;
print "Opened database successfully\n";

my $stmt = qq(SELECT id, name, address, salary  from COMPANY;);
my $sth = $dbh->prepare( $stmt );
my $rv = $sth->execute() or die $DBI::errstr;
if($rv < 0) {
   print $DBI::errstr;
}
while(my @row = $sth->fetchrow_array()) {
      print "ID = ". $row[0] . "\n";
      print "NAME = ". $row[1] ."\n";
      print "ADDRESS = ". $row[2] ."\n";
      print "SALARY =  ". $row[3] ."\n\n";
}
print "Operation done successfully\n";
$dbh->disconnect();

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
ID = 1
NAME = Paul
ADDRESS = California
SALARY =  20000

ID = 2
NAME = Allen
ADDRESS = Texas
SALARY =  15000

ID = 3
NAME = Teddy
ADDRESS = Norway
SALARY =  20000

ID = 4
NAME = Mark
ADDRESS = Rich-Mond
SALARY =  65000

Operation done successfully

----


=== UPDATE Operation

The following Perl code shows how we can use the UPDATE statement to update any record and then fetch and display updated records from our COMPANY table −

[source]
----
#!/usr/bin/perl

use DBI;
use strict;

my $driver   = "Pg";
my $database = "testdb";
my $dsn = "DBI:$driver:dbname = $database;host = 127.0.0.1;port = 5432";
my $userid = "postgres";
my $password = "pass123";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;
print "Opened database successfully\n";

my $stmt = qq(UPDATE COMPANY set SALARY = 25000.00 where ID=1;);
my $rv = $dbh->do($stmt) or die $DBI::errstr;
if( $rv < 0 ) {
   print $DBI::errstr;
}else{
   print "Total number of rows updated : $rv\n";
}
$stmt = qq(SELECT id, name, address, salary  from COMPANY;);
my $sth = $dbh->prepare( $stmt );
$rv = $sth->execute() or die $DBI::errstr;
if($rv < 0) {
   print $DBI::errstr;
}
while(my @row = $sth->fetchrow_array()) {
      print "ID = ". $row[0] . "\n";
      print "NAME = ". $row[1] ."\n";
      print "ADDRESS = ". $row[2] ."\n";
      print "SALARY =  ". $row[3] ."\n\n";
}
print "Operation done successfully\n";
$dbh->disconnect();

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
Total number of rows updated : 1
ID = 1
NAME = Paul
ADDRESS = California
SALARY =  25000

ID = 2
NAME = Allen
ADDRESS = Texas
SALARY =  15000

ID = 3
NAME = Teddy
ADDRESS = Norway
SALARY =  20000

ID = 4
NAME = Mark
ADDRESS = Rich-Mond
SALARY =  65000

Operation done successfully

----


=== DELETE Operation

The following Perl code shows how we can use the DELETE statement to delete any record and then fetch and display the remaining records from our COMPANY table −

[source]
----
#!/usr/bin/perl

use DBI;
use strict;

my $driver   = "Pg";
my $database = "testdb";
my $dsn = "DBI:$driver:dbname = $database;host = 127.0.0.1;port = 5432";
my $userid = "postgres";
my $password = "pass123";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;
print "Opened database successfully\n";

my $stmt = qq(DELETE from COMPANY where ID=2;);
my $rv = $dbh->do($stmt) or die $DBI::errstr;
if( $rv < 0 ) {
   print $DBI::errstr;
} else{
   print "Total number of rows deleted : $rv\n";
}
$stmt = qq(SELECT id, name, address, salary  from COMPANY;);
my $sth = $dbh->prepare( $stmt );
$rv = $sth->execute() or die $DBI::errstr;
if($rv < 0) {
   print $DBI::errstr;
}
while(my @row = $sth->fetchrow_array()) {
      print "ID = ". $row[0] . "\n";
      print "NAME = ". $row[1] ."\n";
      print "ADDRESS = ". $row[2] ."\n";
      print "SALARY =  ". $row[3] ."\n\n";
}
print "Operation done successfully\n";
$dbh->disconnect();

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
Total number of rows deleted : 1
ID = 1
NAME = Paul
ADDRESS = California
SALARY =  25000

ID = 3
NAME = Teddy
ADDRESS = Norway
SALARY =  20000

ID = 4
NAME = Mark
ADDRESS = Rich-Mond
SALARY =  65000

Operation done successfully

----


== PostgreSQL - Python Interface


=== Installation

The PostgreSQL can be integrated with Python using psycopg2 module. sycopg2 is a PostgreSQL database adapter for the Python programming language. psycopg2 was written with the aim of being very small and fast, and stable as a rock. You do not need to install this module separately because it is shipped, by default, along with Python version 2.5.x onwards.

If you do not have it installed on your machine then you can use yum command to install it as follows −

[source]
----
$yum install python-psycopg2

----

To use psycopg2 module, you must first create a Connection object that represents the database and then optionally you can create cursor object which will help you in executing all the SQL statements.


=== Python psycopg2 module APIs

The following are important psycopg2 module routines, which can suffice your requirement to work with PostgreSQL database from your Python program. If you are looking for a more sophisticated application, then you can look into Python psycopg2 module's official documentation.
[%autowidth]
|===

|S. No.|API & Description
|1|*psycopg2.connect(database="testdb", user="postgres", password="cohondob", host="127.0.0.1", port="5432")*
This API opens a connection to the PostgreSQL database. If database is opened successfully, it returns a connection object.

|2|*connection.cursor()*
This routine creates a *cursor* which will be used throughout of your database programming with Python.

|3|*cursor.execute(sql [, optional parameters])*
This routine executes an SQL statement. The SQL statement may be parameterized (i.e., placeholders instead of SQL literals). The psycopg2 module supports placeholder using %s sign
For example:cursor.execute("insert into people values (%s, %s)", (who, age))

|4|*cursor.executemany(sql, seq_of_parameters)*
This routine executes an SQL command against all parameter sequences or mappings found in the sequence sql.

|5|*cursor.callproc(procname[, parameters])*
This routine executes a stored database procedure with the given name. The sequence of parameters must contain one entry for each argument that the procedure expects.

|6|*cursor.rowcount*
This read-only attribute which returns the total number of database rows that have been modified, inserted, or deleted by the last last execute*().

|7|*connection.commit()*
This method commits the current transaction. If you do not call this method, anything you did since the last call to commit() is not visible from other database connections.

|8|*connection.rollback()*
This method rolls back any changes to the database since the last call to commit().

|9|*connection.close()*
This method closes the database connection. Note that this does not automatically call commit(). If you just close your database connection without calling commit() first, your changes will be lost!

|10|*cursor.fetchone()*
This method fetches the next row of a query result set, returning a single sequence, or None when no more data is available.

|11|*cursor.fetchmany([size=cursor.arraysize])*
This routine fetches the next set of rows of a query result, returning a list. An empty list is returned when no more rows are available. The method tries to fetch as many rows as indicated by the size parameter.

|12|*cursor.fetchall()*
This routine fetches all (remaining) rows of a query result, returning a list. An empty list is returned when no rows are available.

|===


=== Connecting to Database

The following Python code shows how to connect to an existing database. If the database does not exist, then it will be created and finally a database object will be returned.

[source]
----
#!/usr/bin/python

import psycopg2

conn = psycopg2.connect(database="testdb", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")

print "Opened database successfully"

----

Here, you can also supply database *testdb* as name and if database is successfully opened, then it will give the following message −

[source]
----
Open database successfully

----


=== Create a Table

The following Python program will be used to create a table in previously created database −

[source]
----
#!/usr/bin/python

import psycopg2

conn = psycopg2.connect(database = "testdb", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")
print "Opened database successfully"

cur = conn.cursor()
cur.execute('''CREATE TABLE COMPANY
      (ID INT PRIMARY KEY     NOT NULL,
      NAME           TEXT    NOT NULL,
      AGE            INT     NOT NULL,
      ADDRESS        CHAR(50),
      SALARY         REAL);''')
print "Table created successfully"

conn.commit()
conn.close()

----

When the above given program is executed, it will create COMPANY table in your *test.db* and it will display the following messages −

[source]
----
Opened database successfully
Table created successfully

----


=== INSERT Operation

The following Python program shows how we can create records in our COMPANY table created in the above example −

[source]
----
#!/usr/bin/python

import psycopg2

conn = psycopg2.connect(database = "testdb", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")
print "Opened database successfully"

cur = conn.cursor()

cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
      VALUES (1, 'Paul', 32, 'California', 20000.00 )");

cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
      VALUES (2, 'Allen', 25, 'Texas', 15000.00 )");

cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
      VALUES (3, 'Teddy', 23, 'Norway', 20000.00 )");

cur.execute("INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) \
      VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 )");

conn.commit()
print "Records created successfully";
conn.close()

----

When the above given program is executed, it will create given records in COMPANY table and will display the following two lines −

[source]
----
Opened database successfully
Records created successfully

----


=== SELECT Operation

The following Python program shows how we can fetch and display records from our COMPANY table created in the above example −

[source]
----
#!/usr/bin/python

import psycopg2

conn = psycopg2.connect(database = "testdb", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")
print "Opened database successfully"

cur = conn.cursor()

cur.execute("SELECT id, name, address, salary  from COMPANY")
rows = cur.fetchall()
for row in rows:
   print "ID = ", row[0]
   print "NAME = ", row[1]
   print "ADDRESS = ", row[2]
   print "SALARY = ", row[3], "\n"

print "Operation done successfully";
conn.close()

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
ID =  1
NAME =  Paul
ADDRESS =  California
SALARY =  20000.0

ID =  2
NAME =  Allen
ADDRESS =  Texas
SALARY =  15000.0

ID =  3
NAME =  Teddy
ADDRESS =  Norway
SALARY =  20000.0

ID =  4
NAME =  Mark
ADDRESS =  Rich-Mond
SALARY =  65000.0

Operation done successfully

----


=== UPDATE Operation

The following Python code shows how we can use the UPDATE statement to update any record and then fetch and display updated records from our COMPANY table −

[source]
----
#!/usr/bin/python

import psycopg2

conn = psycopg2.connect(database = "testdb", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")
print "Opened database successfully"

cur = conn.cursor()

cur.execute("UPDATE COMPANY set SALARY = 25000.00 where ID = 1")
conn.commit()
print "Total number of rows updated :", cur.rowcount

cur.execute("SELECT id, name, address, salary  from COMPANY")
rows = cur.fetchall()
for row in rows:
   print "ID = ", row[0]
   print "NAME = ", row[1]
   print "ADDRESS = ", row[2]
   print "SALARY = ", row[3], "\n"

print "Operation done successfully";
conn.close()

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
Total number of rows updated : 1
ID =  1
NAME =  Paul
ADDRESS =  California
SALARY =  25000.0

ID =  2
NAME =  Allen
ADDRESS =  Texas
SALARY =  15000.0

ID =  3
NAME =  Teddy
ADDRESS =  Norway
SALARY =  20000.0

ID =  4
NAME =  Mark
ADDRESS =  Rich-Mond
SALARY =  65000.0

Operation done successfully

----


=== DELETE Operation

The following Python code shows how we can use the DELETE statement to delete any record and then fetch and display the remaining records from our COMPANY table −

[source]
----
#!/usr/bin/python

import psycopg2

conn = psycopg2.connect(database = "testdb", user = "postgres", password = "pass123", host = "127.0.0.1", port = "5432")
print "Opened database successfully"

cur = conn.cursor()

cur.execute("DELETE from COMPANY where ID=2;")
conn.commit()
print "Total number of rows deleted :", cur.rowcount

cur.execute("SELECT id, name, address, salary  from COMPANY")
rows = cur.fetchall()
for row in rows:
   print "ID = ", row[0]
   print "NAME = ", row[1]
   print "ADDRESS = ", row[2]
   print "SALARY = ", row[3], "\n"

print "Operation done successfully";
conn.close()

----

When the above given program is executed, it will produce the following result −

[source]
----
Opened database successfully
Total number of rows deleted : 1
ID =  1
NAME =  Paul
ADDRESS =  California
SALARY =  20000.0

ID =  3
NAME =  Teddy
ADDRESS =  Norway
SALARY =  20000.0

ID =  4
NAME =  Mark
ADDRESS =  Rich-Mond
SALARY =  65000.0

Operation done successfully

----
----