Access > SQL > Create Table . Constraints > Foreign Key - sql

The below statement is being used to create a table CAMPUS. I am getting the Error:
"Syntax error in CONSTRAINT clause"
"UPDATE" is highlighted signifying source of error.
By removing "ON UPDATE CASCADE ON DELETE NO ACTION" I am able to create the table with no issues.
What is the proper syntax or procedure? (the MS Access "Help" was of no help)
SQL Code:
CREATE TABLE CAMPUS(
CampusID Counter(1,5) NOT NULL,
UnivID Long NOT NULL,
CampusName Text(50) NOT NULL,
Address Text(50) NULL,
Zip Number NULL,
Phone Number NULL,
CONSTRAINT CampusPK PRIMARY KEY (CampusID,UnivID),
CONSTRAINT CampusFK FOREIGN KEY (UnivID)
REFERENCES UNIVERSITY(UnivID)
ON UPDATE CASCADE
ON DELETE NO ACTION
CONSTRAINT CampusAK1 UNIQUE (CampusName)
);

Access (ACE, Jet, whatever) has supported referential actions in its SQL DLL since Jet 4.0 (Access2000). However, they are only available in ANSI-92 Query Mode.
With effect from Access2003, the Access UI can be placed in ANSI-92 Query Mode, allowing the newer, richer SQL DDL to be executed from the SQL View of a Query. Note that ADO (OLE DB) always uses ANSI-92 Query Mode and DAO uses "traditional" ANSI-89 Query Mode (however IIRC DAO's object model has been enhanced to include all referential actions including the post-89 SET NULL action).
Therefore, I speculate that you are getting a syntax error because your are trying to execute ANSI-92 Query Mode SQL DDL while in ANSI-89 Query Mode.

It's been more then 10 years since I last used MS Access, but it seems you can only write either CASCADE or SET NULL after ON UPDATE and ON DELETE in a referential constraint.
So basically you have to omit this part
ON DELETE NO ACTION
Link http://www.sqlexamples.info/SQL/bsc_sqlddl1.htm

Related

SQL Learner -- MS Access 2013 ON UPDATE CASCADE and ON DELETE CASCADE

I'm new to SQL and try to get some handy knowledge from the book "SQL for Microsoft Access 2nd Edition" published in 2008.
In chapter 3, keyword ON UPDATE CASCADE ON DELETE CASCADE are introduced. I tried to run the statements with the keywords in MS Access 2013's SQL view. There is an error message saying
"Syntax error in CONSTRAINT clause."
The statements work perfectly without ON UPDATE CASCADE ON DELETE CASCADE.
The note in the book explain the keywords don't work on the version before SQL-92. I guess Access 2013 is way after SQL-92.
Can anyone explain to me why the keywords don't work?
below is the statements (ON UPDATE CASCADE ON DELETE CASCADE is at the end):
CREATE TABLE tblManufacturers
(
ManufacturerID INTEGER CONSTRAINT ManfID PRIMARY KEY,
ToyID INTEGER NOT NULL,
CompanyName CHAR (50) NOT NULL,
Address CHAR (50) NOT NULL,
City CHAR (20) NOT NULL,
State CHAR (2) NOT NULL,
PostalCode CHAR (5) NOT NULL,
AreaCode CHAR (3) NOT NULL,
PhoneNumber CHAR (8) NOT NULL UNIQUE,
CONSTRAINT ToyFk FOREIGN KEY (ToyID) REFERENCES tblToys (ToyID)
ON UPDATE CASCADE
ON DELETE CASCADE
);
Those keywords don't work because DAO doesn't support them. Built-in query builder also uses DAO. If you want to create table using CASCADE keywords, it can be done in VBA using ADO only:
CurrentProject.Connection.Execute strSQL
strSQL here contains CREATE TABLE statement
The ON UPDATE CASCADE and ON DELETE CASCADE statements are not supported by Access (see https://msdn.microsoft.com/en-us/library/office/ff836971.aspx).
Regarding the functionality, you should not have a need to use ON UPDATE CASCADE. This constraint means that if you do change a primary key in the master table, the changes propagate to every child table referencing the master table. Changing a primary key is considered a no-go in the SQL world. Is you really must change primary keys (because of some kind of disaster struck), this will be done with a script, lots of backup and extreme care. A primary key is this: a unique (ideally globally), immutable identifier of a row in a table.
The ON DELETE CASCADE means that if you remove a row in the master table, any rows referencing this key in child tables will also be deleted. While this sounds like a lazy shortcut, I would recommend against it and doing this within application logic (there might be a use case where you want to retain records or log them or do something with them instead of blindly erasing them from the database.

Microsoft Access - SQL command to add a constraint

I Am new in stackoverflow and whats worst is I am new to Microsoft Access. My homework
Assume the Part table has been created, but there are no integrity constraints. Create the necessary integrity constraint to ensure that the only allowable values for the Class field are AP, HW, and SG. Ensure that the PartNum field is the primary key and that the PartNum field in the OrderLine table is a foreign key that must match the primary key of the Part table.
So I know how to create this by using Microsoft Access by going to the Validation Rule and add validation for AP, HW, and SG. However, I need to also create the query to show how this is done.
My code:
ALTER TABLE Parts
ADD CONSTRAINT classRule
CHECK IN Class(AP, HW, SG)
;
My textbook has an example which is similar to what I just wrote above. When I run this I get a Constraint error. What am I doing wrong? Also, the foreign key and primary key have already been made so I just need to write the sql query to display my result. Any help is appreciated!
The CHECK clause exists but it's not a particularly good idea to use it because it can create issues in you application.
That being said, your constraint should work but there are a couple things:
You should avoid the use of the word Class as a field name. It's not a reserved word per se, but it's a VBA reserved word and while Access let you create that field, you may encounter strange problems elsewhere later.
As Brian said, you need to use single quotes for string literals in your CHECK
You can't create CONTRAINT with CHECK from the SQL Query Editor in Access, you'll get errors on the CHECK part every time you try.
Instead you need to execute the DDL SQL from VBA: just open the VBA (Alt+F11) then type the following in the Immediate Window (Ctrl-G if you don't see it), then press ENTER:
CurrentProject.Connection.Execute "ALTER TABLE Parts ADD CONSTRAINT ClassRule CHECK (Class IN ('AP', 'HW', 'SG'));"
If you don't get an error, then the constraint was properly executed, otherwise, double check that the syntax is correct, field names, parenthesis are properly balanced, and that the Part table is not open.
You probably want:
ALTER TABLE Parts
ADD CONSTRAINT classRule
CHECK (class in ('AP', 'HW', 'SG'));
There is a space between CONSTRAINT and the name
Put conditions within the () after the CHECK keyword
Put literals within single quotes, as this is what differentiates field names from values
Edit
Although the above is valid syntax, from what I'm reading you may not be able to add a check constraint in Access via writing out the SQL, at least not in the SQL view of query designer.
You can add a check constraint by going to Design View for the table of interest, then on the row representing the column of interest, type the following on the line for "Validation Rule":
in ('AP', 'HW', 'SG')
http://www.databaseskill.com/1942875/
"Note The check constraint statement can only be executed through the Jet OLE DB provider and ADO; it will return an error message if used though the Access SQL View user interface."
Above quote is from the URL I just provided.

SQL Database singleton for storing db version information

I need a very simple thing in SQL Database - I am using SQL Server and/or SQL Compact.
In c# I would write it like this
public class MyApp
{
public static int Version = 1;
}
e.g. I need to store configuration information in a form of singleton in SQL database.
Is there any better method than to create table with only one record?
Actually for my present needs it would be sufficient to have only one version number stored with database, but it must work both for SQL Server and SQL Compact database.
A table with one row is probably your best approach. Normally, you'd use a CHECK() constraint to guarantee you'll have only one row.
create table your_table_name (
one_row integer not null unique
default 1 check (one_row = 1),
version varchar(5) not null unique
);
insert into your_table_name values (1, '0.0.0');
If your platform doesn't support CHECK() constraints, but does support GRANT and REVOKE, you might be able to insert one row into the version table, then grant only update permissions. (Revoke delete and insert permissions.)
If your platform doesn't support CHECK() constraints, and doesn't support GRANT and REVOKE, but does support foreign key references, you might be able to replace the CHECK() constraint above with a foreign key reference to single-row table. This doesn't entirely solve the problem--you still have a single-row table that you can't adequately constrain.
If your dbms supports regular expressions in CHECK() constraints, you could add additional constraints to guarantee your version number follows a regular expression. You could also split the "version" into several columns of integers, each with its own constraints. But varchar(5) and varchar(7) seem to be the most common.

EF5 generates SQL Server CE constraints with dot in name

I am building a .NET disconnected client-server application that uses Entity Framework 5 (EF5) to generate a SQL Server CE 4.0 database from POCOs. The application allows the user to perform a bulk copy of data from the network SQL Server into the client's SQL Server CE database. This is very (VERY) slow, due to the constraints and indexes created by EF5. Temporarily dropping the constraints and indexes will reduce the 30-minute wait to 1 minute or less.
Before starting the bulk copy, the application executes queries to drop the constraints and indexes from the SQL Server CE tables. However, the commands fail, because EF5 created constraint names include the table schema name, dot, and table name. The dot in the constraint name is causing the drop command to fail, due to a parsing issue.
For example, POCO Customer creates table dbo.Customer with the primary key constraint PK_dbo.Customer_Id. The database performs as expected.
However, upon executing non-query:
ALTER TABLE Customer DROP CONSTRAINT PK_dbo.Customer;
SQL Server Compact ADO.NET Data Provider returns an error:
There was an error parsing the query.
[ Token line number = 1, Token line offset = 57, Token in error = . ]
Of course, using a secondary DataContext object that does not have foreign keys generate the database without the constraints, and then add them later works; but, that requires maintaining two DataContext objects and hopefully not forgetting to keep both updated. Therefore, I am looking for one of two solutions:
Compose the DROP statement in such a way that the . character is parsed
Prevent EF5 from using the . character in the constraint and index names
Thank you in advance for your help!
Wrap that bad boy in a []. It tells the parser that everything inside is the key name.
ALTER TABLE Customer DROP CONSTRAINT [PK_dbo.Customer];
Should run fine.
Personally I just wrap every identifier in brackets to avoid this exact issue. So I would write this query like this.
ALTER TABLE [Customer] DROP CONSTRAINT [PK_dbo.Customer];
I think it's more readable that way because you can instantly see identifiers.

H2 database Unsuccessful schema statement when add index and foreign key constraint

H2 does not appear to support the index/FK syntax generated by hibernate for the MySQL5 dialects when using ;MODE=MYSQL and hibernate with a dialect of org.hibernate.dialect.MySQL5Dialect.
My goal here is to have one set of SQL scripts and use hibernate for the ORM parts. Everything works fine in MySQL 5.5 but when I try to use H2 for things like unit tests and starting up a demo version of my app I get hundreds of failures from hibernate generated alter table statements as shown below. Unfortunately, I have not been able to find a way to get hibernate to change the way the statements are generated but that might be an option as well. I tried using org.hibernate.dialect.H2Dialect but that produces more severe errors so I don't think that will work.
alter table SAM_PUBLISHEDSECUREDIP_T
add index FK1EDEA25B9482C945 (ASSESSMENTID),
add constraint FK1EDEA25B9482C945 foreign key (ASSESSMENTID)
references SAM_PUBLISHEDASSESSMENT_T (ID)
Results in an error like this in H2:
org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "ALTER
TABLE SAM_PUBLISHEDSECUREDIP_T ADD INDEX FK1EDEA25B9482C945
(ASSESSMENTID),[*] ADD CONSTRAINT FK1EDEA25B9482C945 FOREIGN KEY
(ASSESSMENTID) REFERENCES SAM_PUBLISHEDASSESSMENT_T (ID) "; SQL
statement: alter table SAM_PUBLISHEDSECUREDIP_T add index
FK1EDEA25B9482C945 (ASSESSMENTID), add constraint FK1EDEA25B9482C945
foreign key (ASSESSMENTID) references SAM_PUBLISHEDASSESSMENT_T (ID)
[42000-172]
NOTE: I am open to writing and providing a patch for H2 but I could use some tips on where to look in that codebase.
H2 is not 100% compatible with MySQL, even when using the MySQL mode. It seems some of your SQL statements are not supported by H2.
Creating an index is not done using alter table (does MySQL really use this strange syntax? Every DBMS I know uses CREATE INDEX to create an index).
You have to split this up in two statements:
CREATE INDEX fk_assessment_id_index
on SAM_PUBLISHEDSECUREDIP_T (ASSESSMENTID);
alter table SAM_PUBLISHEDSECUREDIP_T
add constraint FK1EDEA25B9482C945 foreign key (ASSESSMENTID)
references SAM_PUBLISHEDASSESSMENT_T (ID);
Those two statements should also work in MySQL if I'm not mistaken.