Modify a column to NULL - Oracle - oracle11g

I have a table named CUSTOMER, with few columns. One of them is Customer_ID.
Initially Customer_ID column WILL NOT accept NULL values.
I've made some changes from code level, so that Customer_ID column will accept NULL values by default.
Now my requirement is that, I need to again make this column to accept NULL values.
For this I've added executing the below query:
ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL
I'm getting the following error:
ORA-01451 error, the column already allows null entries so
therefore cannot be modified
This is because already I've made the Customer_ID column to accept NULL values.
Is there a way to check if the column will accept NULL values before executing the above query...??

You can use the column NULLABLE in USER_TAB_COLUMNS. This tells you whether the column allows nulls using a binary Y/N flag.
If you wanted to put this in a script you could do something like:
declare
l_null user_tab_columns.nullable%type;
begin
select nullable into l_null
from user_tab_columns
where table_name = 'CUSTOMER'
and column_name = 'CUSTOMER_ID';
if l_null = 'N' then
execute immediate 'ALTER TABLE Customer
MODIFY (Customer_ID nvarchar2(20) NULL)';
end if;
end;
It's best not to use dynamic SQL in order to alter tables. Do it manually and be sure to double check everything first.

Or you can just ignore the error:
declare
already_null exception;
pragma exception_init (already_null , -01451);
begin
execute immediate 'alter table <TABLE> modify(<COLUMN> null)';
exception when already_null then null;
end;
/

You might encounter this error when you have previously provided a DEFAULT ON NULL value for the NOT NULL column.
If this is the case, to make the column nullable, you must also reset its default value to NULL when you modify its nullability constraint.
eg:
DEFINE table_name = your_table_name_here
DEFINE column_name = your_column_name_here;
ALTER TABLE &table_name
MODIFY (
&column_name
DEFAULT NULL
NULL
);

I did something like this, it worked fine.
Try to execute query, if any error occurs, catch SQLException.
try {
stmt.execute("ALTER TABLE Customer MODIFY Customer_ID nvarchar2(20) NULL");
} catch (SQLException sqe) {
Logger("Column to be modified to NULL is already NULL : " + sqe);
}
Is this correct way of doing?

To modify the constraints of an existing table
for example... add not null constraint to a column.
Then follow the given steps:
1) Select the table in which you want to modify changes.
2) Click on Actions.. ---> select column ----> add.
3) Now give the column name, datatype, size, etc. and click ok.
4) You will see that the column is added to the table.
5) Now click on Edit button lying on the left side of Actions button.
6) Then you will get various table modifying options.
7) Select the column from the list.
8) Select the particular column in which you want to give not null.
9) Select Cannot be null from column properties.
10) That's it.

Related

In SQLite , How to SELECT a column only if it exists in the table

I am trying to write a query where the table will be generated dynamically for each job . And the columns will either exist or not based on input. In SQLite , i need to fetch the value of a column only if it exists otherwise null.
I tried with if & case statements using Pragma_table_info , but for negative scenario it is not working.
'''select
case when (select name from pragma_table_info('table_name') where name = col_name )is null
then error_message
else col_name'''
end
from table_name
This query is running if the mentioned col_name exists . But if not exists then it is throwing syntax error in else part.
Only in select query it should be done
Your code should work if the table's name, the column's name and the error message are properly quoted:
SELECT CASE
WHEN (SELECT name FROM pragma_table_info('table_name') WHERE name = 'col_name')
IS NULL THEN 'error_message'
ELSE 'col_name'
END
But you can do the same simpler with aggregation and COALESCE():
SELECT COALESCE(MAX(name), 'error_message')
FROM pragma_table_info('table_name')
WHERE name = 'col_name'
See the demo.

trigger with insert inside a select

