FileMaker + PHP: полная поддержка SQL

Автор: Андрей Волков

В отличие от очень многих СУБД FileMaker не поддерживает управление данными с помощью языка структурированных запросов SQL. Несмотря на то, что в 12 версии в FileMaker была введена функция Execute SQL, разработчики получили лишь возможность извлекать с ее помощью данные  в простом текстовом виде.

Такие операции, как UPDATE, INSERT, DELETE (то есть обновление, добавление и удаление записей), с помощью Execute SQL выполнить невозможно.

Начиная с 13 версии, с появлением команды Perform Script On Server, эта проблема несколько потеряла свою актуальность. Команда в принципе позволяет выполнить названные выше операции, хотя и несколько варварским методом: для каждой операции приходится создавать и хранить отдельный скрипт.

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

Под PHP расширением в данном случае мы будем понимать специальный php-файл, который мы подложим на сервер в папку C:\Program Files\FileMaker\FileMaker Server\Web Publishing\web-server-support\test\fmi-test\

И к которому сможем обратиться через веб-запрос: http://hostipaddress/fmi-test/sql.php

Этот файл будет обращаться к базам данных файлмейкер, используя подключение ODBC. Чтобы это стало возможным, необходимо на сервере (там же, где размещен php файл):

  •  установить ODBC драйвер для файлмейкера,
  • в настройках файлмейкер сервера разрешить подключение по ODBC и активизировать Web Engine,
  • в самих базах данных создать акаунт с привилегией Access via ODBC.

Драйвер FileMaker ODBC driver входит в дистрибутив файлмейкер сервера. Там два дистрибутива: для 32-х и для 64-битных приложений. Скорее всего, потребуется 32-битный драйвер, но можно не особо смущаясь инсталлировать оба. Процесс инсталляции не требует никаких специальных знаний.

Я бы также порекомендовал для всех баз данных использовать один и тот же акаунт для odbc подключений. В этом случае логин и пароль можно попросту «записать» в php файл. Тогда для запуска SQL потребуется только указать два параметра: имя файла базы данных, в котором выполняем запрос, и собственно текст запроса (так называемый SQL стейтмент).

Про запуск SQL мы уже говорили в одной из предыдущих статей: используется команда Insert From URL ($url), в которой $url будет собираться следующим образом:

«http://hostipaddress/fmi-test/sql.php?db=» & $filename & «&sql=» & GetAsUrlEncoded($sql)

Где переменная $filename передает имя базы данных, а переменная $sql собственно содержит sql-запрос.

Например, удалить все записи из таблицы test_table в файле my_test_ db поможет следующий веб-запрос:

http://hostipaddress/fmi-test/sql.php?db=my_test_db&sql=DELETE%20ALL%20FROM%20test_table

Давайте теперь рассмотрим файл sql.php, который будет выполнять все наши распоряжения.

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

