How to set a conditional DEFAULT value to a column in oracle without using triggers? - oracle

How to set a conditional DEFAULT value to a column in oracle without using triggers?
I want to achieve following needs:
If "flag1"=1 then Default value to column Newfield must be "4".
If "flag1"=2 then Default value to column Newfield must be "5".

That's what triggers are for. Use them.

A column DEFAULT is not allowed to reference another column, so this is not possible.
You could perhaps just let the default remain as NULL, and then have a view to adjust it like:
create view mytable_view as
select flag1, nvl(newfield, case flag1 when 1 then 4
when 2 then 5
end) as newfield
from mytable;

If column Newfield does not need to be updateable, then you could simply implement it in a view, as Tony showed, or in 11g you could make it a virtual column.

If 'flag' is something session (or statement) level then SYS_CONTEXT may be a way through. Possibly a BEFORE STATEMENT trigger if the issue is avoiding a context switch for every row inserted

Related

How to keep a null date value from reverting back the default date after page refresh? (Oracle APEX)

I'm pretty new to APEX and programming as a whole, so bear with me. I have a table I created using dynamic PL/SQL and have a TO and FROM datepicker to set the range of rows to select. It is functioning great so far but I'm having a problem with the defaults for both datepickers. I've set the FROM datepicker to default to one year in the past and the TO datepicker is set to the current date. I've set them both using a SQL expression in the default field. Whenever you change the date and refresh, the table selects the correct rows. BUT if you want to remove the dates in both pickers so that you can see every row in the table, the null values are being reset to the default values after refreshing the page. I feel like there's probably a very simple way to fix this, but I'm at a loss. Any help with this would be greatly appreciated!
An item gets its value from session state; if it doesn't exist, then from source; if it doesn't exist (and the item is still NULL), then default value is used.
Therefore, what you did is just the opposite of what you want - if everything else is NULL, default value is used.
What to do? Don't set default value for the item - use it directly in report's WHERE clause. Something like this:
select whatever
from your_table
where some_conditions
and date_column between nvl(:P1_DATE_FROM, add_months(trunc(sysdate), -12))
and nvl(:P1_DATE_TO , trunc(sysdate))
So:
if P1_DATE_FROM and/or P1_DATE_TO are set, these values will be used
if they are NULL, they will be set to previous year and today
Of course, you'd remove both item's default values.

Oracle Apex: How to put a dynamic value in filter

is it possible to add a dynamic value on filter.
I'm trying to save a report with a filter using the current user:
A solution to this problem is to include the variable as a column in your query and then filter on that column.
Example:
Your select would be something like
SELECT
your_value1,
CASE WHEN created_by = :APP_USER THEN 1 ELSE 0 END AS is_current_user
FROM
your_table
If you then set a filter on is_current_user you'll only get the rows where created_by = :APP_USER.
Maybe it is possible; though, I don't know how. Whichever option I tried:
:APP_USER
&APP_USER.
v('APP_USER')
created a page item whose source is :APP_USER and base filter on that item
nothing worked. Apex applies single quotes around those expressions and - therefore - treats them as strings, e.g. ':APP_USER'.
However, what you might do in this particular case is to edit the query itself and add WHERE condition:
where blocked_by = :APP_USER
That would certainly work.

Concate string with Max Value for auto ID in Oracle

I want to Generate Auto ID concat String in Oracle Form 6i without using Sequence:
EXAMPLE
EMP1
EMP2
EMP3
EMP4
Whats error in this Trigger:
SELECT concat('EMP',TO_CHAR(NVL(MAX(EMP_ID),0) + 1))
INTO :EMP_Block.EMP_ID FROM EMPLOYEES WHERE EMP_ID LIKE 'EMP%';
Why do you not want to use a sequence? You need to think how your approach will deal with uncommited data from another session. Suppose you select a "max" value of "5", but before you commit, some other session also selects the max value -- they also will get "5" and try to use that. Now you've got two separate sessions working with a max value of 5 and no knowledge of the other. And if you try to do some sort of enquing (like SELECT FOR UPDATE or placing an explicit lock) you kill performance because all sessions needing this will have to line up behind each other.
The problem is that EMP_ID is varchar. Without filtering EMP from EMP4, you cannot add a number to it. You need to use something like below in concat. I am not able to test it but let me know if you still see any problem.
concat('EMP',to_char(replace(max(emp_id),'EMP','')+1))

Stored Procedure: Cursor is bad?

I read somewhere that 99% of time you don't need to use a cursor.
But I can't think of any other way beside using a cursor in this following situation.
Select t.flag
From Dual t;
Let's say this return 4 rows of either 'Y' or 'N'. I want the procedure to trigger something if it finds 'Y'. I usually declare a cursor and loop until %NOTFOUND. Please tell me if there is a better way.
Also, if you have any idea, when is the best time to use a cursor?
EDIT: Instead of inserting the flags, what if I want to do "If 'Y' then trigger something"?
Your case definitely falls into the 99%.
You can easily do the conditional insert using insert into ... select.... It's just a matter or making a select that returns the result that you want to insert.
If you want to insert one record for each 'Y' then use a query with where flag = 'Y'. If you only want to insert a single record depending on whether there are at least one 'Y', then you can add distinct to the query.
A cursor is useful when you make something more complicated. I for example use a cursor when need to insert or update records in one table, and also for each record insert or update one or more records into several other tables.
Something like this:
INSERT INTO TBL_FLAG (col)
SELECT ID FROM Dual where flag = 'Y'
You will usually see a performance gain when using set based instead of procedural operations because most modern DBMS are setup to perform set based operations. You can read more here.
well the example doesnt quite make sense..
but you can always write an insert as select statement instead of what i think you are describing
Cursors are best to use when an column value form one table will be used repeatedly in multiple queries on different tables.
Suppose the values of id_test column are fetched from MY_TEST_TBL using a cursor CUR_TEST. Now this id_test column is a foreign key in MY_TEST_TBL. If we want to use id_test to insert or update any rows in table A_TBL,B_TBL and C_TBL, then in this case it's best to use cursors instead of using complex queries.
Hope this might help to understand the purpose of cursors

oracle default value for a column

You know how we could use:
dateStamp DATE DEFAULT sysdate
to assign a default value to a column in table_x. What if I want to assign a default function? Can I do that?
The function will have some values from "table_params" to run some formula including a column named : "base" in table_x.
I could possibly write a cursor to loop through and run an update statement, but I was just curious if this is possible.
thanks in advance.
From Oracle documentation:
Restriction on Default Column Values
A DEFAULT expression cannot contain references to PL/SQL functions or to other columns, the
pseudocolumns CURRVAL, NEXTVAL, LEVEL, PRIOR, and ROWNUM, or date
constants that are not fully specified.
Either use a trigger (as was already mentioned) or run an UPDATE statement after your INSERT statement(s) (shouldn't be a problem if you keep your DML in PL/SQL).
You can write an INSERT trigger for the table that calls the function you want.

Resources