I'm trying to create a trigger in which, only under certain circumstances, an insert is performed on another table. Consider the following code:
create table journal (
pk integer primary key autoincrement,
dsc varchar(10) not null
);
create table users (
name varchar(30) primary key not null
);
create trigger users_ai
after insert on users
begin
select
case
when 1 then
insert into journal(dsc) values('foo')
end;
end;
I get the following error when I run this code:
Error: near line 10: near "insert": syntax error
In production, the "1" in the when clause would be replaced by a more complex expression. I've also tried "true" and get the same results. I've also tried surrounding the insert statement in parens and get the same results. Any ideas how to accomplish what I want?
If you look at the syntax diagram for "CREATE TRIGGER", you'll see your attempt just doesn't match. You can, however, simply use the WHEN branch (without needing FOR EACH ROW):
create trigger users_ai
after insert on users
when 1 begin
insert into journal(dsc) values('foo');
end;
OK, figured it out. Instead of putting a conditional expression in the block of the trigger, I used a when clause. Here's the code that works:
create trigger users_ai
after insert on users when 1
begin
insert into journal(dsc) values('foo');
end;
If that when expression is changed to something that returns false (say 0) then the insert isn't done. In production, the expression will sometimes return true, sometimes false, which, of course, is the point of this code. Thanks everybody!
I think that you want a CASE statement, not a CASE expression.
create trigger users_ai after insert on users
begin
case
when ... then insert into journal(dsc) values('foo');
when ... then ...;
else ...;
end case;
end;
Note: if your trigger needs access to the data that was just inserted, its definition should the for each row option.
You can try to use an INSERT ... SELECT and your expression in the WHERE clause.
...
INSERT INTO journal
(dsc)
SELECT 'foo'
WHERE 1 = 1;
...
1 = 1 needs to be replaced by your Boolean expression.

Incorrect default value passed to the SQL Server database

I have set my column to int not null default 1... but whenever I save my record, it sets default value for that record to be 0.
I am not setting it anywhere. I don't know where I am making a mistake.
I have debugged my code , and when I am passing new entity object it is setting default value for not null to 0 .May be it is something with LINQ, But I don't know how to handle it.I don't want to explicitly assign value.
Thanks!
For sql-server, you can use SQL Server Profiler to catch all the scripts you run into the DB.
This may show you some details
Try running this query, replacing the 'myTable' and 'myColumn' values with your actual TABLE and COLUMN names, and see what's returned:
SELECT
OBJECT_NAME(C.object_id) AS [Table Name]
,C.Name AS [Column Name]
,DC.Name AS [Constraint Name]
,DC.Type_Desc AS [Constraint Type]
,DC.Definition AS [Default Value]
FROM sys.default_constraints DC
INNER JOIN sys.Columns C
ON DC.parent_column_id = C.column_id
AND DC.parent_object_id = C.object_id
WHERE OBJECT_NAME(DC.parent_object_id) = 'myTable'
AND COL_NAME(DC.parent_object_id,DC.parent_column_id) = 'myColumn'
;
Should return something like this:
[Table Name] [Column Name] [Constraint Name] [Constraint Type] [Default Value]
-------------------------------------------------------------------------------------------
myTable myColumn DF_myTable_myColumn DEFAULT_CONSTRAINT ('0')
If the [Default Value] returned is indeed (1), then it means that you have set the constraint properly and something else is at play here. It might be a trigger, or some other automated DML that you've forgotten/didn't know about, or something else entirely.
I am not the world's biggest fan of using a TRIGGER, but in a case like this, it could be handy. I find that one of the best uses for a TRIGGER is debugging little stuff like this - because it lets you see what values are being passed into a table without having to scroll through mountains of profiler data. You could try something like this (again, switching out the myTable and myColumn values with your actual table and column names):
CREATE TABLE Default_Check
(
Action_Time DATETIME NOT NULL DEFAULT GETDATE()
,Inserted_Value INT
);
CREATE TRIGGER Checking_Default ON myTable
AFTER INSERT, UPDATE
AS
BEGIN
INSERT INTO Default_Check (Inserted_Value)
SELECT I.myColumn
FROM Inserted I
;
END
;
This trigger would simply list the date/time of an update/insert done against your table, as well as the inserted value. After creating this, you could run a single INSERT statement, then check:
SELECT * FROM Default_Check;
If you see one row, only one action (insert/update) was done against the table. If you see two, something you don't expect is happening - you can check to see what. You will also see here when the 0 was inserted/updated.
When you're done, just make sure you DROP the trigger:
DROP TRIGGER Checking_Default;
You'll want to DROP the table, too, once it's become irrelevant:
DROP TABLE Default_Check;
If all of this still didn't help you, let me know.
In VB use
Property VariableName As Integer? = Nothing
And
In C# use
int? value = 0;
if (value == 0)
{
value = null;
}
Please check My Example:
create table emp ( ids int null, [DOJ] datetime NOT null)
ALTER TABLE [dbo].[Emp] ADD CONSTRAINT DF_Emp_DOJ DEFAULT (GETDATE()) FOR [DOJ]
1--Not working for Default Values
insert into emp
select '1',''
2 ---working for Default Values
insert into emp(ids) Values(13)
select * From emp

