Script SQL constraint for a number to fall within a Range? - sql

How to script a constraint on a field in a table, for an acceptable range of values is between 0 and 100?

ALTER TABLE Table
ADD CONSTRAINT CK_Table_Column_Range CHECK (
Column >= 0 AND Column <= 100 --Inclusive
)

Try:
ALTER TABLE myTableName
ADD CONSTRAINT myTableName_myColumnName_valZeroToOneHundred
CHECK (myColumnName BETWEEN 0 AND 100)
This check would be inclusive - here is some info about BETWEEN from MSDN:
BETWEEN (Transact SQL)

A check constraint like "fieldname BETWEEN 0 AND 100" should do it.

According to me, the right question isn't "how" but "why".
This 0-100 rule sounds to me like a business rule. Why should it be implemented on the server/database side? If an incorrect value is entered, who will get the error message?
If the user gets the error message, wouldn't it be easier to have the code giving him the message before the transaction reaches the server?
What about range modification? May the rule change? I guess yes: rules ALLWAYS change. Can the range be updated from 0-100 to 101-200? In this case, what about values already entered in the database?

Related

Make a constraint for SYSDATE minus a date of birth

I would love to know what I'm doing wrong ,
I would like to add a CHECK constraint in oracle to make sure a user is over 18
So I did
ALTER TABLE User
ADD CONSTRAINT check_age CHECK(TO_CHAR(SYSDATE, 'yyyy/mm/dd')- TO_CHAR(dateOfBirth, 'yyyy/mm/dd')> 18)
But Im receiving error
Cause: An attempt was made to use a date constant or system variable,
such as USER, in a check constraint that was not completely
specified in a CREATE TABLE or ALTER TABLE statement. For
example, a date was specified without the century.
*Action: Completely specify the date constant or system variable.
Setting the event 10149 allows constraints like "a1 > '10-MAY-96'",
which a bug permitted to be created before version 8.
Why it's wrong?
I still don't understand why I can't add it and I would kindly love if someone can explain it to me
Thanks
Starting in Oracle 11g, while you can't directly use sysdate in a constraint, you could get the same effect with a virtual column:
create function over_18 (
p_birth_date in User.dateOfBirth%type
) return varchar2 deterministic is
begin
return case when months_between(sysdate, p_birth_date) /12 > 18 then 'Y' else 'N' end;
end over_18;
/
alter table User add (over_18_ind as (cast(over_18(dateOfBirth) as varchar2(1))));
/
alter table User add constraint check_age check (over_18_ind = 'Y');
/
Based on an article here.
Even if Oracle allowed you to use sysdate in a constraint, your constraint wouldn't work anyway, since the formats you converted your dates to can't be implicitly cast back to numbers to subtract (I supplied an alternate age check).

Oracle Update table to set specific attribute value in semicolon separated values

I have a column where I have values like:
Email_Password+oi8hu907b;New_eMail+Y;Email_Username+iugbhijhb8
Now I want to update New_eMail attribute for all rows which has Y to N without affecting anything else.
Please advise.
i hate it but...
update table
set column = replace(column,'New_eMail+Y','New_eMail+N')
where column like '%New_eMail+Y%'
you don't need the WHERE clause but if you put a functional index on the table it may be quicker with it
Since it may be the only place in the string where '+Y;' occurs the following statement may do the trick:
update <your_table>
set <your_column> = replace(<your_column>,'+Y;','+N;')
where instr(<your_column>,'+Y;')>0
This solution differs from the others provided because it does not depend on the value of the email address.
My answer is a slight improvement over the answer from user davegreen100
Since they don't allow me to post it as a comment, I add it here.
update <<tablename>>
set <<columnname>> = replace(<<columnname>>,';New_eMail+Y;',';New_eMail+N;')
where <<columnname>> like '%;New_eMail+Y;%'

Is there a way to make a column's nullability depend on another column's nullability?

