Postgresql как написать скрипт

Приветствую Вас в блоге «Будни программиста».

      Сегодня впервые мне пришлось столкнуться с написанием скриптов на pgScript. Синтаксис написания скриптов на pgScript сильно отличается от синтаксиса написания тел хранимых процедур на plpgsql, что, честно говоря, в начале написания приводило к жуткой синтаксической путанице. :)

Итак, переходим непосредственно к изучению…

       Типы данных в pgScript.

STRING — Символьный тип данных;
INTEGER  — Целочисленный тип;
REAL — Число с плавающей точной;
RECORD — Тип запись — массив данных.

       Объявление переменных.

      Первое, что бросается в глаза глядя на pgScript — это объявление
переменных. В объявлении не указывается тип переменной, а значит нет
операций явного преобразования, например:

declare @tst;

или, если необходимо объявить несколько переменных то:

declare @tst, @tst1, @tst2;

Для присваивания значений используется служебное слово SET:

set @A = 1000, @B = 2000;   -- @A и @B числа целого типа;
set @C = 10E1, @D = 1.5;    -- @C и @D числа с плавающей точкой;
set @E = 'ab', @F = 'a''b'; -- @E и @F строковые типы;
set @G = "ab", @H = "a"b"; -- @G и @H строковые типы;

       Причем имена переменных в скрипте являются «псевдонимами»
значений. Вот пример наглядно показывающий то, что я хочу сказать:

SET @A = EXEC concat_text('abc', 'def'); --выполнение функции
ASSERT @A[0][0] = 'abcdef'; -- если @A[0][0] = 'abcdef'; - лож - генерится исключение.
SET @A = 'abc', @B = 'def';
SET @C = SELECT concat_text('@A', '@B') AS output; -- Опять вызов функции. Обратите внимание на способ указания значений переменных (!). 

      Вывод результатов.

       Вывод данных в течение выполнения скрипта выполняется командой  PRINT:

print 'true';

       Если требуется вывести значение какой либо переменной, то это можно сделать так:

print 'Result '+ cast(@tst as string);

       Print выводит указанные данные в процессе исполнения скрипта, что позволяет нам в некоторой степени визуально контролировать процесс выполнения. Если что-нибудь пошло не так, всегда наготове кнопка «Stop».

      Операторские скобки.

       Операторскими скобками в скриптах является BEGIN…END, а разделителем операторов символ «;»:

declare @test;
begin
--Тело скрипта pgScript;
end

       Заметьте, что  после операторских скобок символ «;» не ставится. Он разделяет операторы находящиеся между begin и end.

      Ветвления.

       Для построения нелинейной логики выполнения скрипта можно использовать инструкцию IF. Синтаксис так же отличен от plpgsql. В pgScript нет указания окончания оператора END IF, а так же отсутствует THEN;

if @tst<20 
    print 'true';

       Простой пример скрипта использующий все операторы описанные выше выглядит следующим образом:

declare @tst;
begin
  set @tst = 10;
  if @tst<20 
    print 'true';
end

       Использование SQL-операторов в скрипте.

Используем SELECT:

declare @current_number; --объявление переменной
begin
    --присваиваем значение из запроса
    set @current_number = (select count(*) from documents_assignment);
    --сравниваем результат с нулем
    if cast(@current_number as integer) > 0 
        --если результат больше нуля - используем функцию max для определения истинного максимального числа
        set @current_number = (select max(internal_number) from documents_assignment);
    --инкремент...
    set @current_number = cast(@current_number as integer)+1;
    --вывод результата 
    print 'Result: '+ cast(@current_number as string);
end

       В скрипте описан алгоритм получения числа которое на единицу больше максимального в поле «internal_number». Это был показательный пример, теперь его можно немного оптимизировать:

declare @current_number;
begin
    set @current_number = (select coalesce(max(internal_number),0) from documents_assignment);
    set @current_number = cast(@current_number as integer)+1;
    print 'Result: '+ cast(@current_number as string);
end

Предвидя вопрос: siquence в моем случае использовать невозможно по ряду специфичных причин.

Маленькое отступление.

Не работает конструкция:
set @client_id = (select id_owner from account_owner_account_link
                    where id_account = @orders_record[@orders_rec_number][3] and
                    id_account_owner_type = 2 /*client*/);
Надо будет позже разобраться почему…
Вероятно это связано с тем, что скрипт при парсинге запроса не может распознать необычную для SQL форму записи «where id_account = @orders_record[@orders_rec_number][3]», и выдает синтаксическую ошибку.

       В результате использования того что было описано выше, сегодня получился вот такой рабочий скрипт который периодически будет выполнять боевые задачи:

--объявляем переменные которые будут необходимы
declare @orders_rec_number,
    @orders_max_rec_number, 
    @client_id,
    @account_id,
    @orders_id,
    @orders_date;
    
