您的两个条件都可以用于 100 行表。或者,甚至是 1,000 行的表。但是,下面的示例不是生产表的推荐操作。
RE:“最多有 100 行”
创建表,然后添加一个 INSTEAD OF INSERT 触发器,在允许插入之前检查表的大小。
RE:“类似于将(插入时)推入表中。”
使用聚集主键(推荐)创建表,但使用 DESC 键(不推荐用于除了小的、很少使用的表之外的任何东西)。 CLUSTERED 索引是物理排序的。因此,添加下一个更大的数字(如在 IDENTITY 序列中)会将新条目推到索引的顶部。 SELECT 将按磁盘顺序返回行。对于具有聚集索引的 100 行表而言,磁盘顺序和索引顺序是相同的。
代码:
注意:下面的代码将 max_size 限制为 3 以进行演示。为您的示例设置 @max_size = 100
-->-- create table with descending order for primary key. will act like a push down stack
IF OBJECT_ID('dbo.so_limit_size') IS NOT NULL DROP TABLE dbo.so_limit_size
CREATE TABLE dbo.so_limit_size (
id TINYINT IDENTITY(1,1)
, name VARCHAR(100)
, city VARCHAR(100)
, CONSTRAINT pk_so_limit_size PRIMARY KEY CLUSTERED (id DESC) -- DESC makes it work like a push down stack
)
INSERT INTO dbo.so_limit_size (name, city)
VALUES
( 'Mike', 'New York City' )
, ( 'David', 'Pekin' )
, ( 'Marcus', 'Warsaw' )
SELECT * FROM dbo.so_limit_size -- 3 rows
GO
CREATE TRIGGER dbo.limit_size ON dbo.so_limit_size
INSTEAD OF INSERT AS
SET NOCOUNT ON
-- purpose: limit size of table to @max_size. insert batch of 1 or more that exceeds @max_size will not be allowed
DECLARE @max_size TINYINT = 3 -- size limit of table
DECLARE @existing_count TINYINT = (SELECT COUNT(*) FROM dbo.so_limit_size)
, @insert_count TINYINT = (SELECT COUNT(*) FROM Inserted )
PRINT 'existing_count = ' + LOWER(@existing_count) + ' new insert count = ' + LOWER(@insert_count)
IF @existing_count + @insert_count >= 3
BEGIN
PRINT 'insert will cause table count to exceed max_size. insert aborted. max_size = ' + LOWER(@max_size)
END
ELSE
BEGIN
PRINT 'table count less than max_size. insert allowed. max_size = ' + LOWER(@max_size) --<<-- demonstration, print is not a recommended practice for a trigger
INSERT INTO dbo.so_limit_size (name, city)
SELECT name, city FROM inserted
END
GO
INSERT INTO dbo.so_limit_size (name, city)
VALUES
( 'Zorba', 'Athens' ) -- will not be allowed if @max_size = 3
SELECT * FROM dbo.so_limit_size