В прошлых уроках мы изучали язык SQL, в основном это было связанно с запросами на выборку, теперь пришло время переходить к программированию в базах данных, поэтому сегодня мы с Вами будем учиться создавать функции на языке PL/pgSQL в СУБД PostgreSQL.
И начинаем как обычно с теории.
Что такое функции в SQL?
Функции – это объекты базы данных, которые используются для автоматизации и упрощения расчетов. Функции пишутся уже с использованием настоящего языка программирования в PostgreSQL — это PL/pgSQL.
PL/pgSQL – язык программирования, который используется в СУБД PostgreSQL для написания функций, триггеров и других управляющих конструкций.
Сразу скажу, что писать функции без базовых знаний SQL практически невозможно, поэтому советую ознакомиться с основами SQL, например, Вам помогут вот эти статьи:
- SQL код – самоучитель по SQL для начинающих программистов
- Основы языка запросов SQL
- Строковые функции SQL
- Как добавить новый столбец в таблицу на SQL?
Теперь давайте поговорим о том, для чего нам нужны эти самые функции. Как и в любом языке программирования есть «встроенные» функции, а также есть возможность писать свои «пользовательские» функции и PL/pgSQL не исключение, если быть точнее, то SQL не исключение, так как PL/pgSQL является расширением языка SQL.
Как Составить Жиросжигающую Тренировку / похудение / жиросжигание / сушка
В функциях мы можем легко прописывать условия, как и в других языках программирования, в функцию можно передавать параметры и соответственно она может нам возвращать результат, после выполнения действий с входящими параметрами. Одной из главных особенностей функций является то, что при обращении к базе данных из приложения все действия происходят на сервере, что гораздо быстрей, т.е. эффективней. Если не использовать вызов функций из приложения, то обращаться к базе данных придется несколько раз, что в свою очередь замедляет работу.
Также, например, можно написать функции, которые будут просто упрощать написание запросов на SQL. Другими словами, можно прописать в функции какое-нибудь действие, которое Вы часто используете при написании запросов и просто вызывать ее в самом запросе. Тем самым запрос становится намного короче, проще и быстрей выполняется, а также к запросу добавляется динамика, так как функции могут быть динамические, т.е. возвращать разный результат в зависимости от входящего параметра или изменений в базе.
В функциях в СУБД PostgreSQL можно использовать все операторы SQL такие как: INSERT, DELETE, UPDATE и другие. И Вы теперь представьте, что можно прописать в функции!? а потом просто вызвать ее одной строкой.
Создание функций на PL/pgSQL
Теперь давайте будем учиться писать эти самые функции. И для начала ниже представлен общий синтаксис написания функции в PL/pgSQL:
CREATE OR REPLACE FUNCTION название функции (типы передаваемых данных через запятую) RETURNS тип возвращаемого значения AS $BODY$ DECLARE Объявление переменных BEGIN Тело программы RETURN возвращаемый результат; END; $BODY$ LANGUAGE язык, на котором написана функция (например, SQL или plpgsql) VOLATILE
Тип возвращаемого значения может быть разный, например, numeric, integer, text или, например void это тип, который не возвращает значение, а функция просто отрабатывает (например, добавляет новые строки).
Как лучше составить программу тренировок и прогрессировать | Турник и брусья
Сейчас давайте напишем простенькую функцию, пока без использования plpgsql. Допустим, у нас есть две таблицы с одинаковой строуктурой: test и test1:
Test1
id | name | flag | znach |
1 | mike | 1 | 10 |
2 | peter | 15 |
и Test2
id | number | name2 | tarif |
1 | 111 | mike1 | 2 |
2 | 222 | peter1 | 3 |
Например, мы часто используем в запросах объединение этих двух таблиц, для того чтобы подтянуть к таблице test1, столбец number из таблицы test2. Для упрощения всего этого давайте напишем простенькую функцию:
CREATE OR REPLACE FUNCTION «work».test_number(numeric) RETURNS numeric AS $BODY$ SELECT «number» FROM «work».»test2″ WHERE $BODY$ LANGUAGE ‘sql’ VOLATILE
- test_number — название функции;
- numeric — тип входящего параметра (он у нас один, но их может быть много);
- SELECT «number» FROM «work».»test2″ WHERE – запрос, т.е. тело функции. $1 передаваемый параметр;
- LANGUAGE ‘sql’ VOLATILE – язык, на котором написана функция.
Теперь давайте вызовем нашу функцию в запросе, это проще простого:
SELECT *, «work».test_number(id) AS Number FROM import.test1
где, «work».test_number(id) – это и есть вызов нашей функции. Мы передали ему параметр id, т.е. целую колонку, результат будет таким:
id | name | flag | znach | number |
1 | mike | 1 | 10 | 111 |
2 | peter | 15 | 222 |
Если нужно кого-то конкретного подтянуть, можно написать вот так, т.е. передать параметр 1 (id=1).
SELECT *, «work».test_number(1) AS Number FROM import.test1 WHERE style=»text-align: justify;»>Таким образом, у нас выведется одна строка:
id | name | flag | znach | number |
1 | mike | 1 | 10 | 111 |
Здесь мы с Вами обошлись без всякого рода объединений, согласитесь так намного проще, запрос короче и выполняется быстрей.
Теперь попробуем написать функцию уже с использованием языка PL/pgSQL. Допустим, мы хотим знать, кто в нашей таблице соответствует тому или иному признаку. Например, кто из наших сотрудников работает. Определять будем по признаку flag (1 – работает; 0 – не работает). При этом нам не удобно вспоминать чему соответствует этот признак, например 1, поэтому давайте напишем функцию, чтобы видеть надпись, напротив того или иного сотрудника. Пишем функцию:
CREATE OR REPLACE FUNCTION «work».test_if(numeric) RETURNS text AS $BODY$ DECLARE val ALIAS FOR $1; val1 integer; val2 text; BEGIN val1 :=1; IF val1 = val THEN val2 := ‘Он работает’; ELSE val2 := ‘Не работает’; END IF; RETURN val2; END; $BODY$ LANGUAGE ‘plpgsql’ VOLATILE
Здесь мы уже используем объявление переменных, условие и возвращение значения.
SELECT *, «work».test_if(flag) AS Status FROM import.test1
id | name | flag | znach | status |
1 | mike | 1 | 10 | Он работает |
2 | peter | 15 | Не работает |
Как Вы уже, наверное, поняли, что возможности функций практически не ограничены, на языке PL/pgSQL можно написать очень серьезные функции, с трудными расчетами и так далее. В данной заметке мы с Вами рассмотрели только основы написания, а дальше зависит только о Вас. Удачи!
Источник: info-comp.ru
Написание программ на чистом WinAPI
Попробуем написать с Вами программу, которая не будет пользоваться VCL, а будет использовать вызовы функций Windows API.
Приложения такого типа нужны, когда размер исполняемого файла является критичным. Например, в инсталяторах, деинсталяторах, самораспаковывающихся архивах и т.п. В крайнем случае, для того чтобы посмотреть какую работу выполняет за нас VCL, и что из себя представляет Windows-программа.
На самом деле все очень просто.
Для этого нам необходимо:
1. Зарегистрировать класс окна для окна главной формы.
function InitApplication: Boolean;
//Заполняем структуру TWndClass
// перерисовываем, если размер изменяется
wcx.style := CS_HREDRAW or CS_VREDRAW;
// адрес оконной процедуры
// handle to instance
// загружаем стандандартную иконку
wcx.hIcon := LoadIcon( 0 , IDI_APPLICATION);
// загружаем стандартный курсор
wcx.hCursor := LoadCursor( 0 , IDC_ARROW);
// делаем светло-cерый фон
// пока нет главного меню
// имя класса окна
// Регистрируем наш класс окна.
Result := RegisterClass(wcx) <> 0 ;
2. Написать подпрограмму обработки оконных сообщений.
function MainWndProc(Window: HWnd; AMessage, WParam,
LParam: Longint): Longint; stdcall ; export ;
//подпрограмма обработки сообщений
case AMessage of
Result := DefWindowProc(Window, AMessage, WParam, LParam);
3 . Создать главное окно приложения.
function InitInstance: HWND;
// Создаем главное окно.
// имя класса окна
// стандартный стиль окна
// стандартные горизонтальное, вертикальное положение, ширина и высота
0 , //нет родительского окна
hInstance, // handle to application instance
nil ); // no window-creation data
4 . Написать тело программы.
if ( not InitApplication) then
MessageBox( 0 , ‘Ошибка регистрации окна’ , nil , mb_Ok);
if (hwndMain = 0 ) then
MessageBox( 0 , ‘Ошибка создания окна’ , nil , mb_Ok);
// Показываем окно и посылаем сообщение WM_PAINT оконной процедуре
while (GetMessage(AMessage, 0 , 0 , 0 )) do
//Запускаем цикл обработки сообщений
5. Запустить программу на исполнение.;)
Наша программа пока только может немногое — отображать форму, и закрываться после нажатия на кнопку закрытия формы. Но посмотрите на размер исполняемого файла — он больше чем на порядок меньше созданного с использованием VCL.
Полный текст програмы:
uses Windows, Messages;
function MainWndProc(Window: HWnd; AMessage, WParam,
LParam: Longint): Longint; stdcall ; export ;
//подпрограмма обработки сообщений
case AMessage of
Result := DefWindowProc(Window, AMessage, WParam, LParam);
function InitApplication: Boolean;
//Заполняем структуру TWndClass
// перерисовываем, если размер изменяется
wcx.style := CS_HREDRAW or CS_VREDRAW;
// адрес оконной процедуры
// handle to instance
// загружаем стандандартную иконку
wcx.hIcon := LoadIcon( 0 , IDI_APPLICATION);
// загружаем стандартный курсор
wcx.hCursor := LoadCursor( 0 , IDC_ARROW);
// делаем светло-cерый фон
// пока нет главного меню
// имя класса окна
// Регистрируем наш класс окна.
Result := RegisterClass(wcx) <> 0 ;
function InitInstance: HWND;
// Создаем главное окно.
// имя класса окна
// стандартный стиль окна
// стандартные горизонтальное, вертикальное положение, ширина и высота
0 , //нет родительского окна
hInstance, // handle to application instance
nil ); // no window-creation data
if ( not InitApplication) then
MessageBox( 0 , ‘Ошибка регистрации окна’ , nil , mb_Ok);
if (hwndMain = 0 ) then
MessageBox( 0 , ‘Ошибка создания окна’ , nil , mb_Ok);
// Показываем окно и посылаем сообщение WM_PAINT оконной процедуре
while (GetMessage(AMessage, 0 , 0 , 0 )) do
//Запускаем цикл обработки сообщений
Последний раз мы рассмотрели пару ф-й и их особенности(FindWindow,
GetNextWindow и GetWindowText), однако несмотря на это были вопросы
именно на эту тему — вывод : торопитесь ребята. Старайтесь по
максимуму использовать, то что у Вас уже есть.
Итак вдогонку к 12-у выпуску хочется отметить, что при поиске окон,
как отмечалось, нужен класс и имя, так вот — если Вы ищите DOS-окно,
то его класс всегда = ‘tty’.
Сегодня рассмотрим некоторые вспомогательные функции, которые немного
облегчают и нашу жизнь, и программу в целом.
Получить каталог Windows( вдруг при установке Вы назвали его Unix 🙂 ).
s1 : array [ 0 .. 254 ] of Char;
В s1 получим искомый путь.
Один момент — не надо описывать s1 просто как PChar, иначе
при выполнении получите неприятное сообщение.
Анологично можно найти и системный каталог. Это тоже важно, поскольку,
например для Win9x это ‘WindowsSystem’, а для NT ‘System32’.
255 — это длинна строки. Отдельно подчеркну, что очень рекомендую вместо
этого числа ставить переменную Max_Path, содержащую в себе максимальную
длинну пути в Вашей операционной системе.
Еще очень интересная функция. Она позволяет запретить или разрешить все
действия с окном пользователю.
Где h-дескриптор окна, если сказать Application.Handle, то свое окно.
t=False — запретить действия, True — разрешить.
Ну и все с Api — функциями на этом.
Новые статьи
- Перехват нажатия на системные кнопки формы (закрытие , минимизация окна и т.д.)
- Как с помощью API поместить Label на Form?
- Как писать Win32API приложения на Delphi
- Пример приложений на чистом API
- Для чего нужен WinAPI
Источник: delphi-hlp.ru
«Функция» в теле программы. Как сделать?
Мне нужно создать функцию, но только в теле программы, в main’е. Но не могу, выдается как правило ошибка. Как по другому я могу сделать такое? Чтобы в начале мейна создать его, а потом в серединах программы вызвать его как функцию, одной строкой?
Отслеживать
задан 13 окт 2012 в 7:11
1,842 18 18 золотых знаков 75 75 серебряных знаков 131 131 бронзовый знак
Покажите, что у вас на данный момент уже имеется, и вам подскажут, как исправить.
13 окт 2012 в 7:32
13 окт 2012 в 7:36
13 окт 2012 в 7:46
13 окт 2012 в 9:07
13 окт 2012 в 10:32
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
C++ не поддерживает nested functions. В С можно сделать например так:
// Example 3 // int f( int i ) < int j = i*2; int g( int k ) < return j+k; >j += 4; return g( 3 ); >
Правда в С++ внутри тела функции можно поместить объявление класса, внутри которого поместить объявление соответствующей функции(с помощью перегрузки оператора ()) и получить таким образом функтор(объект-функцию), но это не будет работать так как внутри этого класса не будет видно членов main.
// Example 3(a): Naive «local functor» // approach (doesn’t work) // int f( int i ) < int j = i*2; class g_ < public: int operator()( int k ) < return j+k; // error: j isn’t accessible >> g; j += 4; return g( 3 ); >
Вот ссылка в которой рассмотрены различные трюки эмулирования поведения nested function через local class.
Еще добавлю что наверняка можно сделать еще проще и просто написать ваш код по первому варианту внутри директивы:
extern «C»<>
Источник: ru.stackoverflow.com