declare @orders_record; --records...
--начало тела скрипта 
begin
    print 'Begin script';

    --init (блок инициализации переменных)
    set @orders_rec_number = 0;
    set @orders_max_rec_number = 0; 
    set @client_id = 0;
    set @account_id = 0;
    set @orders_id = 0;
    set @orders_date = cast('1900-01-01' as string);
    --end init
    
    --заполнение массива RECORD данными из запроса
    set @orders_record = select id_orders, orders_number, orders_date,  id_account from orders order by id_orders;
    set @orders_max_rec_number = (select count(id_orders) from orders);
    set @orders_max_rec_number = cast(@orders_max_rec_number as integer);
    
    --Цикл. Почему именно так (while 1)? Дело привычки.
    while 1 
    begin
        if (@orders_rec_number = @orders_max_rec_number)
          break;
        --пример получения значения одного элемента из RECORD - массива
        set @account_id = @orders_record[@orders_rec_number][3];
        --пример получения значения из запроса
        set @client_id = (select coalesce(id_owner,0) 
          from account_owner_account_link
        where id_account = @account_id and
          id_account_owner_type = 2 /*client*/);
        --пример сравнивания значение переменной которая может cодержать "NULL"
        if (select coalesce(@client_id,0)<>0)
        begin
            set @client_id = cast(@client_id as integer);
            set @orders_id = @orders_record[@orders_rec_number][0];
            set @orders_date = @orders_record[@orders_rec_number][2];
         
            --пример выполнения хранимой процедуры
            SELECT f_documents_assignment_add(
            '@orders_date', --тип:timestamp...
            '@orders_date', --тип:timestamp...
            cast(@client_id as integer),
            1,
            cast(@orders_id as integer)
            );
        end

        set @orders_rec_number = @orders_rec_number + 1;

    end -- конец цикла

    print 'End script';
    -- конец тела скрипта
end

Это далеко не все возможности pgScript. Далее мы подробнее рассмотрим:

  1. Тип RECORD;
  2. Генераторы последовательностей;
  3. Генераторы случайных значений;
  4. Работа с транзакциями;
  5. Функции;
Содержание

Введение
PostgreSQL скрипт из Bash
Запуск скрипта из файла
Импорт из .csv файла
Похожие статьи

Введение

PostgreSQL скрипт из Bash

Чтобы выполнить

Bash

скрипт

с командой PostgreSQL достаточно создать файл

script.sh

подобного содержания

#!/bin/bash
PGPASSWORD=ПАРОЛЬ psql -h ХОСТ -U ИМЯ_ПОЛЬЗОВАТЕЛЯ -d ИМЯ_БД -с "ВАША КОМАНДА"

Например

#!/bin/bash
PGPASSWORD=QWERTY psql -h 127.0.0.1 -U andrei -d urnsu -с "SELECT * FROM news"

И вызвать его

. script.sh

Если SQL скрипт большой и содержит сложный синтаксис, его не так просто подружить с синтаксисом bash.

В такой ситуации может быть полезно создать отдельный файл

sql_script.sql

и файл с bash скриптом

bash_script.sh

Из

bash_script.sh

можно вызвать

sql_script.sql

следующим образом

#!/bin/bash
cat sql_script.sql | PGPASSWORD=QWERTY psql -h 127.0.0.1 -U andrei -d urnsu

. bash_script.sh

Запуск скрипта из файла

В Windows

Несколько примеров для

Windows Subsystem for Linux

Сперва проверим, что с переменными окружения всё впорядке.

Для этого введём в консоль psql.exe нажмём Enter и проверим что

WSL

не жалуется на неизвестную команду.

Если жалуется — прочитайте мои советы в статье

Системная переменная PATH

Пишем скрипт
script.sql

CREATE TABLE person (
id int,
first_name VARCHAR(50),
last_name VARCHAR(50),
gender VARCHAR(5),
date_of_birth DATE
)

Применим этот скрипт к базе данных
HeiHei_ru_DB

У меня postgres запущен локально на порту 5433. У Вас может быть
на 5432 — проверьте.

cat script.sql | psql.exe -h localhost -p5433 -U postgres HeiHei_ru_DB

Password for user postgres:

CREATE TABLE

Саме время сделать что-то более близкое к реальному скрипту

На поля таблицы нужно ввести некоторые ограничения и добавить им свойств.

CREATE TABLE booking_sites (
id BIGSERIAL NOT NULL PRIMARY KEY,
company_name VARCHAR(50) NOT NULL,
origin_country VARCHAR(50) NOT NULL,
age VARCHAR(3) NOT NULL,
date_of_birth DATE NOT NULL,
website_url VARCHAR(50)
);

Теперь запустим этот скрпит уже не в тестовую а в рабочую базу данных
heihei (которая совпадает с названием сайта HeiHei.ru,
но если написать .ru будет синтаксическая ошибка ERROR: syntax error at or near «.»)

cat booking_sites.sql | psql.exe -h localhost -p5433 -U postgres heihei

Password for user postgres:

CREATE TABLE

В Linux

Выполним следующий скрипт из файла

my_script.sql

