Setting a max record limit in access - ms-access

I have a table that holds several hundred records but I with a special property. I only want the user to be able to select that property 50 times though. How can I set a limit and return an error when the limit is reached?

To add to #Kevin Ross, the mechanism "at the DB level" to enforce the rule is a CHECK constraint e.g.
ALTER TABLE tblFoo ADD
CONSTRAINT tblFoo_bar__50_limit
CHECK (NOT EXISTS (
SELECT T1.Bar
FROM tblFoo AS T1
WHERE T1.Bar = 'Thing_you_only_want_50_of'
GROUP
BY T1.Bar
HAVING COUNT(*) > 50
));
CHECK constraints have existed in Jet from version 4.0 (circa Access 2000) and still exists in ACE (e.g. Access 2010).
You need to create the CHECK constraint using SQL DDL while in ANSI-92 Query Mode. No, you can't create CHECK constraints using DAO or the Access UI but that doesn't mean they don't exist ;)
If for some reason you have philosophical objection to SQL DDL, you could do similar things with an additional 'sequence' column, row-level Validation Rules and a compound UNIQUE constraint, all of which can be created using DAO or the Access UI and have been available in Jet for more years than I can remember.
Here's a rough sketch of what that alternative approach could look like:
ALTER TABLE tblFoo ADD
Bar__sequence INTEGER;
ALTER TABLE tblFoo ADD
CONSTRAINT tblFoo_bar_sequence__values
CHECK (
(
Bar <> 'Thing_you_only_want_50_of'
AND Bar__sequence IS NULL
)
OR (
Bar = 'Thing_you_only_want_50_of'
AND Bar__sequence BETWEEN 1 AND 50
)
);
ALTER TABLE tblFoo ADD
CONSTRAINT tblFoo_bar__50_limit
UNIQUE (Bar__sequence);
In this case, the results of the above three SQL DDL statements can be achieved using the Table Designer in the Access UI i.e. add the column, amend the Table Validation Rule and add a unique index.

select top 50 * from ...

I believe what renick was trying to say was before your save operation you could do something like
SELECT Count(*)
FROM tblFoo
WHERE Bar=’Thing_you_only_want_50_of’
You would then check to see if this figure is greater than equal to or greater than 50, if it is then return an error and not then let the user save.
As far as I know there is no way to restrict that at the DB level however access 2010 does have more controls such as triggers etc. Not sure what version you are using but if you are on 2010 it might be worth checking out

The question is very unclear. It's not clear if "select" means "display limited to 50 items" or "allow user to create data records that are limited to 50 items". I won't address the first interpretation, since it doesn't seem to me to be relevant.
Assuming certain other things, such as a Jet/ACE back end (the only way the question makes sense to me), how you accomplish this depends on your version of Access.
up to and including Access 2007: you'll have to apply the limitation in the user interface of your application. EDIT: As #onedaywhen has pointed out in his answer, it's possible to use DDL in SQL 92 mode to add a CHECK CONSTRAINT that operates on the current record based on groups of other records. I did not know this was possible when I posted.
in Access 2010, you can avail yourself of the new table-level data macros (which work like triggers) and limit the user to the 50 selections.
I'm not providing details for either of these, as there's simply not enough information provided to do so.

Related

MYSQL - Check from Select "itself" possible?

