Одна из вещей, которая раздражает меня работающий с SQL на языках OO, должна определить SQL-операторы в строках.
Когда я раньше работал над универсальными компьютерами типа IBM, языки использовали препроцессор SQL для парсинга SQL-операторов из собственного кода, таким образом, операторы могли быть записаны в открытом тексте SQL без путаницы строк, например, в Коболе существует ДОЛЖНОСТНОЕ ЛИЦО SQL.... Конструкция синтаксиса ДОЛЖНОСТНОГО ЛИЦА КОНЦА, которая позволяет чистым SQL-операторам быть встроенными в код Кобола.
<pure cobol code, including assignment of value
to local variable HOSTVARIABLE>
EXEC SQL
SELECT COL_A, COL_B, COL_C
INTO :COLA, :COLB, :COLC
FROM TAB_A
WHERE COL_D = :HOSTVARIABLE
END_EXEC
<more cobol code, variables COLA, COLB, COLC have been set>
... это делает SQL-оператор действительно легким читать и проверить ошибки. Между ДОЛЖНОСТНЫМ ЛИЦОМ SQL.... Маркеры ДОЛЖНОСТНОГО ЛИЦА КОНЦА там не являются никакими ограничениями на добавление отступа, linebreaking и т.д., таким образом, можно отформатировать SQL-оператор согласно вкусу.
Обратите внимание, что этот пример для выбора одной строки, когда набор результатов нескольких-строк ожидается, кодирование отличается (но все еще v. легкий читать).
Так, беря Java в качестве примера
Что заставило "старый КОБОЛ" приблизиться к нежелательному? Не только SQL, но и системные вызовы могли быть сделаны намного более читаемыми с тем подходом. Давайте назовем это встроенным подходом препроцессора иностранного языка.
Был бы встроенный препроцессор иностранного языка для SQL быть полезным для реализации? Вы видели бы преимущество в способности записать собственные SQL-операторы в коде Java?
Я действительно спрашиваю, думаете ли Вы, что SQL на языках OO является возвратом, и если не затем, что могло бы быть сделано для создания его лучше.
В Java уже есть стандарт для встроенного SQL, он называется SQLJ.
Сказав это, я никогда не видел, чтобы он использовался в дикой природе, и я понятия не имею, действительно ли это опция, с современными инструментами. Оракул пошел на это по-крупному, когда появился стандарт, но я думаю, что он умер на виноградной лозе.
.В SQL-домене уже есть нечто похожее на "встроенный препроцессор языка" для Java и .NET: http://ibatis.apache.org/
Кроме того, люди обычно используют полноценный ORM, как Hibernate, для абстрагирования SQL.
Имейте в виду, что эти инструменты не позволяют хранить SQL-строки в самом Java-коде, а служат аналогичным целям. Лично я не вижу никакой пользы в хранении SQL-строк в самом коде, так как это обычно мессье. Наличие всего SQL аккуратно написанного в конкретном файле помогает многократному использованию и удобству обслуживания вашего SQL. Они действительно позволяют SQL в качестве строк, если в этом возникает необходимость, но это, как правило, крайняя мера (когда инструмент ORM не имеет хорошей абстракции для вашего случая использования)
EDIT: Я действительно думаю, что смешивание SQL и кода (будь то OO или нет) является хрупким и нежелательным. Гораздо лучше иметь централизованное место для хранения ваших запросов. Это подход iBATIS.
Для текущего состояния дел могу предложить следующие пункты
Есть много проблем с встраиванием sql как части языка:
С другой стороны, DSL сейчас - это все шумиха. И есть языки, в которых есть XML-литералы. Так что я думаю, что вполне возможно, что появятся (или уже существуют) языки, которые имеют ORM как встроенные возможности и позволяют использовать SQL (или HQL?) как DSL внутри кода
.Объектно-реляционные инструменты картирования, такие как Hibernate, теоретически делают подобные вещи менее проблематичными. "теоретически" ;)
Также, если вы можете использовать Грааль, я слышал, что можно просто писать фантастические многострочные строки, что облегчает чтение SQL выражений.
.Ну, самый простой, самый тупой способ сделать это - просто включить SQL как строку в свой код.
Что-то вроде
Statement s = new Statement("Select * from wherever");
Может быть не очень сложное, но это работает. Недостатком является то, что компилятор не может проверить синтаксис SQL. Немного лучшим решением является Prepaired Statements, где вы указываете параметочный шаблон. Так что вы можете делать такие вещи:
PreparedStatement s = connection.prepareStatement("Select * from wherever where state = ?");
Таким образом, ваше JDBC соединение должно бросить исключение, как только вы создадите готовый оператор во время выполнения. Так что если код работает в первый раз, он всегда должен работать.
Затем в вашем коде позже, когда вы захотите изменить параметр, который вы делаете:
s.setString(1, "CA");
В Microsoft есть встроенный язык запросов для .net под названием LINQ. Для баз данных вы используете LINQ to SQL, что позволяет встраивать запросы прямо в ваш код.
Вы можете обойти такую неспособность с достойным IDE. Например, IDELE IDEA поддерживает функции, которые называются инъекционными языками. Это позволяет вам писать код на языке, который вы хотите внутри строкового литерала и иметь возможность использовать выделение кода, завершение, навигацию и другие услуги. Вы можете прочитать подробнее об этом здесь: http://blogs.jetbraines.com/idea/2009/03/user-defined-language-inized/