SELECT data FROM certificates WHERE (id=’8c585c96-a593-456d-4a87-4d12322c6063′);

cat my_script.sql | psql -h localhost -p5432 -d db_name -U andrei

Password for user andrei:

data
——————————————————————
——BEGIN CERTIFICATE—— +
MIIDDDCCAfSgAwIBAgIIBkh3ZXTEqB8wDQYJKoZIhvcNAQELBQAwGzEZMBcGA1UE+
AxMQUHJpdlggd2ViIHNlcnZlcjAeFw0yMjA3MTkxMzQ0MDJaFw0yMjA3MjAxMzQ0+
MDJaMBsxGTAXBgNVBAMTEFByaXZYIHdlYiBzZXJ2ZXIwggEiMA0GCSqGSIb3DQEB+
AQUAA4IBDwAwggEKAoIBAQCpOJuP+kmgcNlxnfZ9nBwpvSO8LANeW6DuAgc9D4P0+
RI5qGvF5duVNV7DrY3V3+Lwu4udWUUUnm7NvKbR9vaUcB7tx+2O1SXFwAO0Z0UA5+
nswTlYz0Hblw0Z1SIlhv2VValv6jP66KL37mAYc1QObxNwH4wqEPePix0DUlm0+w+
r8qHKPhpAwL5Haf00zJWwc5t1ENNLhGSG90eYhas+cVkdnWgxn0fbcc23R7QU1Bg+
KxLyT23ptqzlRq/6Vdlt1DDt6/sd92ndY/72txUUA1aT9Ycw+4lK2Z7uIxUXGy65+
iz3gu2THWRll82HBFPrsFKthK+hGvwF/IhBiR9ly8FgJAgMBAAGjVDBSMA4GA1Ud+
DwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0G+
A1UcDgQWBBSVXlTlVVB5a4yYYlbJ/SwWAjPo/zANBgkqhkiG9w0BAQsFAAOCAQEA+
PmpmWqcBZo4b8JuBrhcI1hGR5lNkq7/eWZYkCvPLjzkDAnWdf4SZZQNPE6O24xAx+
aQNcn2PeBaO5eJVuZwEQMqoRr2j9CO637XRPv0zAOKCuKfcnGuUrerKLiuSQDT1Y+
hwXzp0lCWO8BT/chIJvjSPHYVKgJimXi9oLtf4QvPvliBt0dY/J6LAnewsEYD9ug+
iUA8iCpAITBVDybF462d+m4L5YN0gmLx+sGhPqNHjIWP8HN73HwvIvuCL+lTAk2M+
FGmYVaqthWDts4UNwdaVA1ZnmJVOjklhn2Jm6yKRNs7ZJ2kESX0k+gj33x0AAdcz+
Q5hgzQSUF3wc4rTnFW90/g== +
——END CERTIFICATE—— +

(1 row)

Импорт из .csv файла

Чтобы файл открылся желательно положить его в папку

  • C:UsersPublic — для Windows
  • /tmp — для
    Linux
    и
    Unix

Либо грамотно настроить разрешения — иначе будет

ошибка

Пример скрипта для импорта

