Вопрос

Мне было интересно, существует ли какой-либо код, который позволяет представлять SQL в виде некоторого дерева объектов, которое может быть собрано, изменено и затем, наконец, отображено в действительный SQL?

С моей точки зрения, это могло бы выглядеть примерно так...

var stmnt = new Statement();
stmnt
  .AddMaster("Customer")
  .Show("Firstname, "Lastname")
  .AddJoin("Address", "ID", "CustomerID")
  .Show("Street", "City");
stmnt.WhereStatement()
  .AddParameter("Address.City", Op.Equal);

string sql = stmnt.Generate();
// select a.FirstName, a.LastName, b.Street, b.City
// from Customer a
// join Address b on b.CustomerID = a.ID
// where b.City = :p1

Это всего лишь пример, и то, что там есть, может работать совершенно по-другому, но да, я хотел бы услышать, что есть на этот счет.

Обновить:

Я осведомлен о многочисленных возможностях использования технологий ORM для получения моих результатов из базы данных, но мне нужна была модель для самого SQL.Я знаю, что уровень абстракции довольно низкий, но, возможно, это может привести к ситуации, когда несколько сотрудников могут работать над инструкцией SQL (несколько соединений, несколько wheres), которая затем может быть "визуализирована" в конце фазы сборки.

Это было полезно?

Решение

Пакет python SQLAlchemy имеет уровень ORM, но он также имеет уровень генерации SQL.

[Я понимаю, что вы отметили этот пост c # и .net, но я подумал, что вам, возможно, захочется посмотреть, что там еще есть]

Вот несколько примеров кода:

from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.sql import select

metadata = MetaData()

# Make a basic customer table.
Customer = Table('Customer',
                 metadata,
                 Column('ID', Integer, primary_key=True),
                 Column('FirstName', String),
                 Column('LastName', String))

# Make a basic address table
Address = Table('Address',
                metadata,
                Column('ID', Integer, primary_key=True),
                Column('City', String),
                Column('Street', String),
                Column('CustomerID', None, ForeignKey('Customer.ID')))


# Generate some sql
stmt = select([Customer.c.FirstName,
               Customer.c.LastName,
               Address.c.Street,
               Address.c.City],
              from_obj=Customer.join(Address),
              whereclause=Address.c.City == 'Wellington')

# Display
print stmt
# output:
SELECT "Customer"."FirstName", "Customer"."LastName", "Address"."Street", "Address"."City" 
FROM "Customer" JOIN "Address" ON "Customer"."ID" = "Address"."CustomerID" 
WHERE "Address"."City" = :City_1

# note that SQLAlchemy picked up the join condition from the foreign key.
# you can specify other join conditions if you want.

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

for row in stmt.execute():
    print 'Name:', row.c.FirstName, row.c.LastName, 'City:', row.c.City

Надеюсь, это поможет.

Другие советы

Hibernate имеет свой собственный язык запросов Hibernate (HQL), который представляет SQL-подобные конструкции в виде объектов.

ИЛИ-картограф, такой как Microsoft LINQ ( ссылка )

Вот несколько примеров:

from c in customers
where c.LastName.StartsWith("A")
select c

//

var q = from c in db.Contact
           where c.DateOfBirth.AddYears(35) > DateTime.Now
           orderby c.DateOfBirth descending
           select c;

Несколько ссылок, которые помогут вам начать:

Смотрите выше, и я видел, как не один программист шел по этому пути.(И я говорил не одному программисту, что видел не одного программиста ..., но обычно они в конечном итоге сами выясняют, насколько хорошо это работает.)

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

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

Вы можете попробовать МетаДб.Кое-какая работа уже проделана.Пример запроса http://i3.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=metadb&DownloadId=11482

Но если вы можете использовать .NET 3.5, вы можете использовать LINQ.

В .Net Linq делает в значительной степени то, о чем вы говорите.

Если вы все еще используете .NET 2.0 и не перешли на LINQ, то я бы создал базовый класс statement, а затем создал классы, которые допускают шаблон декоратора.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top