我正在使用事务数据库:一个关系数据库,其中表中的行被定义为数据集,在给定时间,数据库“认为”该行的字段包含。
架构的一部分:
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)
);
换句话说,虚拟“文章”表有三列: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是否有任何类似的功能?
答案 0 :(得分:1)
您可以创建三个存储过程并将Time作为变量传递给每个存储过程。
对于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”
但我确信有一种更简单的方法,但这是我能想到的唯一方法。