set datestyle to "US";
COPY public.people (id, date, name, address, comment)
FROM '/tmp/file.csv'
DELIMITER ','
CSV HEADER ENCODING 'UTF8'
QUOTE '"'
ESCAPE '''';

Похожие статьи

PostgreSQL
Основы
Установка
postgresql.conf: Конфигурационный файл
Таблицы
Пользователи
SELECT
WHERE
bash скрипты для Postgres
Репликация master slave
Write Ahead Log
recovery.conf
pg_hba.conf
Help
Ошибки

pgAdmin III

pgScript Scripting Language Reference

Overview

pgScript is composed of pgScript commands:

pgScript command
    : Regular PostgreSQL SQL Command (SELECT INSERT CREATE ...)
    | Variable declaration or assignment (DECLARE SET)
    | Control-of-flow structure (IF WHILE)
    | Procedure (ASSERT PRINT LOG RMLINE)

Command names (SELECT, IF, SET, …) are case-insensitive
and must be ended with a semi-column ;. Identifiers are case-sensitive.

Examples

Batch table creations

DECLARE @I, @T; -- Variable names begin with a @
SET @I = 0; -- @I is an integer
WHILE @I &lt; 20
BEGIN
   SET @T = 'table' + CAST (@I AS STRING); -- Casts @I
   CREATE TABLE @T (id integer primary key, data text);

   SET @I = @I + 1;
END

Insert random data

DECLARE @I, @J, @T, @G;
SET @I = 0;
SET @G1 = INTEGER(10, 29, 1); /* Random integer generator
                             Unique numbers between 10 and 29 */
SET @G2 = STRING(10, 20, 3); /* Random string generator
                             3 words between 10 and 20 characters */
WHILE @I &lt; 20
BEGIN
    SET @T = 'table' + CAST (@I AS STRING);

SET @J = 0;
    WHILE @J &lt; 20
    BEGIN
        INSERT INTO @T VALUES (@G1, '@G2');
        SET @J = @J + 1;
    END

SET @I = @I + 1;
END

Batch table deletions

DECLARE @I, @T; -- Declaring is optional
SET @I = 0;
WHILE 1 -- Always true
BEGIN
    IF @I &gt;= 20
      BREAK; -- Exit the loop if @I &gt; 20

 SET @T = 'table' + CAST (@I AS STRING);
    DROP TABLE @T;

 SET @I = @I + 1;
END

Print information on screen

SET @[email protected]#TITLE = 'pgScript';
PRINT '';
PRINT @[email protected]#TITLE + ' features:';
PRINT '';
PRINT '  * Regular PostgreSQL commands';
PRINT '  * Control-of-flow language';
PRINT '  * Local variables';
PRINT '  * Random data generators';</pre>

Variables

There are two main types of variables : simple variables and records
(result sets composed of lines and columns).

Variable names begin with a @ and can be composed of
letters, digits, _, #, @.

Variable type is guessed automatically according to the kind of value it
contains. This can be one of: number (real or integer), string, record.

Simple variables

Simple variable declaration

Declaring simple variable is optional:

DECLARE @A, @B;
DECLARE @VAR1;

Simple variable affectation

This is done with the SET command. The variable type depends on the
value assigned to this variable:

SET @A = 1000, @B = 2000;   -- @A and @B are <strong>integer numbers**
SET @C = 10e1, @D = 1.5;    -- @C and @D are <strong>real numbers**
SET @E = 'ab', @F = 'a''b'; -- @E and @F are <strong>strings**
SET @G = "ab", @H = "a"b"; -- @G and @H are <strong>strings**

An uninitialized variable defaults to an empty string. It is possible to
override variables as many times as wanted:

PRINT @A;      -- Prints an empty string
SET @A = 1000; -- @A is initialized an integer
PRINT @A;      -- Prints 1000
SET @A = 'ab'; -- @A becomes a string
PRINT @A;      -- Prints ab

Data generators

Data generators allows users to generate random values. There are
various types of generators, each one producing different type of data.
A variable initialized with a data generator behaves like a regular
simple variable except that it has a different value each time it is
used:

SET @A = INTEGER(100, 200);
PRINT @A; -- Prints an integer between 100 and 200
PRINT @A; -- Prints another integer between 100 and 200

A variable can contain a generator but its type is one of: number (real
or integer), string. For a list of available generators and their
associated type, see generators.

Records

Record declaration

Declaring a record is required. A name for each column must be
specified even if they will not be used anymore afterwards:

DECLARE @R1 { @A, @B }, @R2 { @A, @C }; -- Two records with two  columns
DECLARE @R3 { @A, @B, @C, @D };         -- One record  with four columns

The number of lines is dynamic: see the next section.

Record affectation

To access a specific location in a record, one must use the line number
(starts at 0) and can use either the column name (between quotes) or the
column number (starts at 0). This specific location behaves like a
simple variable. Note that a record cannot contain a record:

SET @R1[0]['@A'] = 1; -- First line &amp; first column
SET @R1[0][0] = 1;    -- Same location
SET @R1[4]['@B'] = 1; -- Fifth line &amp; second column
SET @R1[0][1] = 1;    -- Same location

In the above example, three empty lines are automatically inserted
between the first and the fifth. Using an invalid column number or name
results in an exception.

Specific location can be used as right values as well. A specific line
can also be used as right value:

SET @R1[0][0] = @R3[0][1], @A = @R2[0][0]; -- Behaves like simple variables
SET @A = @R1[1]; -- @A becomes a record which is the first line of @R1

Remember that SET @R1[0][0] = @R2 is impossible because a record
cannot contain a record.

It is possible to assign a record to a variable, in this case the
variable does not need to be declared:

SET @A = @R3; -- @A becomes a record because it is assigned a record

SQL queries

Any SQL query executed returns a record. If the query is a SELECT
query then it returns the results of the query. If it is something else
then it returns a one-line record (true) if this is a success
otherwise a zero-line record (false):

SET @A = SELECT * FROM table;   -- @A is a record with the results of the query
SET @B = INSERT INTO table ...; -- @B is a one-line record if the query succeeds

Record functions

See function2.

Cast

It is possible to convert a variable from one type to another with the
cast function:

SET @A = CAST (@B AS STRING);
SET @A = CAST (@B AS REAL);
SET @A = CAST (@B AS INTEGER);
SET @A = CAST (@B AS RECORD);

When a record is converted to a string, it is converted to its flat
representation. When converted to a number, the record is first converted
to a string and then to a number (see string conversion for more
details).

When a number is converted to a string, it is converted to its string
representation. When converted to a record, it is converted to a
one-line-one-column record whose value is the number.

When a string is converted to a number, if the string represents a
number then this number is returned else an exception is thrown. When
converted to a record, either the program can find a record pattern
in the string or it converts it to a one-line-one-column record whose
value is the string. A record pattern is:

SET @B = '(1, "abc", "ab\"")(1, "abc", "ab\"")'; -- @B is a string
SET @B = CAST (@B AS RECORD); @B becomes a two-line-three-column record

Remember a string is surrounded by simple quotes. Strings composing a
record must be surrounded by double quotes which are escaped with \
(we double the slash because it is already a special character for the
enclosing simple quotes).

Operations

Operations can only be performed between operands of the same type. Cast
values in order to conform to this criterion.

Comparisons result in a number which is 0 or 1.

Strings

Comparisons: = <> > < <= >= AND OR

Concatenation: +

SET @B = @A + 'abcdef'; -- @A must be a string and @B will be a string

Boolean value: non-empty string is true, empty string is false

Inverse boolean value: NOT

Case-insensitive comparison: ~=

Numbers

Comparisons: = <> > < <= >= AND OR

Arithmetic: + - * / %

SET @A = CAST ('10' AS INTEGER) + 5; -- '10' string is converted to a number

Boolean value: 0 is false, anything else is true

Inverse boolean value: NOT (note that NOT NOT 10 = 1)

An arithmetic operation involving at least one real number gives a real
number as a result:

SET @A = 10 / 4.; -- 4. is a real so real division: @A = 2.5
SET @A = 10 / 4;  -- 4 is an integer so integer division: @A = 2

Records

Comparisons: = <> > < <= >= AND OR

Boolean value: zero-line record is false, anything else is true

Inverse boolean value: NOT

Comparisons for records are about inclusion and exclusion. Order of
lines does not matter. <= means that each row in the left operand
has a match in the right operand. >= means the opposite. = means
that <= and >= are both true at the same time…

Comparisons are performed on strings: even if a record contains numbers
like 10 and 1e1 we will have '10' <> '1e1'.

Control-of-flow structures

Conditional structure

IF condition
BEGIN
    pgScript commands
END
ELSE
BEGIN
    pgScript commands
END

pgScript commands are optional. BEGIN and END keywords are
optional if there is only one pgScript command.

Loop structure

WHILE condition
BEGIN
    pgScript commands
END

pgScript commands are optional. BEGIN and END keywords are
optional if there is only one pgScript command.

BREAK ends the enclosing WHILE loop, while CONTINUE causes
the next iteration of the loop to execute. RETURN behaves like
BREAK:

WHILE condition1
BEGIN
    IF condition2
    BEGIN
        BREAK;
    END
END

Conditions

Conditions are in fact results of operations. For example the string
comparison 'ab' = 'ac' will result in a number which is false
(the equality is not true):

IF 'ab' ~= 'AB' -- Case-insensitive comparison which result in 1 (true) which is true
BEGIN
    -- This happens
END

IF 0 -- false
BEGIN
    -- This does **not** happen
END
ELSE
BEGIN
    -- This happens
END

WHILE 1
BEGIN
    -- Infinite loop: use BREAK for exiting
END

It is possible to the result of a SQL SELECT query directly as a
condition. The query needs to be surrounded by parenthesis:

IF (SELECT 1 FROM table)
BEGIN
    -- This means that table exists otherwise the condition would be false
END

Additional functions and procedures

Procedures

Procedures do not return a result. They must be used alone on a line and
cannot be assigned to a variable.

Print

Prints an expression on the screen:

PRINT 'The value of @A is' + CAST (@A AS STRING);

Assert

Throws an exception if the expression evaluated is false:

ASSERT 5 &gt; 3 AND 'a' = 'a';

Remove line

Removes the specified line of a record:

RMLINE(@R[1]); -- Removes @R second line

Functions

Functions do return a result. Their return value can be assigned to a
variable, like the CAST operation.

Trim

Removes extra spaces surrounding a string:

SET @A = TRIM(' a '); -- @A = 'a'</pre>

Lines

Gives the number of lines in a record:

IF LINES(@R) &gt; 0
BEGIN
    -- Process
END

Columns

Gives the number of columns in a record:

IF COLUMNS(@R) &gt; 0
BEGIN
    -- Process
END

Random data generators

Overview of the generators

One can assign a variable (SET) with a random data generators. This
means each time the variable will be used it will have a different
value.

However the variable is still used as usual:

SET @G = STRING(10, 20, 2);
SET @A = @G; -- @A will hold a random string
SET @B = @G; -- @B will hold another random string
PRINT @G,    -- This will print another third random string

Sequence and seeding

Common parameters for data generators are sequence and seed.

sequence means that a sequence of values is generated in a random
order, in other words each value appears only once before the sequence
starts again: this is useful for columns with a UNIQUE constraint.
For example, this generator:

SET @G = INTEGER(10, 15, 1); -- 1 means generate a sequence

It can generate such values:

14 12 10 13 11 15 14 12 10 13 11

Where each number appears once before the sequence starts repeating.

sequence parameter must be an integer: if it is 0 then no sequence is
generated (default) and if something other than 0 then generate a
sequence.

seed is an integer value for initializing a generator: two generators
with the same parameters and the same seed will generate exactly the
same values.

seed must be an integer: it is used directly to initialize the random
data generator.

Data generators

Optional parameters are put into brackets:

Generator
 : INTEGER ( min, max, [sequence], [seed] );
 | REAL ( min, max, precision, [sequence], [seed] );
 | DATE ( min, max, [sequence], [seed] );
 | TIME ( min, max, [sequence], [seed] );
 | DATETIME ( min, max, [sequence], [seed] );
 | STRING ( min, max, [nb], [seed] );
 | REGEX ( regex, [seed] );
 | FILE ( path, [sequence], [seed], [encoding] );
 | REFERENCE ( table, column, [sequence], [seed] );

Integer numbers

INTEGER ( min, max, [sequence], [seed] );
INTEGER ( -10, 10, 1, 123456 );

min is an integer, max is an integer, sequence is an integer
and seed is an integer.

Real numbers

REAL ( min, max, precision, [sequence], [seed] );
REAL ( 1.5, 1.8, 2, 1 );

min is a number, max is a number, precision is an integer
that indicates the number of decimals (should be less than 30),
sequence is an integer and seed is an integer.

Dates

DATE ( min, max, [sequence], [seed] );
DATE ( '2008-05-01', '2008-05-05', 0 );

min is a string representing a date, max is a string representing
a date, sequence is an integer and seed is an integer.

Times

TIME ( min, max, [sequence], [seed] );
TIME ( '00:30:00', '00:30:15', 0 );

min is a string representing a time, max is a string representing
a time, sequence is an integer and seed is an integer.

Timestamps (date/times)

DATETIME ( min, max, [sequence], [seed] );
DATETIME ( '2008-05-01 14:00:00', '2008-05-05 15:00:00', 1 );

min is a string representing a timestamp, max is a string
representing a timestamp, sequence is an integer and seed is an
integer.

Strings

STRING ( min, max, [nb], [seed] );
STRING ( 10, 20, 5 );

min is an integer representing the minimum length of a word, max
is an integer representing the maximum length of a word, nb is an
integer representing the number of words (default: 1) and seed
is an integer.

In the above example we generate 5 words (separated with a space) whose
size is between 10 and 20 characters.

Strings from regular expressions

REGEX ( regex, [seed] );
REGEX ( '[a-z]{1,3}@[0-9]{3}' );

regex is a string representing a simplified regular expressions and
seed is an integer.

Simplified regular expressions are composed of:

  • Sets of possible characters like [a-z_.] for characters between
    a and z + _ and .
  • Single characters

It is possible to specify the minimum and maximum length of the
preceding set or single character:

  • {min, max} like {1,3} which stands for length between 1
    and 3
  • {min} like {3} which stands for length of 3
  • Default (when nothing is specified) is length of 1

Note: be careful with spaces because 'a {3}' means one a followed
by three spaces because the 3 is about the last character or set of
characters which is a space in this example.

If you need to use [ ] { or }, they must be escaped
because they are special characters. Remember to use double
backslash
: '\[{3}' for three [.

Strings from dictionary files

FILE ( path, [sequence], [seed], [encoding] );
FILE ( 'file.txt', 0, 54321, 'utf-8' );

path is a string representing the path to a text file, sequence
is an integer, seed is an integer and encoding is a string
representing the file character set (default is system encoding).

This generates a random integer between 1 and the number of lines in the
file and then returns that line. If the file does not exist then an
exception is thrown.

encoding supports the most known encoding like utf-8, utf-16le,
utf-16be, iso-8859-1, …

Reference to another field

REFERENCE ( table, column, [sequence], [seed] );
REFERENCE ( 'tab', 'col', 1 );

table is a string representing a table, column is a string
representing a column of the table, sequence is an integer and
seed is an integer.

This is useful for generating data to put into foreign-key-constrained
columns.

Здравствуйте.

Недавно заинтересовался написанием скриптов на pgScript.

Все что удалось найти из мануалов — вот это http://www.pgadmin.org/docs/dev/pgscript.html#function2

Мануал доступный, но, как мне кажется, тонковат. Надо бы больше информации с примерами. А где ее взять?
Порыл в сети, ничего толкового не нашел. Тем более на русском языке. В связи с этим начал сам экспериментировать и потихоньку писать некое подобие мануала (pgScript. Написание простых скриптов. Первый опыт. ). Это только начало. Хочу написать еще глубже и подробнее. Может кто-нить может указать место, или скинуть если есть инфу по pgScript. Чем больше тем лучше.
Заранее спасибо.  :)

С Уважением, drmiller.

For example, in MS-SQL, you can open up a query window and run the following:

DECLARE @List AS VARCHAR(8)

SELECT @List = 'foobar'

SELECT *
FROM   dbo.PubLists
WHERE  Name = @List

How is this done in PostgreSQL? Can it be done?

asked Apr 20, 2009 at 2:28

1

Complete answer is located in the official PostgreSQL documentation.

You can use new PG9.0 anonymous code block feature (http://www.postgresql.org/docs/9.1/static/sql-do.html )

DO $$
DECLARE v_List TEXT;
BEGIN
  v_List := 'foobar' ;
  SELECT *
  FROM   dbo.PubLists
  WHERE  Name = v_List;
  -- ...
END $$;

Also you can get the last insert id:

DO $$
DECLARE lastid bigint;
BEGIN
  INSERT INTO test (name) VALUES ('Test Name') 
  RETURNING id INTO lastid;

  SELECT * FROM test WHERE id = lastid;
END $$;

answered Aug 9, 2011 at 0:08

nad2000's user avatar

nad2000nad2000

4,2861 gold badge29 silver badges24 bronze badges

6

DO $$
DECLARE  
   a integer := 10;  
   b integer := 20;  
   c integer;  
BEGIN  
   c := a + b;
    RAISE NOTICE'Value of c: %', c;
END $$;

answered Mar 31, 2016 at 6:04

Achilles Ram Nakirekanti's user avatar

4

You can use:

set list '''foobar'''
SELECT * FROM dbo.PubLists WHERE name = :list;

That will do

answered Apr 28, 2013 at 18:35

Karim de Alba's user avatar

5

Here’s an example of using a variable in plpgsql:

create table test (id int);
insert into test values (1);
insert into test values (2);
insert into test values (3);

create function test_fn() returns int as $$
    declare val int := 2;
    begin
        return (SELECT id FROM test WHERE id = val);
    end;
$$ LANGUAGE plpgsql;

SELECT * FROM test_fn();
 test_fn 
---------
       2

Have a look at the plpgsql docs for more information.

answered May 12, 2009 at 13:30

overthink's user avatar

overthinkoverthink

23.8k4 gold badges69 silver badges69 bronze badges

I’ve came across some other documents which they use set to declare scripting variable but the value is seems to be like constant value and I’m finding for way that can be acts like a variable not a constant variable.

Ex:

set Comm 150

select sal, sal+:Comm from emp

Here sal is the value that is present in the table ’emp’ and comm is the constant value.

max taldykin's user avatar

max taldykin

12.3k5 gold badges43 silver badges64 bronze badges

answered Jul 29, 2010 at 4:26

Vinodraj's user avatar

VinodrajVinodraj

951 silver badge1 bronze badge

0

Building on @nad2000’s answer and @Pavel’s answer here, this is where I ended up for my Flyway migration scripts. Handling for scenarios where the database schema was manually modified.

DO $$
BEGIN
    IF NOT EXISTS(
        SELECT TRUE FROM pg_attribute 
        WHERE attrelid = (
            SELECT c.oid
            FROM pg_class c
            JOIN pg_namespace n ON n.oid = c.relnamespace
            WHERE 
                n.nspname = CURRENT_SCHEMA() 
                AND c.relname = 'device_ip_lookups'
            )
        AND attname = 'active_date'
        AND NOT attisdropped
        AND attnum > 0
        )
    THEN
        RAISE NOTICE 'ADDING COLUMN';        
        ALTER TABLE device_ip_lookups
            ADD COLUMN active_date TIMESTAMP;
    ELSE
        RAISE NOTICE 'SKIPPING, COLUMN ALREADY EXISTS';
    END IF;
END $$;

answered Sep 26, 2018 at 13:51

Shane Kenyon's user avatar

Shane KenyonShane Kenyon

4,9172 gold badges40 silver badges36 bronze badges

For use variables in for example alter table:

DO $$ 
DECLARE name_pk VARCHAR(200);
BEGIN
select constraint_name
from information_schema.table_constraints
where table_schema = 'schema_name'
      and table_name = 'table_name'
      and constraint_type = 'PRIMARY KEY' INTO name_pk;
IF (name_pk := '') THEN
EXECUTE 'ALTER TABLE schema_name.table_name DROP CONSTRAINT ' || name_pk;

answered Aug 22, 2019 at 11:07

davidleongz's user avatar

davidleongzdavidleongz

1412 silver badges10 bronze badges

Postgresql does not have bare variables, you could use a temporary table.
variables are only available in code blocks or as a user-interface feature.

If you need a bare variable you could use a temporary table:

CREATE TEMP TABLE list AS VALUES ('foobar');

SELECT dbo.PubLists.*
FROM   dbo.PubLists,list
WHERE  Name = list.column1;

answered Dec 31, 2016 at 1:45

Jasen's user avatar

JasenJasen

11.6k2 gold badges29 silver badges47 bronze badges

2

I had to do something like this

CREATE OR REPLACE FUNCTION MYFUNC()
RETURNS VOID AS $$
DO
$do$
BEGIN
DECLARE
 myvar int;
 ...
END
$do$
$$ LANGUAGE SQL;

answered Dec 30, 2016 at 18:39

Nick's user avatar

NickNick

3,1374 gold badges29 silver badges42 bronze badges

You can also simply make a constant query that you use in the actual query:

WITH vars as (SELECT 'foobar' AS list) 
SELECT *
FROM   dbo.PubLists, vars
WHERE  Name = vars.list

answered Oct 6, 2022 at 6:38

DPF's user avatar

DPFDPF

2602 silver badges12 bronze badges

3

Given the popularity, and somewhat incomplete answers I’ll provide two solutions.

  1. A do block that won’t return rows. You can return rows with a transaction cursor, but it’s a bit messy.
  2. A function (that returns rows)

Below I’ll use an over-baked example of updating the tweet on the bottom right «blurb» with «hello world».

id (serial) pub_id (text) tweet (text)
1 abc hello world
2 def blurb

A simple do block

do $$
declare
    src_pub_id text;
    dst_pub_id text;
    src_id    int; 
    dest_id   int;
    src_tweet text;
begin
    src_pub_id := 'abc';
    dst_pub_id := 'def';
    
    -- query result into a temp variable
    src_id := (select id from tweets where pub_id = src_pub_id);

    -- query result into a temp variable (another way)
    select tweet into src_tweet from tweets where id = src_id;

    dest_id := (select id from tweets where pub_id = dst_pub_id);
    update tweets set tweet=src_tweet where id = dest_id;
end $$ language plpgsql; -- need the language to avoid ERROR 42P13

A function

create or replace function sync_tweets(
    src_pub_id text, -- function arguments
    dst_pub_id text
) returns setof tweets as -- i.e. rows. int, text work too
$$
declare
    src_id    int; -- temp function variables (not args)
    dest_id   int;
    src_tweet text;
begin
    -- query result into a temp variable
    src_id := (select id from tweets where pub_id = src_pub_id);

    -- query result into a temp variable (another way)
    select tweet into src_tweet from tweets where id = src_id;

    dest_id := (select id from tweets where pub_id = dst_pub_id);
    update tweets set tweet=src_tweet where id = dest_id;

    return query -- i.e. rows, return 0 with return int above works too
        select * from tweets where pub_id in (src_pub_id, dst_pub_id);
end
$$ language plpgsql; -- need the language to avoid ERROR 42P13

-- Run it!
select * from sync_tweets('abc', 'def');

-- Optional drop if you don't want the db to keep your function
drop function if exists sync_tweets(text, text);

/*
  Outputs
   __________________________________________________ 
  |  id (serial)  |  pub_id (text)  |  tweet (text)  |
  |---------------|-----------------|----------------|
  |  1            |  abc            |  hello world   |
  |  2            |  def            |  blurb         |
  --------------------------------------------------
*/

answered Feb 9 at 15:45

Josh Hibschman's user avatar

Josh HibschmanJosh Hibschman

2,8761 gold badge23 silver badges24 bronze badges

In this article, you will learn how to execute sql or script file in PostgreSQL on Windows and Linux step by step.

Create and Execute script in POstgreSQL on Linux Environment:

On Linux, We can execute scripts files in two ways:

1. From Linux shell
2. From psql shell

Execute PostgreSQL sql script from Linux shell:

1. Create a script file.

cat > createdatabase.sql create database test; c test create table test123(name varchar(40), age int);

2. Switch to postgres user.

sudo su - postgres

3. Then, execute the sql script using following syntax:

psql -U postgres -f /home/r2schools/createdatabase.sql

How to execute sql or script file in PostgreSQL on Windows and Linux

Execute PostgreSQL sql script from psql shell:

1. Create a script file.

cat > createtable.sql c test CREATE TABLE students(SNO int PRIMARY KEY, SNAME varchar(50),DOB date, class int, gender varchar(5));

2. Connect to postgresql using psql shell and run the following command.

i /home/r2schools/createtable.sql

3. Lets verify the table is created or not.

test=# dt List of relations Schema | Name | Type | Owner --------+----------+-------+---------- public | students | table | postgres public | test123 | table | postgres

Create and Execute script in PostgreSQL on Windows Environment:

Execute PostgreSQL sql script from psql shell On Windows:

1. Create a script file and paste the following commands and save file.

create database test; c test create table test123(name varchar(40), age int);

2. Open psql from start menu

Here, path should be in single quotes and forward slashes must be given.

i 'C:/Test/createdatabase.sql'

Execute PostgreSQL sql script from Windows command prompt:

1. Create a script file.

create database test; c test create table test123(name varchar(40), age int);

2. Now open command prompt as administrator and run the following command to execute a script as shown below.

C:WINDOWSsystem32>psql -U postgres -f C:Testcreatedatabase.sql

Password for user postgres:
Output:

CREATE DATABASE You are now connected to database "test" as user "postgres". CREATE TABLE

If we want to stop script when an error occurred while executing script, then use ON_ERROR_STOP=on

Examples:

psql -U postgres -f /home/r2schools/createdatabase.sql ON_ERROR_STOP=on

Понравилась статья? Поделить с друзьями:
  • Philips как пишется
  • Pavilion как пишется
  • Parrot как пишется
  • Parkour как пишется
  • Parfum или perfume как правильно пишется