SQL: представление как функция значения в таблице - PullRequest
1 голос
/ 05 декабря 2011

Я работаю с транзакционной базой данных: реляционной базой данных, где строка в таблице определяется как набор значений, которые база данных в данный момент времени «думает» о полях строки.

Часть схемы:

CREATE TABLE Article
(
    id INTEGER,
    PRIMARY KEY(id)
);

CREATE TABLE Article_headline
(
    Article_id INTEGER,
    headline TEXT,
    tt DATETIME
    FOREIGN KEY(Article_id) REFERENCES Article(id)
);

CREATE TABLE Article_body
(
    Article_id INTEGER,
    body TEXT,
    tt DATETIME
    FOREIGN KEY(Article_id) REFERENCES Article(id)
);

Другими словами, виртуальная таблица «Article» имеет три столбца: id, заголовок и тело.

Я могу создать временные представления для представления виртуальной таблицы «Статья», определенной в данное время:

CREATE TEMPORARY VIEW Article_headline_old
AS SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= "2011-11-03 16:05:23"
GROUP BY Article_id;

CREATE TEMPORARY VIEW Article_body_old
AS SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= "2011-11-03 16:05:23"
GROUP BY Article_id;

CREATE TEMPORARY VIEW Article_old
AS SELECT id, headline, body
FROM Article, Article_headline_old, Article_body_old
WHERE Article_headline_old.Article_id = Article.id
AND Article_body_old.Article_id = Article.id;

Мне нужно создавать эти три временных представления каждый раз, когда я хочу запросить базу данных, чтобы получить статью, чего я бы предпочел не делать. Я бы предпочел создать «функции» постоянного представления как часть самой схемы:

CREATE VIEW Article_headline_at(theTime)
AS SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= theTime
GROUP BY Article_id;

CREATE VIEW Article_body_at(theTime)
AS SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= theTime
GROUP BY Article_id;

CREATE VIEW Article_at(theTime)
AS SELECT id, headline, body
FROM Article,
     Article_headline_at(theTime) AS Article_headline_old,
     Article_body_at(theTime) AS Article_body_old
WHERE Article_headline_old.Article_id = Article.id
AND Article_body_old.Article_id = Article.id;

А потом, когда я хочу выбрать статью из базы данных:

SELECT * FROM Article_at("2011-11-03 16:05:23");

Есть ли в SQL аналогичные функции?

1 Ответ

1 голос
/ 05 декабря 2011

Вы можете создать три хранимые процедуры и передать каждому время как переменную.

Для Article_headline_at и Article_body_old_at вставьте эти хранимые процедуры во временную таблицу внутри хранимых процедур Article_at и выполните запрос.Это может быть вашим решением:

CREATE PROCEDURE Article_headline_at @theTime datetime as

SELECT Article_id, headline, MAX(tt)
FROM Article_headline
WHERE tt <= theTime
GROUP BY Article_id;

-----



CREATE PROCEDURE Article_body_old_at @theTime datetime as
SELECT Article_id, body, MAX(tt)
FROM Article_body
WHERE tt <= theTime
GROUP BY Article_id;

-----

CREATE PROCEDURE Article_at @theTime datetime as
IF OBJECT_ID('tempdb.dbo.#Article_headline_at') IS NOT NULL DROP TABLE tempdb.dbo.#Article_headline_at
IF OBJECT_ID('tempdb.dbo.#Article_body_old_at') IS NOT NULL DROP TABLE tempdb.dbo.#Article_body_old_at

create table #Article_headline_at (
Article_id int,
body nvarchar(max),
tt int
)

create table #Article_body_old_at (
Article_id int,
headline nvarchar(max),
tt int
)

declare @sql1 nvarchar(max)
declare @sql2 nvarchar(max)

set @sql1 = 'insert into #Article_headline_at exec #Article_headline_at @theTime = '''+ @theTime + ''''
set @sql2 = 'insert into #Article_body_old_at exec #Article_body_old_at @theTime = '''+ @theTime + ''''

exec sp_executesql @sql1
exec sp_executesql @sql2


SELECT id, headline, body
FROM Article, #Article_headline_at(theTime), #Article_body_at(theTime)
WHERE #Article_headline_old.Article_id = Article.id
AND #Article_body_old.Article_id = Article.id;

-----

, поэтому в конце всего этого вы можете сделать

exec Article_at @theTime = "2011-11-03 16:05:23"

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

...