I'm using MS Access 2010 and I'm trying to create tables using SQL. I would like to put in some check constraints but I'm having some troubles:
CREATE TABLE Test (
tester Text CHECK (tester IN ('ABC', 'BCD', 'CDE'))
);
I'm getting a syntax error,
Any suggestions?
Thank you!
EDIT: Sorry if I wasn't clear. What I would like actually is to CHECK that tester is either "ABC", "BCD" or "CDE" those are the only values he can have.
EDIT2: I tried something else:
CREATE TABLE Test (
tester Text NOT NULL,
CONSTRAINT m_pk PRIMARY KEY(tester),
CONSTRAINT check_tester CHECK (DATALENGTH(tester) > 2)
);
and I also get a syntax error. Is there something I'm really not understanding with checking Text values? I can't possibly see where either of these is wrong.
Beginning with Jet 4, CHECK contraints are supported for Access DDL executed from ADO, but not from DAO.
You can execute a single DDL statement which creates the table Test with your constraint. You don't need to execute one statement to create the table and then another to add the constraint.
CREATE TABLE Test
(
tester TEXT(255),
CONSTRAINT ABC_or_BCD_or_CDE CHECK
(
tester IN ('ABC', 'BCD', 'CDE')
)
);
I formatted it that way to make it easier to examine the pieces. You could use this VBA to execute the statement:
strSql = "CREATE TABLE Test ( tester Text(255)," & vbCrLf & _
"CONSTRAINT ABC_or_BCD_or_CDE" & vbCrLf & _
"CHECK ( tester IN ('ABC', 'BCD', 'CDE')));"
Debug.Print strSql
CurrentProject.Connection.Execute strSql
Notes:
CurrentProject.Connection is an ADO object, so its .Execute method succeeds. The same statement with CurrentDb.Execute (a DAO method) would fail.
With ADO, declaring a field as TEXT without including a length (tester TEXT instead of tester TEXT(255)) will give you a memo field.
You will need to run against a connection:
ssql = "CREATE TABLE Test (tester Text)"
CurrentProject.Connection.Execute ssql
ssql = "ALTER TABLE test ADD CONSTRAINT " _
& "myrule CHECK (tester IN ('ABC', 'BCD', 'CDE'))"
CurrentProject.Connection.Execute ssql
Or
sSQL = "CREATE TABLE Test (tester Text, " _
& "CONSTRAINT myrule CHECK (tester IN ('ABC', 'BCD', 'CDE')))"
Note that the name, myrule in this case, must not already exists, even for a different table.
Some notes: Is it possible to create a check constraint in access and/or DAO?
My bad,
It appears MS Access does not allow CHECK Constraints except for primary and foreign keys. My teacher taught her course with Oracle until last year and apparently did not see that this could not be done in MS Access.
Related
I'm trying to add a column of the type NUMBER to my table using VBA. That is working for me. But i also want to set the default value for the column to 0, which is not working properly. I believe i need some help.
I do not want to alter a column, i want to add a column and at the same time set a default value.
The following code is working, it adds a column with nothing in it.
strSQL = "ALTER TABLE testTable ADD COLUMN testColumn NUMBER;"
dbs.Execute strSQL
But this is not working and gives an error.
strSQL = "ALTER TABLE testTable ADD COLUMN testColumn NUMBER DEFAULT 0;"
dbs.Execute strSQL
The error message i get is "Run-time error'3293': Syntax error in ALTER TABLE statement."
Default only works when it's used in DDL executed from an ADO connection. The syntax for this, which I have tested would be this:
CurrentProject.Connection.Execute "ALTER TABLE testTable ADD COLUMN testColumn NUMBER"
CurrentProject.Connection.Execute "ALTER TABLE testTable ALTER COLUMN testColumn SET DEFAULT 0"
Also, this only sets the default for the table for all new records, and does not modify existing records to 0. If that is also your intention, simply run an update query, like this one.
strSQL = "UPDATE testTable SET testTable.testColumn = 0;"
CurrentDb.Execute strSQL
I am new to this forum.
I have the following environment: an Access frontend client that is connected to a database on SQL Server (backend). I would like to use an Access form to enter data that is associated with a specific ID number (in database Table). Ideally the ID will automatically increment when an INSERT is made to the Table. The vba code (based on the SQL query) I wrote is the following:
Option Compare Database
Option Explicit
Private Sub List0_Click()
Dim HelloWORLD As String
Dim dbsCurrent As Database
Set dbsCurrent = CurrentDb
CurrentDb.Execute "INSERT INTO Table1 (TESTING_1, TESTING_2) VALUES (" & 9 & "," & HelloWORLD & ")"
End Sub
The code is compiling but it is not appending the Table1 like it is supposed to do. Please Help.
You can use sequences.
You can creates sequence MySequence1 and use it:
CurrentDb.Execute "INSERT INTO Table1 (TESTING_1, TESTING_2) VALUES (NEXT VALUE FOR MyDemoSequence," & HelloWORLD & ")"
Can you make the ID field an IDENTITY field within SQL Server? This will automatically increment whenever a new row is inserted. Example from Microsoft documentation:
CREATE TABLE new_employees
(
id_num int IDENTITY(1,1),
fname varchar (20),
minit char(1),
lname varchar(30)
)
The first number is the seed, and the second is the increment, so IDENTITY(1,1) means start at '1', and increase by '1' each time.
You can retrieve the ID that was created using SELECT SCOPE_IDENTITY(); following the insert if necessary.
I am fairly new to using VBA in MS Access and I am having trouble embedding SQL statements into VBA code. I have a database with almost 200 tables, and I would like to change the data type of one column (named lake) in each table to a "text" data type. I wrote the following code, but keep getting a syntax error for the ALTER TABLE statement.
Public Sub changeDataType()
Dim db As DAO.Database
Dim table As DAO.TableDef
Set db = CurrentDb
For Each table In db.TableDefs
DoCmd.RunSQL "ALTER TABLE" & table.Name & "ALTER COLUMN [lake] TEXT(100);"
Next
Set db = Nothing
End Sub
Can anyone tell me why I'm getting the syntax error?
Thanks,
Paul
this statement will not be correct:
DoCmd.RunSQL "ALTER TABLE" & table.Name & "ALTER COLUMN [lake] TEXT(100);"
if, for instance "table.Name" = "myTable", the resulting statement will look like this:
DoCmd.RunSQL "ALTER TABLEmyTableALTER COLUMN [lake] TEXT(100);"
try adding a space to separate the name, like this:
DoCmd.RunSQL "ALTER TABLE [" & table.Name & "] ALTER COLUMN [lake] TEXT(100);"
I don't know what am doing wrong but my constraint clause is not working
ALTER TABLE Employee
ADD CONSTRAINT CheckSalary CHECK (Salary > 0);
//entitesin my table
EMPID
EMPNAME
EMPDOB
EMPRGENDER
EMPCONTACT
EMPADDRESS
EMPSSN
EMPSTATUS
EMPLOYMENTID
EMPEMAIL
SALARY
any help would be appreciated
Check constraints are only supported in Access DDL when executed from ADO.
Here is an Immediate window example ...
strSql = "ALTER TABLE Employee " & vbCrLf & _
"ADD CONSTRAINT CheckSalary CHECK (Salary > 0);"
? strSql
ALTER TABLE Employee
ADD CONSTRAINT CheckSalary CHECK (Salary > 0);
' CurrentDb is a DAO object, so this will throw
' error 3289, "Syntax error in CONSTRAINT clause."
CurrentDb.Execute strSql
' CurrentProject.Connection is an ADO object,
' so this works ...
CurrentProject.Connection.Execute strSql
Note if you were trying to execute that statement from the query designer, it would also fail because the query designer uses DAO.
So you can have a CHECK constraint if you want one, but setting a Validation Rule for Salary might be easier. Either way, you may also want to prohibit Nulls from Salary.
MS-Acess does not support CHECK constaints, instead it uses what it calls "Validation Rules".
See MSDN for more info.
I am trying to create a check constraint on an access (jet?) table.
So, I open the .mdb file with access, go into queries->create query in design view,
type esc, then menu->view->query and finally type
create table X (
a number,
check (a > 20)
)
but access thinks that I have a "syntax error in field definition". However, I don't think so. Therefore my question: is it possible to create a check constraint with access. If so: how.
Additionally, I'd like to create the constraint with dao/vba, not on the GUI. Is that possible?
And lastly, on a slightly related note: how do you enter sql statements into access. I can't imagine that I have to use the queries->design view->query->view route in order to do that. I am used to Oracle's SQL*Plus, which I like very much, and I'd hope there's something similar for access as well.
Thanks for any input
Rene
Here are some notes.
You can create a Pass-Through query for Oracle (Select menu "Query" > "SQL Specific" > "Pass-Through")
Since Access 2003, you can select SQL Server Compatible Syntax (ANSI 92) (http://office.microsoft.com/en-us/access/HA010345621033.aspx)
A validation rule with VBA / DAO
''Reference: Microsoft DAO x.x Object Library
Dim tdf As TableDef
Dim db As Database
Set db = CurrentDb
Set tdf = db.TableDefs("Table1")
tdf.Fields("aDouble").ValidationRule = "<10"
tdf.Fields("aDouble").ValidationText = "Must be less than 10"
Constraints with ADO / VBA. See [Intermediate Microsoft Jet SQL for Access 2000](http://msdn.microsoft.com/en-us/library/aa140015(office.10).aspx)
''Reference: Microsoft ADO Ext. x.x for DDL and Security
Dim cn As ADODB.Connection 'For action queries
Dim rs As ADODB.Recordset 'For select queries
Dim s As String
Dim RecordsAffected As Long
Set cn = CurrentProject.Connection
''You can store sql in a table
s = DLookup("SQLText", "sysSQL", "ObjectName='q1'")
''Result: CREATE TABLE tblCreditLimit (LIMIT DOUBLE)
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
''You can run queries from VBA
s = "INSERT INTO tblCreditLimit VALUES (100)"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
s = "CREATE TABLE tblCustomers (CustomerID COUNTER, CustomerName Text(50))"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
s = "INSERT INTO tblCustomers VALUES (1, 'ABC Co')"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
s = "ALTER TABLE tblCustomers " _
& "ADD COLUMN CustomerLimit DOUBLE"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
''You can add contraints using ADO like so:
s = "ALTER TABLE tblCustomers " _
& "ADD CONSTRAINT LimitRule " _
& "CHECK (CustomerLimit <= (SELECT LIMIT " _
& "FROM tblCreditLimit))"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
s = "UPDATE tblCustomers " _
& "SET CustomerLimit = 200 " _
& "WHERE CustomerID = 1"
''Error occurs here
cn.Execute s, RecordsAffected
s = "UPDATE tblCustomers " _
& "SET CustomerLimit = 90 " _
& "WHERE CustomerID = 1"
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
''Clean up
''You cannot do this through the database window,
''because of the constraint.
s = "ALTER TABLE tblCustomers DROP CONSTRAINT LimitRule "
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
s = "DROP TABLE tblCustomers "
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
s = "DROP TABLE tblCreditLimit "
cn.Execute s, RecordsAffected
Debug.Print RecordsAffected
There is Validation rule on a column.
You can use VB for Access. no SQL*Plus here...
You can always use SQL Express as a data source - with all the benefits of real sql server and use access only as a front.
To do this in Access, you need to first open the interface into ANSI-92 Query Mode. I've tested your SQL DDL code: it works fine and creates a column of type FLOAT (Double).
Is is not possible to do this using DAO but you can use ADO. Long story short: CHECK constraints were introduced into the engine in the Jet 4.0 era when the Access Team were favouring ADO. With effect from Access2007, the Access Team are back to favouring DAO but have yet to plug the Jet 4.0 'holes' in DAO. So for the majority of Jet 4.0 -only functionality (compressible data types, fixed-length text data types, fast foreign keys, etc) you need to use ADO.
You can’t use standard ANSI in the query builder UNLESS you set the database as sql ansi compatible. If you do change this setting, then you CAN can use the sql in the query builder as you have. I would not recommend changing this setting for existing databases however.
If you do, you could type in:
CREATE TABLE z1
(id int IDENTITY , FirstName CHAR, LastName CHAR, SSN INTEGER ,
check (id < 20),
constraint Mypk primary key (id) )
In you don’t need to save the sql in the query builder, and just want to type in the sql, then simply whack ctrl-g to get the access command line prompt, and you can then type in:
currentproject.Connection.Execute "CREATE TABLE
z1(id int IDENTITY , FirstName CHAR, LastName CHAR, SSN INTEGER ,
check (id < 20),
constraint Mypk primary key (id) )"
The above would be typed on one line. So, you can use the command line prompt if you want..