Add column to a table if not exist

I have a problem to add a new column to a SQLITE table if this column is not already exist.
I have try with this code but i don’t know why it wont execute:
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'mytable' AND COLUMN_NAME = 'mynewcolumn')
BEGIN
ALTER TABLE mytable ADD COLUMN mynewcolumn TEXT
END
I get an Exception error :
error: near "IF": syntax error
This is the solution i select :
1- I do PRAGMA table_info :
pragma table_info(MyTable)
This command gives all the informations about all the columns of the table. each row correspand to the information of a column.
This commande return an output table with 4 columns : cid, name, type, notnull, dft value, pk
2- I read all the rows from "PRAGMA table_info (MyTable)", and i compare the column "name" with the name of the column i want to check if exist.
3- If Column exist then i dont do anything
4- but if the column doen't exist then, here i add the column to my table using this commade :
ALTER TABLE MyTable ADD COLUMN NewColumn TEXT;
this is work for me, and do the job correctly.
To test whether a column exists, execute PRAGMA table_info and check if the column name appears in the result.

SQLite update trigger changes all rows in the table

Problem: a simplest possible update trigger writes a new value to all table rows instead of just the row being updated. Here is the table:
[names]
id INTEGER PRIMARY KEY
name TEXT
len INTEGER
Now I want to create triggers to update 'len' with the length of 'name'. This INSERT trigger seems to be doing the job corectly:
CREATE TRIGGER 'namelen' AFTER INSERT ON 'names'
BEGIN
UPDATE 'names' SET len = length(NEW.name) WHERE (id=NEW.id);
END;
Problems begin when I add a similar UPDATE trigger:
CREATE TRIGGER 'namelenupd' AFTER UPDATE ON 'names'
BEGIN
UPDATE 'names' SET len = length(NEW.name) WHERE (OLD.id=NEW.id);
END;
The update trigger writes the new length to all rows of the table, despite the WHERE clause. For example, if I say
UPDATE 'names' SET name='foo' where id=1;
then the value of 'len' becomes 3 for all rows of the table. I've looked at sqlite trigger examples and I can't see my error. What else must I do to make sure the trigger updates the 'len' column only in the row(s) that are actually updated?
Both OLD.xxx and NEW.xxx refer to the table row that caused the trigger to run.
The UPDATE statement inside the trigger runs independently; if you want to restrict it to one table row, you have to explicitly do this in its WHERE clause by filtering on that statement's table values, i.e., names.id or just id.
When the original UPDATE statement does not change the id column, the old and new id values are the same, and the expression OLD.id=NEW.id is true for all records in the table, as seen by the inner UPDATE statement.
The correct trigger looks like this:
CREATE TRIGGER "namelenupd"
AFTER UPDATE OF name ON "names"
BEGIN
UPDATE "names" SET len = length(NEW.name) WHERE id = NEW.id;
END;
Had the same issue, here's the syntax from my trigger
You would change "ALTER" to "CREATE" depending on what you already have (or not)
You have "id" as your primary key
Your dbo is "names"
Obviously, this will set the name value to "foo" (not really what you wanted). The key seems to be the last line, where you set inner join inserted on names.Id = inserted.Id.
USE [yourDBname]
ALTER TRIGGER [dbo].[yourTrigger]
ON [dbo].[names]
After INSERT, UPDATE
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Select id from inserted
begin
update [dbo].names
set [dbo].names.name = 'foo'
from dbo.names
inner join inserted
on names.id = inserted.id
END

Resources