I have two columns (among others) in a database table: ExitDate and ExitReason. Our business logic requires that ExitReason be specified if ExitDate is specified. The ExitDate column needs to allow nulls since the value is not always known at the time of insert. Is there a way to make the ExitReason column allow nulls only if the ExitDate value is null? I could accomplish the effect by splitting these two columns into a separate 'exit dates' table and making them both non-nullable, but it would be nice if I wouldn't have to.
Ideas? Thanks!
Assuming you are on SQL Server or something similar, you can do this with a CHECK constraint on your table. (Unfortunately, MySQL parses but ignores CHECK constraints, so you'd have to use a trigger for that platform.)
If the table already exists:
ALTER TABLE ADD CONSTRAINT CK_ExitDateReason
CHECK (
(ExitDate IS NULL AND ExitReason IS NULL)
OR (ExitDate IS NOT NULL AND ExitReason IS NOT NULL)
);
If you are creating the table yourself:
CREATE TABLE dbo.Exit (
...
, CONSTRAINT CK_ExitDateReason CHECK ...
);
Using a check constraint is preferable to using a trigger because:
check constraints are more visible than triggers
the constraint is part of the table definition, as opposed to code that is run separately, so it's logically cleaner
I am willing to bet it is faster than a trigger too
I could accomplish the effect by splitting these two columns into a separate 'exit dates' table and making them both non-nullable, but it would be nice if I wouldn't have to.
That sounds like a very good solution. And if you are using MySQL then it's probably the best solution since CHECK constraints aren't supported.
MS Access offers another method to accomplish your goal. With the table in Design View, open the property sheet. In contrast to a Validation Rule for a field, the table rule can reference other fields in the table.
Add this as a single line for the table's Validation Rule property.
([ExitDate] IS NULL AND [ExitReason] IS NULL)
OR ([ExitDate] IS NOT NULL AND [ExitReason] IS NOT NULL)
It's similar to the CHECK CONSTRAINT #NickChammas supplied. I put square brackets around both ExitDate and ExitReason because without the brackets Access tends to interpret them as text literal values, so adds quotes like this ... which won't work:
("ExitDate" IS NULL AND "ExitReason" IS NULL)
OR ("ExitDate" IS NOT NULL AND "ExitReason" IS NOT NULL)
You may find this method more convenient if you want to include a user-friendly message as the table's Validation Text property to display when the Validation Rule is violated:
"Provide values for both ExitDate and ExitReason, or leave both blank."
Edit: The suggestion by #AndriyM works as a MS Access table Validation Rule:
([ExitDate] Is Null) = ([ExitReason] Is Null)
It is possible to use checks with MS Access, but only through ADO.
sSQL = "ALTER TABLE customer ADD CONSTRAINT CK_ExitDateReason " _
& "CHECK ((ExitDate IS NULL) = (ExitReason IS NULL))"
CurrentProject.Connection.Execute sSQL
The constraint can only be removed via ADO. However, you are free to add and delete columns (fields) without affecting the check.
It is also possible to add a check that references another table.
If you are using the table with a form, the error returned will be 3317. You can either accept the default message or supply your own like so:
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 3317 And IsNull(Me.ExitReason) Then
MsgBox "Please fill in a reason"
Response = acDataErrContinue
End If
End Sub
Further information: Intermediate Microsoft Jet SQL for Access 2000
You could enforce this with a trigger: if you're setting ExitDate to something other than null and ExitReason is being left null or is being set to null, then you throw an error.

Setting column constraint on a table (SQL Server)

I have a column that should contain one of values of 2 power n: 2,4,8,16,32 etc. I want to enforce that on table schema level - is there a way to specify such a column constraint?
Thanks!
Shamelessly stealing from this answer you could use bitwise operations to do this pretty efficiently.
ALTER TABLE tablename ADD CONSTRAINT
ckname CHECK (colName > 0 AND (colName & (colName - 1) =0))
In SQL Server:
ALTER TABLE [dbo].[PowerOfTwo]
WITH CHECK ADD CONSTRAINT [CK_PowerOfTwo]
CHECK ((log([Value])/log(2)=round(log([Value])/log(2), 0, 1)))
how about defining the column to be N. then all uses of that column would be 2^n by definition instead of constraint.
otherwise - you could put trigger logic in place to validate each value as it is entered or updated.
Assume your column name is N. Try something like
CHECK(LOG(N)/LOG(2) = TRUNC(LOG(N)/LOG(2)))
The intent is to verify that the binary logarithm of the value N is an integer, which would mean that N was a power of 2. Not sure if SQL Server supports the LOG and TRUNC functions - substitute in the correct names as needed.
Edit: as I re-read this I realized that rounding might cause a problem (I forgot the Second Commandment of Floating Point, which is: Thou Shalt Never Compare Floating Point Values For Equality!). OK, how about
CHECK(ABS(LOG(N)/LOG(2) - TRUNC(LOG(N)/LOG(2))) < 0.00001)
or substitute whatever error tolerance you'd like for the 0.00001.
Share and enjoy.
Create a column check:
CHECK (column_name IN (2, 4, 8, 16, 32, ..., 2147483648))

Duplicate value in a postgresql table

I'm trying to modify a table inside my PostgreSQL database, but it says there is duplicate! what is the best way to find a duplicate value inside a table? kinda a select query?
Try Like This
SELECT count(column_name), column_name
from table_name
group by column_name having count(column_name) > 1;
If you try to change a value in a column that is part of the PRIMARY KEY or has a UNIQUE constraint and get this error there, then you should be able to find the conflicting row by
SELECT *
FROM your_table
WHERE conflicting_column = conflicting_value;
If conflicting_value is a character type, put it in single quotes (').
EDIT: To find out which columns are affected by the constraint, check this post.
First of all, determine which fields in your table have to be unique. This may be something marked as a Primary Key, a unique index based on one or more fields or a check constraint, again based on one or more fields.
Once you've done that, look at what you're trying to insert and work out whether it busts any of the unique rules.
And yes, SELECT statements will help you determine what's wrong here. Use those to determine whether you are able to commit the row.