I just started with mysql and I don't know if the way to make that check is the correct or I am going in the wrong direction.
I have a varchar named user_num in a table. and I need to check that when I do INSERT, the value of user_num_list have to be between [1, n] being "n" the quantiti of Objects that have the same Group has new Object.
I'm not English speaking and I'm sure it's a bit hard to understand, and for me to express myself, so there is some code:
create table player(
group varchar(15),
user_num int(15),
CONSTRAINT ck_player_user CHECK( user_num > 0 AND user_num < SELECT count(*) FROM player WHERE player.group=group)
)ENGINE=InnoDB;
I don't know if i can "SELECT" inside a CHECK statement and also i dont know how to express "player.group=group" meaning that group(new INSERT player_group) have to be same has player.group
Thank you.
You are out of luck.
First of all, MySQL does not validate the CHECK constraints before version 8.0.16. If you are using a MySQL version older than this one, MySQL will record the CHECK constraint and will silently ignore it
.
Second, in order to enforce this contraint you would need to use a subquery in it, and MySQL does not allow subqueries as part of the CHECK constraint. See 13.1.20.7 CHECK Constraints where it literally says:
Subqueries are not permitted.
The problem with subqueries in the CHECK condition is that it's practically impossible to implement. Consider what happens when you delete a row in this table. The count for the corresponding group will decrease, which might violate a CHECK constraint for another row. The system would need to reevaluate the checks for every row. If you now have one million rows in the table, one million queries need to be executed every time you INSERT, DELETE or UPDATE a row. If you would also permit cross table statements, all checks in the database need to be reevaluated on any change of data.
In theorie it would be possible to generate a "reverse check". The system would need to determine, which operations can possibly violate a check. In your case that would be deleting a row or updating a group. The "reverse check" could be
NOT EXISTS (
SELECT *
FROM player p
WHERE p.group = OLD.group
AND p.user_num > (SELECT COUNT(*) from player p WHERE p.group = OLD.group)
)
I think you would agree, that it would be hard to implement a system, that is able to generate a reverse check like this. Queries can be much more complicated than yours. And for some queries there might not even exist a reverse check. If you look at how long it has taken to implement the CHECK constraint - I wouldn't expect any subqueries to be permitted in the next decade.
So I would say - Your options are:
Implement your checks in triggers
Implement your checks in application code
Change the requirements
I'd prefer the last one.

Database Architecture for logging

This is something that has bothered me for a long time and i still have been unable to find an answer.
I have a huge system with alot of different features. What is common for this system is of course that my users can
create, update, read & delete
different parts of my system.
For simple reasons lets say i have an application that has the following features:
Document administration
Video administration
User administration
Salery administration
(Please do note i took these at random just to prove a point that all of these would have their own separate tables and does not necessarily be connected).
Now i wish to create some sort of logging system. So that when ever someone either create,update or delete an entity it will be recorded.
Now as far as i can see i can do this two ways.
1.
Create a logging table for each of the 4 features that is in my system. However with this method i am required to create a logging table for each new feature i add to the system. i would also have to combine data from X number of tables if i wish to create a log which potentially could be a huge task!
2.
i could create something like the following:
However once again i would have to add a col for each new feature i will add.
So my question is what is the best way for creating logging database architecture
Or is there an easier way?
Instead of one target_xx for each feature, you could do it this way:
target_id | target_type
1 video
4 document
5 user
2 user
or even better. A table with target types and insert only the respective id's on target_type
Something like this:
if you want to capture for each table creation and update date, i would just use the default and the update event from mysql. You can define the fields like this for a table:
ALTER TABLE table
ADD COLUMN CreateDate Datetime DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN LastModifiedDate Datetime ON UPDATE CURRENT_TIMESTAMP;
You can add these 2 fields in all tables. If you want to use one central table for logging (which might be more difficult to manage, because you always need to create joins, maybe also worse performance), then I would work with triggers.

Creating a table with specific field parameters

I struggling to create a table that sets table parameters as well as creating the columns.
I am using MySQL server.
I require that the table meets the following criteria:
The table should be Called CUSTOMER with the columns CUST, LOCX, LOCY.
The column CUST will be a 1 up serial starting 1001 and will be the primary key.
LOCX and LOCY will contain X and Y Integers no greater than +-11, and will be foreign keys to other tables.
For info: I then intend to add my data to the table using the INSERT INTO function in a separate query that I already have.
Any direction on the construction of a query to create a table meeting the requirements above will be greatly appreciated
you can create a new table with a MySQL-GUI if you have problems with that.
These GUI-tools usually provide a New-Table button that also allows you to define your table without writing any code. They are often limited but should be more than sufficient for your needs. there are 1-month trial versions for paid versions and even completely free GUIs so you don't have to buy anything.
after that use the following code to retrieve "perfect" SQL from MySQL:
show create table your_schema_name.your_table_name
do that a few times and study the code. Soon you will be able to write create-table statements and include more complex column definitions on your own. It will also be easier to understand the MySQL Documentation which can be confusing and somehow intimidating with its completeness for beginners.

Mysql: allow query on an otherwise inaccesible column?

