views:

474

answers:

4

Hi,

I'd like to limit the entries in a table. Let's say in table tBoss. Is there a SQL constraint that checks how many tuples are currently in the table? Like

SELECT COUNT(*) from tBoss < 2

Firebird says:

Invalid token. Dynamic SQL Error. SQL error code = -104. Token unknown - line 3, column 8. SELECT.

Thanks. Norbert

A: 
SELECT COUNT(*) FROM tBoss WHERE someField < 2 GROUP BY someUniqueField
RayZ
Thank you, but the whole table should not contain more than 2 entries. So what's the solution without a *where*? I get an error.
Norbert
+1  A: 

To find multiples in a database your best bet is a sub-query for example: (Note I am assuming you are looking to find duplicated rows of some sort)

SELECT id FROM tBoss WHERE id IN ( SELECT id FROM tBoss GROUP BY id HAVING count(*) > 1 )

where id is the possibly duplicated column

Mike Valstar
My thought pattern (and assumption) were following this tract, but insufficient data in the question to isolate what the real goal is at least as of this writing.
Mark Schultheiss
+3  A: 

Does your database have triggers? If so, Add a trigger that rolls back any insert that would add more than 2 rows...

Create Trigger MyTrigName
For Insert On tBoss
As
    If (Select Count(*) From tBoss) > 2
       RollBack Transaction
Charles Bretana
Shannon Severance
I "think" that because each Insert would place locks on the rows it is inserting, which would not be released until the trigger had finished, and allowed the transaction to be committed, that a table lock would not be necessary, but I'm not sure ofthis last point.
Charles Bretana
A: 

You could do this with a check constraint and a scalar function. Here's how I built a sample.

First, create a table:

CREATE TABLE MyTable
 (
   MyTableId  int           not null  identity(1,1)
  ,MyName     varchar(100)  not null
 )

Then create a function for that table. (You could maybe add the row count limit as a parameters if you want more flexibility.)

CREATE FUNCTION dbo.MyTableRowCount()
RETURNS int
AS
 BEGIN
    DECLARE @HowMany int

    SELECT @HowMany = count(*)
      from MyTable
    RETURN @HowMany
 END

Now add a check constraint using this function to the table

ALTER TABLE MyTable
 add constraint CK_MyTable__TwoRowsMax
  check (dbo.MyTableRowCount() < 3)

And test it:

INSERT MyTable (MyName) values ('Row one')
INSERT MyTable (MyName) values ('Row two')
INSERT MyTable (MyName) values ('Row three')
INSERT MyTable (MyName) values ('Row four')

A disadvantage is that every time you insert to the table, you have to run the function and perform a table scan... but so what, the table (with clustered index) occupies two pages max. The real disadvantage is that it looks kind of goofy... but everything looks goofy when you don't understand why it has to be that way.

(The trigger solution would work, but I like to avoid triggers whenever possible.)

Philip Kelley