Write a psudo code with three input parameters...
Anupam ,USA, March 05, 2008 - 12:06 am UTC
declare
v_table_name Varchar2(31):='EMP'; -- Input table name
v_column_name varchar2(31):='ENAME'; -- Input column name
v_data_type varchar2(15):='varchar2(30)'; -- data type
v_exist number;
begin
select count(*) into v_exist from user_tab_cols where table_name=v_table_name and column_name=v_column_name;
if v_exist > 0 then
execute immediate 'Alter table '||v_column_name||' add ('||v_column_name ||' '||v_data_type||')';
end if;
end;
March 05, 2008 - 7:38 am UTC
this is so very very wrong.
and hah - umm - well, look at how wrong it is.
if v_exist > 0
if the column exists
please add it...
end if;
The code to add a column and deal with errors is trivial.
The ramifications of such code is too horrendous to deal with early in the morning, just ruins the day.
indicates zero degrees of control, no source code control - just whip it together, it'll probably work sometimes...
auto-magic DDL
Saager Mhatre, March 05, 2008 - 1:07 pm UTC
Whoa!!! Dynamic, programmatic DDL always scares me (even migrations in ActiveRecord scare me). I can't imagine why people would want to do stuff like this on a regular basis. It's a database, not a bunch of flat files!
Re-runable release code
John, March 05, 2008 - 4:47 pm UTC
I can see this can be usefull when running database releases into the database when it needs to be re-runable so that the release can be tested or additional objects added to the release. I have used a similar proc when releasing code and have not found a way of making a release proc rerunable without having these types of checks. Tom if you have a method/techneque to do this or you would do this a complely differnt way I would like to hear it
March 06, 2008 - 8:06 am UTC
for a failed upgrade - one would typically do a point in time recovery to before the upgrade in order to re-apply failed upgrade later. If your upgrade script (which frankly is a production *program*, a program, not 'just a script') is not coded to correct itself in the event of a failure, you need to restore the database back to a known point in time.
rais sheikh, March 06, 2008 - 2:36 am UTC
tom can it possible to alter table with the following he is using wrong table name.
execute immediate 'Alter table '||v_column_name||' add ('||v_column_name ||' '||v_data_type||')';
March 06, 2008 - 8:20 am UTC
He can debug his own code, I didn't even look at it once I saw the "if" statement - he has miles and miles to go before that code flies...
Re-running Scripts
A reader, March 06, 2008 - 12:34 pm UTC
Tom,
Features like 'drop table IF EXISTS' does not exists in Oracle, So, often we need to use dynamic SQL to make scripts re-executable for Test / Live deployment. As a part of enhancements and maintenance work, there are needs when we create scripts and then pass-it to support to deploy them to Test database and Live database. But, there are number of cases when the scripts might fail or should be killed in between because it is taking unexpected time.
eg. Support killed the session because the one of the script containts 'add column with default value'. It was OK on development because of small data on DEV as compare to others. So, they now re-run the deployment scripts and see lots of errors on the screen (which are not actually errors, it occurs because of re-execution.
To, avoid this, we use execute immediate like following :
SQL> host type add_col.sql
set feedback off
begin
execute immediate('alter table emp drop column new_column');
exception when others then
if sqlcode = -00904 then
null;
end if;
end;
/
set feedback on
alter table emp add new_column number(10);
SQL> @add_col.sql
Table altered.
SQL> @add_col.sql
Table altered.
SQL> @add_col.sql
Table altered.
What is your take on this?
March 07, 2008 - 5:01 pm UTC
My take is still - if someone killed a DDL script, part of an upgrade, you are doing a flashback database or a point in time recovery. You do upgrades during a maintenance window. If it doesn't work, you put it back the way it was.
But you did what I've been telling the above people to do: write code, handle errors.
and there is absolutely an "exists" check.
for x in ( select * from dual where NOT EXISTS (select null from user_tables where table_name = 'T')
loop
execute immediate...
end loop;
not too much different from
if not exists (select null from user_tables where table_name = 'T' )
then
execute....
end if;
which I suspect is what you were doing in t-sql.
When others then null...
ApexBine, March 07, 2008 - 9:56 am UTC
Dear "Reader",
what is the difference between
exception when others then
if sqlcode = -00904 then
null;
end if;
end;
and
exception when others then
null;
end;
?
March 10, 2008 - 10:23 am UTC
one of them is correct, proper, good, well written
and the other would be cause for dismissal from your job.
when others then null is a 'feature' of the language I would have removed if I could.
To : ApexBine from Frankfurt, Germany
A reader, March 07, 2008 - 10:31 am UTC
Thanks for pointing my mistake... sorry for that. the exception handling can be re-written in a "proper" way.
when others then null
A reader, March 07, 2008 - 10:46 am UTC
.. so I re-write the SQL
sql>host type add_col.sql
set serveroutput on
set feedback off
declare
invalid_column exception;
PRAGMA exception_init(invalid_column, -00904);
begin
execute immediate('alter table emp drop column new_column');
exception when invalid_column then
dbms_output.put_line('Adding column for first time');
end;
/
set feedback on
alter table emp add new_column number(10);
sql>
We actually can fast determime it with execute immediate
Mai Hoang Viet, August 22, 2018 - 4:03 am UTC
Please post this code on forum, it's my code which is fastest way to determine a field exist in a table
Create function exist(v_table in varchar2, v_col in varchar2)
Return integer is
Res integer:= 0;
Begin
Begin
Execute immediate 'select ' || v_col || ' from '|| v_table;
Res:=1;
Exception when other then null;
End;
Return (res);
End;