Шаг 1. Подключение к базе данных по ODBC (http://hostipaddress/fmi-test/sql.php)

<?php

// Замените параметры подключения на ваши актуальные значения //

$conn = odbc_connect(«DRIVER={FileMaker ODBC};Server=109.100.100.10;Database=my_db;», «login», «password»);

odbc_close($conn);

?>

Замените параметры подключения на ваши актуальные значения.

Итак, в нашем файле всего две строки. Первая открывает соединение по ODBC, вторая закрывает это соединение. Как нам проверить, что у нас все работает? Давайте выводить в браузер результат нашей работы

<?php

$conn = odbc_connect(«DRIVER={FileMaker ODBC};Server=109.100.100.10;Database=my_db;», «login», «password»);

odbc_close($conn);

echo $conn; // выводит в окно браузера содержимое переменной $conn

?>

Если все настроено правильно, то в браузере мы увидит такое сообщение: Resource id #1

Шаг 2. Попробуем выполнить какой-нибудь sql запрос

<?php

$conn = odbc_connect(«DRIVER={FileMaker ODBC};Server=109.100.100.10;Database=my_db;», «login», «password»);

$rs = odbc_exec($conn,’INSERT INTO my_test_table (test_field) Values(66)’);

odbc_close($conn);

echo $rs; // выводит в окно браузера содержимое переменной $rs

?>

Проверить работу просто. В браузере мы увидим: Resource id #2

В самой же базе данных в таблице my_test_table будет создана новая запись, в которой поле test_field будет значение 66

Пару слов про транзакции. По умолчанию режим транзакций отключен. То есть выполнение команды odbc_exec() ведет непосредственно к изменению состояния базы данных. Но для нашего примера этот режим особо и не нужен, ведь мы выполняем всегда всего лишь один запрос, а не последовательность запросов. При выполнении групповой операции, например, обновлении или удалении группы записей, команда и так не будет выполнена, если хотя бы одна из записей заблокирована пользователем.

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

<?php

error_reporting(0); // отключаем вывод системных сообщений об ошибке

$conn = odbc_connect(«DRIVER={FileMaker ODBC};Server=109.100.100.10;Database=my_db;», «login», «password»);

odbc_autocommit($conn, false); // отключаем автосохранение после каждого запроса

$rs = odbc_exec($conn,’UPDATE my_test_table SET test_field = 66′);

$rs2 = odbc_exec($conn,’UPDATE other_table SET any_field = 77′);

$error = odbc_errormsg($conn); // проверяем, была ли получена ошибка при выполнении запроса

if (!empty($error)) {

       echo «ERROR » . $error;

       odbc_rollback($conn);  // откат транзакции, если хотя бы один из запросов невозможно выполнить

       }      else {

       odbc_commit($conn);  // коммит транзакции

       echo «OK»;

}

odbc_close($conn);

?>

Заодно в этом примере мы сделали обработку ошибок. Теперь если запрос выполнен успешно, в браузере отобразится ОК; если же одна из записей была заблокирована, то увидим:

ERROR [FileMaker][FileMaker] (301): Record is locked by another user

Шаг 3. Теперь мы должны изменить наш файл. Сделаем так, чтобы php-файл считывал SQL-стейтмент, переданный в запросе, и сразу выполнял его, сообщая об успехе или ошибке выполнения.

<?php

error_reporting(0); // отключаем вывод системных сообщений об ошибках

if ( isset($_GET[‘sql’])) {        $sql = $_GET[‘sql’]; } else {exit;}

if ( isset($_GET[‘db’])) { $db = $_GET[‘db’]; } else {exit;}

$host = «109.100.100.10»; // подставьте ваши реальные данные

$login = «login»; // подставьте ваши реальные данные

$password= «password»; // подставьте ваши реальные данные

$conn = odbc_connect(   «DRIVER={FileMaker ODBC};Server=» . $host . «;Database=» . $db . «;»,  $login, $password);

$rs = odbc_exec($conn,$sql);

$error = odbc_error($conn); // проверяем, была ли получена ошибка при выполнении запроса

if (!empty($error)) {

       echo «ERROR » . $error;

} else {

       echo «OK»;

}

odbc_close($conn);

?>

Вот и все. Успешных шагов!

  1. Великолепная статья!
    Вопрос — а запросы изменяющие структуру базы, типа CREATE TABLE и ALTER TABLE — будут работать? То есть можно ли изменить таким образом структуру таблиц из скрипта самого FileMaker?

    • ‘ALTER TABLE roles ADD mydate date’
      ‘ALTER TABLE roles ADD mytext varchar’

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

    • Ну например, для объединения данных из разных таблиц в одну (UNION) для последующего экспорта. Это гипотетический пример.
      Реляции вы, конечно, не создадите, они же не командами SQL делаются, это что-то внутренне FM, насколько я понимаю.

    • мне кажется, полной и удобной автоматизации здесь не достичь.
      экспортировать можно в CSV

    • Вопрос был скорее гипотетический — позволяет ли FileMaker, менять структуры базы с помощью SQL запроса, а не Manage Database. Выяснили — позволяет. Запомним на будушее — может пригодится.

  2. Важное дополнение.
    Если мы приконнектились к некоему файлу базы данных, то ODBC запросы возможны не только для физических таблиц, которые в этом файле имеются, но вообще в отношении всех логических таблиц, которые вынесены в Relationships Graph. То есть в рамках одной сессии (транзакции) можно получать данные и изменять данные в таблицах нескольких разных файлов. Это весьма и весьма удобно.

Добавить комментарий для Marielle Ahles Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

37 − = 33