What I wanted is to sort records in a multi-record block before saving like this:
I already tried to change the order by of this item in here:
But it has no effect(I think).
I also want to know if I can automatically sort records in
WHEN-NEW-RECORD-INSTANCE in block level so that after entering the last record, it will be sorted.
We need to have a multi-record block ( block1 ) with Query Data Source Name property set to a table name which has a varchar2 type column namely str1,
and a Text Item (str1) with Database Item Property is "Yes" ( i.e. default ),
and lastly have a button with the following code inside of WHEN-BUTTON-PRESSED trigger of it :
declare
v_blk varchar2(25) := 'block1';
begin
commit_form;
go_block(v_blk);
execute_query;
end;
Provided we set ORDER BY Clause property set to ascii(str1) as in the picture below, we'll be able to get the desired output when the button pressed after letters are entered in the order of 'h','e','l','l','o'.
Related
I need to add values for a number field and if only it is null, then I have to add a number by using a sequence. I have created the code for this. But since this field is a unique field
I can't add duplicate values. For example as the first record if I entered number 1 and in the next record if I not pass a value for that field, it will automatically generate a value and if its equals to a old record number its showing an error like record already exists. Can someone help me to solve this.
PROCEDURE InsertValues(
newrec_ IN OUT myTable%ROWTYPE,
indrec_ IN OUT Indicator_Rec,
attr_ IN OUT VARCHAR2 )
IS
BEGIN
IF(newrec_.id IS null) then
newrec_.id := myTable_id.NEXTVAL;
Client_SYS.Add_To_Attr('ID', newrec_.id, attr_);
END IF;
super(newrec_, indrec_, attr_);
END InsertValues;
I want to display the item from different table, I am using POST-QUERY trigger
:
SELECT Stock_code
INTO :exchange.stockcode
FROM Exchange_Stock
WHERE Exchange_code = :exchange.Exchange_code;
it come up with FRM-40735 and ORA-01422
but it display some of the record (not all),
I have no idea what is wrong
Most probably the POST-QUERY trigger fires just after the fields of table-based block with multiple records are populated. Obviously Exchange_code values are not unique throughout the table data, whereas a SELECT .. INTO .. FROM ... clause only can bring one row record.
So, you can try to filter out the results so as to get single rows for each parameter fields combinations such as :exchange.Exchange_code & :exchange.code_order instead of only :exchange.Exchange_code field within the WHERE condition :
SELECT Stock_code
INTO :exchange.stockcode
FROM Exchange_Stock
WHERE Exchange_code = :exchange.Exchange_code
AND code_order = :exchange.code_order;
where important thing is to get single row from the query matching for each record in the data block. You can still add more condition to the query if this condition is not provided yet.
I have to create a trigger for a table with many columns and I want to now if is any possibility to avoid using the name of the column after :new and :old. Instead of specifically use the column name I want to use the element from collection with column names of target table (the table on which the trigger is set).
The line 25 is that with the binding error:
DBMS_OUTPUT.PUT_LINE('Updating customer id'||col_name(i)||to_char(:new.col_name(i)));
Bellow you can see my trigger:
CREATE OR REPLACE TRIGGER TEST_TRG BEFORE
INSERT OR
UPDATE ON ITEMS REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW DECLARE TYPE col_list IS TABLE OF VARCHAR2(60);
col_name col_list := col_list();
total INTEGER;
counter INTEGER :=0;
BEGIN
SELECT COUNT(*)
INTO total
FROM user_tab_columns
WHERE table_name = 'ITEMS';
FOR rec IN
(SELECT column_name FROM user_tab_columns WHERE table_name = 'ITEMS'
)
LOOP
col_name.extend;
counter :=counter+1;
col_name(counter) := rec.column_name;
dbms_output.put_line(col_name(counter));
END LOOP;
dbms_output.put_line(TO_CHAR(total));
FOR i IN 1 .. col_name.count
LOOP
IF UPDATING(col_name(i)) THEN
DBMS_OUTPUT.PUT_LINE('Updating customer id'||col_name(i)||to_char(:new.col_name(i)));
END IF;
END LOOP;
END;
Sincerely,
After digging more I have found that is not possible to dynamically reference the :new.column_name or :old.column_name values in a trigger. Due to this I will use my code only to INSERT (it does not have an old value :-() and I will do some code in java to generate UPDATE statements.
I must refine my previous answer based on what has been said by Justin Cave and also my findings. We can create a dynamic list of values triggered by INSERTING and UPDATING, based on referencing clause (old and new). For example I have created 2 collections of type nested table with varchars. One collection will contain all column tabs, as strings, that I will use for auditing and another collection will contains values for that columns with binding reference (ex. :new.). After INSERTING predicate I have created a index by collection (an associative array) of strings with ID taken from list of strings with column tab name and the value taken from the list of values for that columns referenced by new. Due to the index by collection you have a full working dynamic list at your disposal. Good luck :-)
I am creating an overloaded PLSQL stored procedure which allows to display the names of schools, their corresponding category (elementary, etc), and neighbourhood they belong to.
The names of schools is taken from table OTTAWASCHOOLS from the field NAME. The category is taken from the table OTTAWASCHOOLS from the field CATEGORY.
In addition, the user has the choice to input a particular neighbourhood to find the above information of the schools in that neighbourhood. The name of the neighbourhood is taken from the OTTAWANEIGHBOUR table from the field NAME.
However, if the user does NOT input a specific neighbourhood, the output will display the names ALL the schools in the OTTAWASCHOOLS table with their respective neighbourhoods and categories
(I have created only one procedure at the moment).
My code is as follows
SET SERVEROUTPUT ON;
SET VERIFY OFF
CREATE OR REPLACE PACKAGE schools_package
AS
PROCEDURE find_school
(neighbourhood_name IN OTTAWANEIGHBOUR.NAME%TYPE);
END schools_package;
/
CREATE OR REPLACE PACKAGE BODY schools_package
AS
PROCEDURE find_school
(neighbourhood_name IN OTTAWANEIGHBOUR.NAME%TYPE)
IS
school_category OTTAWASCHOOLS.CATEGORY%TYPE;
school_name OTTAWASCHOOLS.NAME%TYPE;
v_neighbourhood_name OTTAWANEIGHBOUR.NAME%TYPE;
CURSOR c_schools IS
SELECT NAME, CATEGORY
FROM eluliGDM.OTTAWASCHOOLS;
r_schools c_schools%ROWTYPE;
BEGIN
FOR r_schools IN c_schools
LOOP
SELECT c1.NAME, c2.NAME, c2.CATEGORY
INTO v_neighbourhood_name, school_name, school_category
FROM eluliGDM.OTTAWANEIGHBOUR c1, eluliGDM.OTTAWASCHOOLS c2
WHERE SDO_RELATE (c2.GEOMETRY, c1.GEOMETRY, 'MASK=INSIDE+COVEREDBY QUERYTYPE=JOIN') = 'TRUE'
AND c2.NAME=r_schools.NAME;
DBMS_OUTPUT.PUT_LINE ('NEIGHBOURHOOD ' || 'CATEGORY '|| 'SCHOOL NAME ');
DBMS_OUTPUT.PUT_LINE ('------------- ' || '-------- '|| '----------- ');
DBMS_OUTPUT.PUT_LINE (v_neighbourhood_name || school_category|| school_name);
END LOOP;
CLOSE c_schools;
END find_school;
END schools_package;
-----------TESTING STORED PROCEDURE---------------
Execute schools_package.find_school();
Execute schools_package.find_school('Mer Bleue');
But when I test the procedure, I get an error :01001. 00000 - "invalid cursor" then proceeds to show me ALL neighborhoods and their corresponding schools. What is wrong with my cursor?
Remove the CLOSE c_schools; statement. The Cursor For Loop already takes care of that. See Oracle Docs:
"The cursor FOR LOOP statement implicitly declares its loop index as a record variable of the row type that a specified cursor returns, and then opens a cursor. With each iteration, the cursor FOR LOOP statement fetches a row from the result set into the record. When there are no more rows to fetch, the cursor FOR LOOP statement closes the cursor."
According to your typing, OTTAWASCHOOLS contains both columns NAME and CATEGORY, so the cursor itself appears to be validly defined.
OTOH, does schema eluliGDM own both the tables and the package? If that is not the package owner, perhaps there are privilege issues? If the schema is the same, why specify the schema in the code? If not the same, consider the use of synonyms and removing the hard-coded schema from the code.
I'm not sure why you have an input parameter; you're not using it. So, I'm not surprised you're getting all the schools; the cursor has no predicate so it's the full table, and the SELECT inside the LOOP joins wherever the NAME column is the same in both tables. Without anything to limit based on input parameter, you have no filters at all beyond the join.
HTH
I have an Apex page with a select list item populated from a SQL query that should default to the product of the item passed through from another page, however it always selects the first item in the list.
We need to set it so it selects the current category however I can't see where this setting is. The version of APEX is 3.2.
Firstly, I suspect (correct me if I'm wrong) that your item is selecting the first item because the item is defined with Display Null Value set to No; internally, however, the item is probably NULL, but the list item cannot show it so it just shows the first list value. But I probably wouldn't change this setting.
To set the default value for a Select List item, set Default Value Type to PL/SQL Function Body, then enter your SQL query (that returns a single value) in the Default attribute for the item, with suitable PL/SQL around it, e.g.:
DECLARE
v_value VARCHAR2(<your data max length>);
BEGIN
SELECT <yourcolumn>
INTO v_value
FROM <yourquery>;
RETURN v_value;
END;