I am stuck on creating constraint on SQL Server - sql

I am totally new to SQL Server management, I tried to add a constraint in a table.
The situation is that I created a column with only 'Y'or 'N' allowed to be valued.
So I tried to create a constraint in Management Studio by right clicking "Constraints" in the table.
However, I really have no idea about the syntax of creating a constraint. Finally, I tried to input the code into "Check Constraint Expression" window by referring the template from the Internet. The SQL Server always tell me "Error Validating constaint".
Can you guys just help me to write the first constraint for me? Because I really dont know how to start.
My requirement is:
I have a table called "Customer"
I created a column called "AllowRefund"
The column "AllowRefund" is only allowed to 'Y' or 'N'
Thanks.

I'd advise against what you are trying to do. There is a datatype (Bit) that is designed to represent values with two states. If you use this type you won't even need the constraint at all. SQL Server will enforce the value to be either one or zero with no additonal work required. You just have to design your app to treat 1 as yes, and 0 as No.
The approach you are attempting is just not a good idea and no good will come of it.

You can do this as follows:
ALTER TABLE Customer
ADD CONSTRAINT CK_Customer_AllowRefund
CHECK (AllowRefund in ('Y','N'))
However #JohnFx is correct - you'd be better off making this column a bit field.

I partly agree with JohnFix, but as knowing the correct syntax to define a check constraint might be useful for you in the future (as you apparently don't read manuals), here is the SQL to create such a constraint:
alter table customer
add constraint check_yes_no check (AllowRefund in ('Y', 'N'));
You probably want to also define the column as NOT NULL in order to make sure you always have a value for that.
(As I don't use "Management Studio" I cannot tell you where and how you have to enter that SQL).

Related

Interview: How to handle SQL NOT NULL constraint on the code end

I was recently asked this question in an interview an I'm having trouble formulating the question well enough to find an answer via search engine.
If my SQL database has a NOT NULL constraint placed on the "name" column, how would I be able to create that row, filling it with other data, without tripping the "name" NOT NULL constraint, assuming that you don't have the proper data to insert into the "name" field?
My off the cuff response was to insert an empty string into the "name" field, but I feel like that's too hacky. Does anyone know the proper response?
It's usually a best practice to insert a dummy value such as a -1 that you can easily replace later. A blank string can be more problematic in some cases. To do this you would either use a CASE WHEN statement, or ideally, an ISNULL() function which would look like this ISNULL([ColName], -1) ISNULL is probably the answer they were looking for. That would insert the data if you have it and then if it's null, it would insert a -1.
As Gordon commented, you could also use a DEFAULT value when creating the table. In my answer above, I am assuming you're working with a table that had already been created - meaning you couldn't do that without altering the table.
There are two ways that I can think of for not having to insert name if it is NULL. By far the simpler is to define a default value:
alter table t alter column name varchar(255) not null default '<no name>';
The alternative is to use a trigger, but that is much more cumbersome.
If I were asking a similar question, this is the answer that I would want.
Why bypass the constraint?
In my opinion either your data is wrong or the constraint.
If you bypass constraints, you can't assure some data quality inside the db.
So, i would say the scenario where a table could not be changed even if the constraint is wrong is a huge technical debt which should be solved instead.

Named CONSTRAINT benefits

I'm learning SQL and stumbled about CONSTRAINT. I can define them like this:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);
and like this:
CREATE TABLE products (
product_no integer,
name text,
price numeric CONSTRAINT positive_price CHECK (price > 0)
);
Why do I give them names? or Why I should or should not give them names?
As I can see in this example and most situations in my mind I can't reuse them. So what is the benefit of giving a name to a CONSTRAINT?
There are significant benefits of giving explicit names to your constraints. Just a few examples:
You can drop them by name.
If you use conventions when choosing the
name, then you can collect them
from meta tables and process them
programmatically.
It seems you are using PostgreSQL and there the difference isn't actually that big.
This is because a system generated name in PostgreSQL is actually somewhat meaningful. But "positive_price" is still easier to understand than "foo_price_check":
Think about which error message is better to understand:
new row for relation "foo" violates check constraint "foo_price_check"
or
new row for relation "foo" violates check constraint "positive_price"
In Oracle this is even worse because a system generated does not contain any hint on what was wrong:
ORA-02290: check constraint (SYS_C0024109) violated
vs.
ORA-02290: check constraint (POSITIVE_PRICE) violated
You don't specify RDBMS. the following points apply to SQL Server and I guess quite likely other RDBMSs too.
You need to know the name of the constraint to drop it, also the name of the constraint appears in constraint violation error messages so giving an explicit name can make these more meaningful (SQL Server will auto generate a name for the constraint that tells you nothing about the intent of the constraint).
Constraints as object in SQL, in the same manner that a PK, FK, Table or almost anything else is. If you give your constraint a name, you can easily drop it if required, say for example during some sort of bulk data import. If you don't give it a name, you can still drop it, however you have to find out the auto-genreated name that SQL will give it.
If your constraint is violated, having its name in the error message helps to debug it and present the error message to the user.
Named constraint have scenarios where they are really useful. Here are the ones I have encountered so far:
Schema compare tools
If you ever need to compare environment like DEV and UT to see differences, you may got "false possitives" on table level which is really annoying. The table definition is literally the same, but because autogenerated name is different, it is marked as change.
Yes, some tools allow to skip/ignore constraint name, but not all of them.
Deployment script from state-based migration tool
If you are using tools for state-based migration tool like MS SSDT, and then you manually review generated changes before applying them on PRODUCTION, you want your final script to be as short as possible.
Having a hundred of lines, that do drop constraint and create it with different name is "noise". Some constraint could be disabled from that tool, some are stil regenerated(DEFAULT/CHECK). Having explicit name and a good naming convention solves it for all.
EIBTI
Last, but not least. Being explicit simplifies things. If you have explicit name, you could refer that database object without searching system/metadata views.

Unique constraint vs pre checking

I use SQL Server 2008, and I have a table with a column of type varchar(X) which I want to have unique values.
What is the best way to achieve that? Should I use unique constraint and catch an exception, or should I pre-check before inserting a new value?
One issue, the application is used by many users so I guess that pre-checking might result in race condition, in case that two users will insert the same values.
Thanks
Race condition is an excellent point to be aware of.
Why not do both? - pre-check so you can give good feedback to the user, but definitely have the unique constraint as your ultimate safeguard.
Let the DB do the work for you. Create the unique constraint.
If it's a requirement that the values be unique --- then a constraint is the only guaranteed way to achieve that. reliable so-called pre-checking will require a level of locking that will make that part of your system essentially single user.
Use a constraint (UNIQUE or PRIMARY KEY). That way the key is enforced for every application. You could perform additional checks and handling in a store procedure if you need to - either before or after the insert.

Constrain a table to have only one row

What's the cleanest way to constrain a SQL table to allow it to have no more than one row?
This related question discusses why such a table might exist, but not how the constraint should be implemented.
So far I have only found hacks involving a unique key column that is constrained to have a specific value, e.g. ALWAYS_0 TINYINT NOT NULL PRIMARY KEY DEFAULT (0) CONSTRAINT CHECK_ALWAYS_0 CHECK (ALWAYS_0 = 0). I am guessing there is probably a cleaner way to do it.
The ideal solution would be portable SQL, but a solution specific to MS SQL Server or postgres would also be useful
The cleanest way (I think) would be an ON INSERT trigger that throws an exception (thus preventing the row from being inserted). This also gives the client app a chance to recover gracefully.
I just solved the same problem on SQL Server 2008 by creating a table with a computed column and putting the primary key on that column:
CREATE TABLE MyOneRowTable (
[id] AS (1) PERSISTED NOT NULL CONSTRAINT pk_MyOneRowTable PRIMARY KEY,
-- rest of the columns go here
);
Use Grant to remove permissions for anyone to insert into the table after adding the one row
Your dba will be able to insert but the dba should only be running schema changes which are checked so should not be a problem in practice

What is the purpose of constraint naming

What is the purpose of naming your constraints (unique, primary key, foreign key)?
Say I have a table which is using natural keys as a primary key:
CREATE TABLE Order
(
LoginName VARCHAR(50) NOT NULL,
ProductName VARCHAR(50) NOT NULL,
NumberOrdered INT NOT NULL,
OrderDateTime DATETIME NOT NULL,
PRIMARY KEY(LoginName, OrderDateTime)
);
What benefits (if any) does naming my PK bring?
Eg.
Replace:
PRIMARY KEY(LoginName, OrderDateTime)
With:
CONSTRAINT Order_PK PRIMARY KEY(LoginName, OrderDateTime)
Sorry if my data model is not the best, I'm new to this!
Here's some pretty basic reasons.
(1) If a query (insert, update, delete) violates a constraint, SQL will generate an error message that will contain the constraint name. If the constraint name is clear and descriptive, the error message will be easier to understand; if the constraint name is a random guid-based name, it's a lot less clear. Particulary for end-users, who will (ok, might) phone you up and ask what "FK__B__B_COL1__75435199" means.
(2) If a constraint needs to be modified in the future (yes, it happens), it's very hard to do if you don't know what it's named. (ALTER TABLE MyTable drop CONSTRAINT um...) And if you create more than one instance of the database "from scratch" and use system-generated default names, no two names will ever match.
(3) If the person who gets to support your code (aka a DBA) has to waste a lot of pointless time dealing with case (1) or case (2) at 3am on Sunday, they're quite probably in a position to identify where the code came from and be able to react accordingly.
To identify the constraint in the future (e.g. you want to drop it in the future), it should have a unique name. If you don't specify a name for it, the database engine will probably assign a weird name (e.g. containing random stuff to ensure uniqueness) for you.
It keeps the DBAs happy, so they let your schema definition into the production database.
When your code randomly violates some foreign key constraint, it sure as hell saves time on debugging to figure out which one it was. Naming them greatly simplifies debugging your inserts and your updates.
It helps someone to know quickly what constraints are doing without having to look at the actual constraint, as the name gives you all the info you need.
So, I know if it is a primary key, unique key or default key, as well as the table and possibly columns involved.
By correctly naming all constraints, You can quickly associate a particular constraint with our data model. This gives us two real advantages:
We can quickly identify and fix any errors.
We can reliably modify or drop constraints.
By naming the constraints you can differentiate violations of them. This is not only useful for admins and developers, but your program can also use the constraint names. This is much more robust than trying to parse the error message. By using constraint names your program can react differently depending on which constraint was violated.
Constraint names are also very useful to display appropriate error messages in the user’s language mentioning which field caused a constraint violation instead of just forwarding a cryptic error message from the database server to the user.
See my answer on how to do this with PostgreSQL and Java.
While the OP's example used a permanent table, just remember that named constraints on temp tables behave like named constraints on permanent tables (i.e. you can't have multiple sessions with the exact same code handling the temp table, without it generating an error because the constraints are named the same). Because named constraints must be unique, if you absolutely must name a constraint on a temp table try to do so with some sort of randomized GUID (like SELECT NEWID() ) on the end of it to ensure that it will uniquely-named across sessions.
Another good reason to name constraints is if you are using version control on your database schema. In this case, if you have to drop and re-create a constraint using the default database naming (in my case SQL Server) then you will see differences between your committed version and the working copy because it will have a newly generated name. Giving an explicit name to the constraint will avoid this being flagged as a change.