Sql server 能否限制(数据库)表中的行数?

Sql server 能否限制(数据库)表中的行数?,sql-server,Sql Server,我们有一个数据库(SQLServer2005),我们希望将其置于源代码控制之下。作为其中的一部分,我们将有一个版本表来存储数据库的当前版本号。有没有办法将该表限制为只能容纳一行?还是将版本号存储在表中是个坏主意 最终采用了这种方法: CREATE TABLE [dbo].[DatabaseVersion] ( [MajorVersionNumber] [int] NOT NULL, [MinorVersionNumber] [int] NOT NULL

我们有一个数据库(SQLServer2005),我们希望将其置于源代码控制之下。作为其中的一部分,我们将有一个版本表来存储数据库的当前版本号。有没有办法将该表限制为只能容纳一行?还是将版本号存储在表中是个坏主意

最终采用了这种方法:

CREATE TABLE [dbo].[DatabaseVersion]
    (
        [MajorVersionNumber] [int]  NOT NULL,
        [MinorVersionNumber] [int]  NOT NULL,
        [RevisionNumber] [int]  NOT NULL
    )
GO

Insert DataBaseVersion (MajorVersionNumber,  MinorVersionNumber,  RevisionNumber) values (0, 0, 0)
GO

CREATE TRIGGER DataBaseVersion_Prevent_Delete
ON DataBaseVersion INSTEAD OF DELETE
AS
BEGIN
    RAISERROR ('DatabaseVersion must always have one Row. (source = INSTEAD OF DELETE)', 16, 1) 
END
GO

CREATE TRIGGER DataBaseVersion_Prevent_Insert
ON DataBaseVersion INSTEAD OF INSERT
AS
BEGIN
    RAISERROR ('DatabaseVersion must always have one Row. (source = INSTEAD OF INSERT)', 16, 1) 
END
GO

使用触发器。

一点也不。您只需向该表中添加另一个升序列(日期、id等),然后按该列的降序对查询进行排序,并将结果限制为1行:

SELECT v.version FROM version v ORDER by v.date DESC LIMIT 1;
这样,您甚至可以获得每个版本何时到达的历史记录

编辑:


上面的sql查询无法在sql Server上运行,因为它不支持LIMIT语句。您必须绕过这一缺陷,可能如本文所述。

将表概括为包含“设置”,并使其成为键/值对

CREATE TABLE Settings (Key nvarchar(max), Value nvarchar(max))
然后在键上创建一个唯一的索引

CREATE UNIQUE INDEX SettingsIDX ON Settings (Key)
这将创建一个具有唯一键值对的表,其中一个可以是Version

INSERT INTO Settings (Key, Value) VALUES ('Version','1');

通过创建一个允许的原始行作为数据库初始化脚本的一部分,以及(也在该脚本中)删除所有登录对该表的插入权限(只允许更新)


您可能还想禁止删除

根据您对其他回复的评论,似乎:

  • 您不希望用户只修改值
  • 您只希望返回一个值
  • 该值是静态的,并且是脚本化的
  • 那么,我可以建议您编写一个返回静态值的函数脚本吗?由于您无论如何都必须编写版本号更新的脚本,因此在更新数据库时只需删除并重新创建脚本中的函数

    这样做的优点是可以从视图或过程中使用,并且由于函数的返回值是只读的,因此不能修改它(不修改函数)

    编辑:您也不必担心将表限制在一行的复杂解决方案


    只是一个建议

    保留数据库的版本号完全有意义。但是,我更希望有一个版本表,它可以包含多行,其中包含版本号、发生更新的时间和执行升级的用户的字段

    这样,您就可以知道哪些升级脚本已经运行,并且可以很容易地查看它们是否已按顺序运行

    当您想读取当前版本号时,只需读取最新的记录即可


    如果您只存储一条记录,您就知道如何知道是否遗漏了脚本。如果你想变得更聪明,你可以在升级脚本中加入检查,这样它们就不会运行,除非以前版本的数据库是正确的。

    你可以使用Joe Celko的默认+主+检查技术:

    create table database_version (
    
      lock char(1) primary key default 'x' check (lock='x'),
      major_version_number int NOT NULL,
      minor_version_number int NOT NULL,
      revision_number int NOT NULL
    );
    

    有了它

    我自己也做过,但这不是我的第一选择:1)nvarchar(max)对于钥匙来说似乎有点大。2) 未键入值。设置表通常很小,因此大小不是问题。我使用文本字段作为版本号,因为它允许“1.0.0.4”之类的内容。。。我从来不需要增加版本号……我不喜欢这个解决方案,因为它依赖于有效的权限管理来实现逻辑的正确运行。表应该强制执行。我的理由是,如果表强制执行它,所有用户都会使用它,即使是SA等。如果管理员添加了一个用户并破坏了权限,它仍然可以工作。如果允许某些用户添加复制,但不允许其他用户(imho),则您的方法会更好。此外,如果您将此数据库部署到另一台服务器,则必须记住正确设置用户帐户。(可能失败)。Kieran建议的“设置”表更加灵活,可以更有效地利用资源。1表1行,也可以用XML文件归档。我想如果你不熟悉这项技术,那么对你来说会很奇怪。。。我个人经常使用权限,并且发现它们在某些场景中非常直观和合适——就像这样。我不会将它们应用于用户,而是应用于应用程序登录。。。这些都是脚本。触发器也是我的第一个想法。在Insert上,查看条目是否存在并只是失败,或者理想情况下使用存储过程执行更新。也许你可以改变你的答案,让它更详细一点?这会很有帮助。插入操作可以无声地更改为更新,而不是引发错误。我没有意识到这一点。谢谢。从v版中选择TOP 1 v版,按v日期订购。是的,我同意,这也是一个很好的解决方案。尽管我认为表限制在一行或函数都同样好。从语义上来说,虽然我更喜欢将表作为版本号,但这感觉像是一段数据,而不是功能(但这只是事后的一个小想法)。