So here I have a table:
What I want is to add a check constraint for the column SessionState in the above designer mode so it can work like a enum. But unfortunately, I can't find the place where I can do that.
I tried right also "right click -> script table as-> create table" but here I can't make a not null check:
Right-click on the SessionState and Select Check Constraints...
Then add your constraint.
Or Select dbo.Table > Constraints > New Constraints... > Expression (under General) and then enter your expression.
([SessionState]='Unknown' OR [SessionState]='Useless' OR [SessionState]='Useful')
Img Full Size: https://i.stack.imgur.com/AvgJX.png
Img Full Size: https://i.stack.imgur.com/HMsEK.png
Or simply enter this code
Alter Table TableName
ADD CONSTRAINT Constraint_name Check (SessionState IN ('Useful', 'Useless', 'Unknown'))
Updated
(Backup all data)
Run this query and get all null & unsupported values.
Then, change them (change SessionState values).
Select * from [Session] WHERE SessionState IS NULL OR SessionState NOT IN ('Useful', 'Useless', 'Unknown')
To change, use this queries...
UPDATE [Session] SET SessionState='Unknown' WHERE SessionState IS NULL
UPDATE [Session] SET SessionState='Unknown' WHERE SessionState NOT IN ('Useful', 'Useless', 'Unknown')
Do the first step again after changing the values.
Then run these queries...
Alter Table Session
ALTER COLUMN SessionState nchar(40) NOT NULL
Alter Table Session
ADD CONSTRAINT Constraint_name Check (SessionState IN ('Useful', 'Useless', 'Unknown'))
Demo: http://rextester.com/TGW65894
For additional information, refer this video: https://youtu.be/9Zj5ODhv0b0
Related
I want to add a nullable boolean column to an existing table with default value of null.
I have used this bit of script but it does not set the default value to null. it sets it to 0 instead.
ADD newColumnName BIT NULL
CONSTRAINT DF_tableName_newColumnName DEFAULT(null)
I just ran your example code snippet on my SQL Server 2008 R2 instance and then inserted a record. It initialized the column to null, as expected. The next step would be to post the alter statement and the insert statement that you used.
I used:
alter table tmp1 Add newColumnName bit null CONSTRAINT DF_tableName_newColumnName DEFAULT(null)
insert into tmp1(emp_id) values(9999)
select * from tmp1
After running the above, I used SQL Server Management Studio "Design" action to examine the properties of the new column. It showed that the "Default Value or Binding" was indeed (Null) as expected.
I am using Oracle Database (version is 9i) and I want to add a column to a current table in oracle database.
I want to add an integer column to keep track of invalid tries per user, so default value should be 5.
When I try to execute this query in Sql*Plus it gives an error table or view doesn't exist ( I have double checked table name is correct.
ALTER TABLE CustApps_user ADD VALID_TRIES INT DEFAULT 5 NOT NULL;
I guess the error you're getting is ORA-00942. This can mean a number of things, but basically it means the object does not exist in the current scope and context of what you're doing. So for instance it is the error thrown when we attempt to build a view on a table in another schema when we have been granted privileges through a role and not directly.
In your case it probably mean that the table is in another schema. You normally may be accessing it through a view or synonym. You can easily check this by querying the data dictionary:
select owner, object_type
from all_objects
where object_name = 'CUSTAPPS_USER'
alter table
table_name
add
(
column1_name column1_datatype column1_constraint,
column2_name column2_datatype column2_constraint,
column3_name column3_datatype column3_constraint
);
Here are some examples of Oracle "alter table" syntax to add data columns.
alter table
cust_table
add
cust_sex varchar2(1) NOT NULL;
Here is an example of Oracle "alter table" syntax to add multiple data columns.
ALTER TABLE
cust_table
ADD
(
cust_sex char(1) NOT NULL,
cust_credit_rating number
);
You have to add bracket in query:
ALTER TABLE CustApps_user ADD (VALID_TRIES INT DEFAULT 5 NOT NULL);
INT is legal, but it will be converted to NUMBER, so you can also use:
ALTER TABLE CustApps_user ADD (VALID_TRIES NUMBER(38,0) DEFAULT 5 NOT NULL);
or change (decrease) NUMBER precision.
Im trying to use Keys and Indexson a database and having difficulty. My requirements are as follows:
I want to be able to have empty string values in the Document No column as well as values
The constraint should check for Unique Values based on a DatabaseID and DocumentNo ( eg you can have the same document no for 2 different database ID's)
The table is similar to this (Extra columns removed for simplicity)
RecordID (bigint)
DocumentNo (varchar(12))
DatabaseID (bigint)
So the constraint should not allow inserting or updating a record if there is already a document no for the specified document no and database ID. A blank document no should be allowed to be entered as there are multiple rows with no document no.
Is this possible? if so please could you let me know how.
EDIT:
Here is the Query to Create the View and Constraint:
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW vNoDuplicateDoNos
WITH SCHEMABINDING
AS
SELECT [PODocumentNo],[SageDatabaseID]
FROM dbo.[Order]
WHERE [PODocumentNo] <> ''
GO
--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX CI_V1_ID
ON vNoDuplicateDoNos ([PODocumentNo],[SageDatabaseID]);
GO
I am not sure about using the GUI for this, but you should use a UNIQUE INDEX with a WHERE condition (assuming you are using SQL Server 2008 or newer):
http://msdn.microsoft.com/en-us/library/ms188783.aspx
CREATE UNIQUE NONCLUSTERED INDEX UIX_TableName_DocumentNo_DatabaseID
ON dbo.TableName
(DocumentNo, DatabaseID)
WHERE DocumentNo <> ''
ON IndexesFileGroup -- omit this line if you do not have a File Group for Indexes
Also, I was not able to find an option for the WHERE condition via the GUI in the "Manage Indexes and Keys" dialog.
To be fair, this was suggested by "Martin" in a comment on the Question. I just felt it needed to be explicitly stated with an example.
IF you are using a version of SQL Server prior to 2008 (when Filtered Indexes were added), you can use a Trigger as follows:
CREATE TRIGGER dbo.TableName_PreventDuplicatesTrigger
ON dbo.TableName
AFTER INSERT, UPDATE
AS
SET NOCOUNT ON
IF (EXISTS(
SELECT 1
FROM dbo.TableName tn
INNER JOIN INSERTED ins
ON ins.DocumentNo = tn.DocumentNo
AND ins.DatabaseID = tn.DatabaseID
WHERE ins.DocumentNo <> ''
))
BEGIN
ROLLBACK TRAN
RAISERROR('Duplicate DocumentNo/DatabaseID combination detected!', 16, 1)
END
GO
The above trigger will look for any existing records that match the two fields but only if the inserted or updated DocumentNo is not empty. If found, it calls ROLLBACK which will cancel the INSERT or UPDATE statement and the RAISERROR will display a message as to what caused the ROLLBACK.
Another option when using a version of SQL Server prior to 2008 is to create an Indexed View on DocumentNo and DatabaseID while filtering out empty DocumentNo records. This was suggested by "Martin" in the comments to this Answer.
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW dbo.UniqueDocumentAndDatabase
WITH SCHEMABINDING
AS
SELECT DocumentNo, DatabaseID
FROM dbo.TableName
WHERE DocumentNo <> ''
GO
CREATE UNIQUE CLUSTERED INDEX UIX_UniqueDocumentAndDatabase
ON dbo.UniqueDocumentAndDatabase
(DocumentNo, DatabaseID)
GO
Please note that the two SET options as well as the WITH SCHEMABINDING are required for Indexed Views. It is also required that SET ANSI_NULLS ON was used when creating the base table.
I would like to set the default value for every column in a number of tables equal to Null. I can view the default constraint under information_schema.columns.column_default. When I try to run
update information_schema.columns set column_default = Null where table_name = '[table]'
it throws "ERROR: cannot update a view HINT: You need an unconditional ON UPDATE DO INSTEAD rule."
What is the best way to go about this?
You need to run an ALTER TABLE statement for each column. Never ever try to do something like that by manipulating system tables (even if you find the correct one - INFORMATION_SCHEMA only contains view to the real system tables)
But you can generate all needed ALTER TABLE statements based on the data in the information_schema views:
SELECT 'ALTER TABLE '||table_name||' ALTER COLUMN '||column_name||' SET DEFAULT NULL;'
FROM information_schema.columns
WHERE table_name = 'foo';
Save the output as a SQL script and then run that script (don't forget to commit the changes)
I'm involved is a project to migrate a project from Oracle to MySQL. I Have a script that i'm running from the MySQL shell command, called CreateTables.sql that looks like this internally:
source table\DropForeignKeys.sql
source tables\Site.sql
source tables\Language.sql
source tables\Country.sql
source tables\Locale.sql
source tables\Tag.sql
mysql --user=root --password --database=junkdb -vv < CreateTables.sql
What I'm after is a way to make the execution for the first script DropForeignKeys.sql conditional based on if the db has any tables of not. Alternatively it would be nice if there were a way to drop constraint if not exists but such a construct does not exists in MySQL to my knowledge.
So my question is how do I make the dropping of foreign key constraints conditional at script level or constraint level, so that I can have a reliable re-playable script?
What I'm after is a way to make the execution for the first script DropForeignKeys.sql conditional based on if the db has any tables of not.
Conditional logic (IF/ELSE) is only supported in functions and stored procedures - you'd have to use something that resembles:
DELIMITER $$
DROP PROCEDURE IF EXISTS upgrade_database $$
CREATE PROCEDURE upgrade_database()
BEGIN
-- INSERT NEW RECORD IF PREEXISTING RECORD DOESNT EXIST
IF((SELECT COUNT(*) AS column_exists
FROM information_schema.columns
WHERE table_name = 'test'
AND column_name = 'test7') = 0) THEN
ALTER TABLE test ADD COLUMN `test7` int(10) NOT NULL;
UPDATE test SET test7 = test;
SELECT 'Altered!';
ELSE
SELECT 'Not altered!';
END IF;
END $$
DELIMITER ;
CALL upgrade_database();
Rather than reference INFORMATION_SCHEMA.COLUMNS, you could reference INFORMATION_SCHEMA.KEY_COLUMN_USAGE.
Depending on your needs:
ALTER TABLE [table name] DISABLE KEYS
ALTER TABLE [table name] ENABLE KEYS
...will disable and re-enable the keys attached to that table without needing to know each one. You can disable and enable keys on a database level using SET foreign_key_checks = 0; to disable, and SET foreign_key_checks = 1; to enable them.
It surprises me that MySQL doesn't seem to have a better way of dealing with this common scripting problem.
Oracle doesn't either, but constraints aren't really something you want to alter blindly without knowing details.
The reason I need the drop foreign keys script is because drop table yields an error when their are FK attachments. Will disabling FK checks allow for me to drop the tables?
Yes, dropping or disabling the constraints will allow you to drop the table but be aware - in order to re-enable the fk check you'll need the data in the parent to match the existing data in the child tables.