I have a table with a column that I want to prevent certain users from seeing. I understand that I should be able to do this using a view, i.e. have a view which excludes the particular column, and deny access to the table but allow access to the view (note, users do not need to be able to update the table/view).
I do however want to allow an equality query against the field. Such as:
SELECT * FROM some_table_or_view WHERE hidden_field = 'some_value';
To clarify:
it should not be possible to have the hidden_field values be returned in a general query
it should be possible to run a query with a constraint (preferably only an equality constraint) on the hidden_field value
Is this possible?
(EDIT: if there's a solution in a dbms other than Mysql, I'd be happy to hear about that, too).
You can create a stored procedure which would return all the fields you allowed it to return, and then you can pass the hidden_value (filtering criterion) as a parameter.
Forbid your database users accessing the table, but allow them to call stored procedures.
Then of course, you would have to create several stored procedures if you had several types of queries against the table. But at least it solves your problem with the rights.
No it is not. Giving a user a possibility to filter the results with the column hidden_value means that they have select rights, and that also means they can see the column, and therefore select it.
Here http://dev.mysql.com/doc/refman/5.1/en/grant.html
is a list of the rights you can grant or not grant to the users in mySQL.

mysql query and index how to do it

i need hand to index a large table ! and i have no idea about index mysql tables
this is the query when i order rows from table
SELECT "posts.* AS `posts` , user.nickname AS nickname
FROM `posts`
LEFT JOIN user AS user ON (user.userid = posts.userid )
WHERE
posts.userid= '" . intval($bbinfo['userid']) . "'
ORDER BY posts.timestamp DESC
LIMIT $start , $_limit
"
how i can use index to index this table after inser a new post to the table ? or by alert the table where and when i can use index table and how ? please help
Just create the index and define the way it works. Then you have nothing to do. If the SQL storage engine think your index should be used he will use it. And when you create or update data it will be maintained.
Now the hard part is the definition of the index.
You can see an index as an order, like when you use a phone book. Your phone book is ordered by city, then by lastName and then by first name. It's an oreder stored near the table that the engine can use to find the results faster than it would be if he needs to read the whole table data.
In a phone book there is only one index, so the data is ordered on, that index. In a database you can have several indexes, so they are stored near the table and contains pointers to the real data addresses.
Indexes are very important when you search data. You can easily find people names Smith in New York. It's harder to find all the Smith in all US cities (with a phone book).
In your query you have two instructions that may benefits from an index. You are filtering by user and then ordering by timestamp.
If you create an index by user and then timestamp the engine will already have the solution of your query by simply reading the index.
So I would create this one:
CREATE index posts_user_and_timestamp_idx ON posts(userid, timestamp DESC);
And this index could be reused for all queries where you are simply filtering by users (like the phone book. You can easily extract pages about one city). But not for queries where the only filter is the timestamp (you would need an index on the timestamp only, hard to extract all smith on all cities from the phone book).
So in fact the main problem of index is that they heavily depends on the queries you are usually using on the database. If you are never using the same sort of queries on a table then you will need a lot of different indexes. And an index is something which takes a looot of place. Most tables are using 3 or 4 more physical space for indexes than for the data.
You should find a MySQL admin tool that works for you since schema changes to your dbs, including adding indexes are a very common task.
I use MySQL Workbench to do most of the schema manipulation, including setting indexes on tables. This is a free admin app for mySQL dbs. If you dont have it, download it.
http://dev.mysql.com/downloads/workbench/5.1.html
Open your db in Workbench, right click on the table to add the index to and choose Alter Table... Then click on indexes at the bottom of the window, you should see something similar to:
You can also use PHPMyAdmin, which is a little more complex and a little harder to instal, IMHO.
I drilled down into my Program Files directory (Windows XP) to find the PHPMyAdmin executable file - which launched the app.
From PHPMyAdmin 3.2.1 - open your schema. Click on the table - which presents you with a GUI menu that will allow you to easily specify an index using the icon with the lighting bolt to the right of the column to be indexed.
You only need to add an index once. No need to worry about doing anything after every INSERT. Based-on what you have in your post, I would try something like this:
CREATE INDEX posts_userid_idx ON posts(userid);
If that doesn't seem to work very well, I would then advise you to check the MySQL Documentation on CREATE INDEX and see if any of the available options would apply to your situation.
Based-on your (revised) comment, you should also add a PRIMARY KEY on postid, as well.
ALTER TABLE posts ADD PRIMARY KEY (postid);
And yes, you should be able to run both of those commands in MySQL Workbench as you would any other query.