SQL:作为表中值的函数查看

Posted

技术标签:

【中文标题】SQL:作为表中值的函数查看【英文标题】:SQL: view as function of value in table 【发布时间】:2011-12-05 01:15:48 【问题描述】:

我正在使用事务性数据库:一个关系数据库,其中表中的一行被定义为数据库在给定时间“认为”该行的字段包含的一组值。

部分架构:

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 有没有类似的功能?

【问题讨论】:

【参考方案1】:

您可以创建三个存储过程并将 theTime 作为变量传递给每个存储过程。

对于 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"

但我确信有更简单的方法,但这是我能想到的唯一方法。

【讨论】:

前两个程序其实正是我所需要的。然后我只创建第三个过程: CREATE PROCEDURE Article_at @theTime DATETIME AS SELECT id, heading, body FROM Article, Article_headline_at(@theTime), Article_body_at(@theTime)

以上是关于SQL:作为表中值的函数查看的主要内容,如果未能解决你的问题,请参考以下文章

SQL SERVER 数据库中查看文本字段中的数据长度LEN() 函数的使用方法

调试 MS SQL 函数时查看临时表的数据

SQL SERVER如何查看一个表被哪些存储过程用到?用哪个系统存储过程?

sqlserver 怎么查看表的数据是加密的

sql SQL计算表中值实例的百分比

在ORACLE如何查看自己建立的所有表,而不是系统表