Возможности SQL не безграничны, и тем более не безгранично воображение программистов. Иногда очень сложно соорудить запрос, который выполнял бы в базе данных необходимые действия за один проход, намного проще выполнить одно действие и на основании полученного результата выполнить следующее действие. Для хранения результата можно использовать временные таблицы, которые автоматически будут уничтожаться после выполнения запроса.
В MS SQL Server вы можете создавать локальные и глобальные временные таблицы. Локальные временные таблицы будут видны только вашей сессии, а глобальные таблицы видны всем сессиям. При этом и те, и другие таблицы, уничтожаются после завершения сессии.
Чтобы таблица стала временной локально видимой, перед именем нужно поставить символ #, например, в следующем примере создается временная таблица #TestTable с одним только полем идентификатором, который является первичным ключом:
CREATE TABLE #TestTable ( id INT PRIMARY KEY )
Таблица будет существовать только во время выполнения одной сессии, и работать с ней сможете только вы. Например, вы написали большой сценарий, выполняющий определенные действия (например, процедуру, хранящуюся на сервере). Если в этом сценарии создать временную таблицу, то она будет существовать, только пока выполняется сценарий. После этого она автоматически уничтожается.
Попробуйте создать таблицу. Теперь попробуйте получить все данные из таблицы с помощью запроса:
SELECT * FROM #TestTable
В результате должна появиться пустая таблица (мы только создали таблицу, но не наполняли ее) из одной колонки с именем id.
Закройте соединение с базой данных или просто перезапустите программу, которую вы используете для отладки запросов. Снова выполните запрос выборки данных из временной таблицы. В ответ должна появиться ошибка: "Invalid object name '#TestTable'" (неправильное имя объекта #TestTable).
Давайте снова создадим временную таблицу. Таблица будет создана, а если бы такой объект уже существовал, то мы увидели бы ошибку. Проверьте существование временной таблицы с помощью запроса выборки данных. Ошибок не должно быть. Откройте новое соединение или еще одну копию программы отладки запросов и выполните выборку данных из временной таблицы в этой копии программы. В ответ должна снова появиться ошибка, о не существовании объекта, потому что в другой программе создается новая сессия, и вы не можете видеть, что локальные таблицы других пользователей.
Глобально видимые таблицы работают также, но в момент существования видны всем подключенным к серверу клиентам. Имена таких таблиц начинаются с двух символов ##. Следующий пример создает глобально временную таблицу:
CREATE TABLE ##TestTable ( id INT PRIMARY KEY )
Такая таблица будет существовать, пока существует сеанс с базой данных, создавшей таблицу, и все это время любой пользователь может работать с глобально временной таблицей.
Во временных таблицах нельзя использовать внешние ключи. Нет, ошибки не будет, и при попытке создать таблицу, она будет создана корректно, но попытки создать внешний ключ будут игнорироваться. Видимо, это связано с тем, что из-за внешнего ключа усложняется удаление таблиц и нужно следовать определенной последовательности. Сервер SQL от Microsoft не может себе позволить такую роскошь, да наверно и другие тоже.
Не смотря на то, что мы рассматриваем тему временных таблиц, я настоятельно рекомендую вам не использовать их в своих проектах. Если вы думаете, что в определенном месте они помогут вам решить проблему, то попробуйте найти другое решение. Если новое решение не приходит на ум, нужно продолжать искать более простой способ. Очень часто программисты используют временные таблицы только из-за того, что не могут объединить некоторые действия в один запрос. Данная книга направлена на то, чтобы научить вас не просто использовать SQL, а делать это эффективно. Временные таблицы, на мой взгляд, являются самым не эффективным решением проблемы.
Единственный случай, когда я использую временные таблицы, когда выполняются следующие условия в условии задачи:
Чтобы в течение создания отчета данные были неизменными, их можно выбрать во временную таблицу и потом уже над этими данными выполнять формирование выходных данных. Есть еще один способ решение задачи – блокировка. Можно заблокировать таблицу для изменений, но это не очень хорошее решение, когда происходит интенсивная работа изменения и добавления данных. После блокировки таблицы, пользователи уже не смогут производить модификаций, что не всегда приемлемо. В такой задаче лучше подумать о возможном использовании временных таблиц.
Возможно, есть и другие задачи, когда временные таблицы могут помочь в решении задачи, но я в своей практике с ними не встречался.