Create View in procedure PL/SQL - sql

i've had a look on the forum but at the moment theres no answer to this question. Basically i'm trying to create a view inside my procedure as its easier than a complicated select statement that doesnt seem to be working because its returning 'ORA-01422 exact fetch returns more than requested number of rows'.I've put the statement at the bottom for reference
However the view option doesnt seem to be working its return another error 'Encountered the symbol "CREATE" when expecting one of the following:'. Is there something i'm doing wrong?
Thanks for having a look.
procedure proRekt (par_id number) is
vardec farm.parcel.description%type;
vland farm.landuse.landuse_id%type;
v_luse farm.landuse.landuse%type;
varpl farm.parcel.parcel_id%type;
begin
create or replace view Door as
select a.parcel_id,a.description,b.landuse_id,c.landuse
from
farm.parcel a,
farm.parcel_landuse b,
farm.landuse c
where a.parcel_id = b.parcel_id
and b.landuse_id = c.landuse_id;
select parcel_id,description,landuse
into varpl,
vardec,
vland
from door
where parcel_id = parID;
**** faulty select statement
select a.parcel_id,c.description,a.landuse_id,b.landuse
into varpl,
vardec,
vland,
v_luse
from farm.parcel_landuse a,
farm.landuse b,
farm.parcel c
where c.parcel_id = parID
and a.landuse_id = b.landuse_id
and a.parcel_id = c.parcel_id;

Create the view in the SQL scope:
create or replace view Door as
select a.parcel_id,
a.description,
b.landuse_id,
c.landuse
from tithedb.parcel a
INNER JOIN tithedb.parcel_landuse b
ON ( a.parcel_id = b.parcel_id )
INNER JOIN tithedb.landuse c
ON ( b.landuse_id = c.landuse_id );
Use it in the PL/SQL scope of the procedure:
procedure proexempt (parID number)
is
vardescription tithedb.parcel.description%type;
varland tithedb.landuse.landuse_id%type;
varlanduse tithedb.landuse.landuse%type;
varparcel tithedb.parcel.parcel_id%type;
begin
select parcel_id,
description,
landuse
into varparcel,
vardescription,
varlanduse
from door
where parcel_id = parID;
-- ... more stuff
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; -- Handle error here.
WHEN TOO_MANY_ROWS THEN
NULL; -- Handle error here (or use "AND ROWNUM = 1" in your query).
END proexempt;
/

Related

GETTING ERROR-- ORA-00936:MISSING EXPRESSION for below query please help on this

SELECT CASE (SELECT Count(1)
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(
SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988')
)
WHEN 0 THEN
(
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27' )
WHEN 1 THEN
(
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
ELSE NULL
END
FROM dual;
You need to recreate your query and make sure to follow the flow of the clauses properly, please check the next two links to get a better understanding :
[ORA-00936: missing expression tips]
How do I address this ORA-00936 error?
Answer: The Oracle oerr utility notes this about the ORA-00936 error:
ORA-00936 missing expression
Cause: A required part of a clause or expression has been omitted. For example, a SELECT statement may have been entered without a list of columns or expressions or with an incomplete expression. This message is also issued in cases where a reserved word is misused, as in SELECT TABLE.
Action: Check the statement syntax and specify the missing component.
The ORA-00936 happens most frequently:
1 - When you forget list of the column names in your SELECT statement.
2. When you omit the FROM clause of the SQL statement.
ora-00936-missing-expression
I hope this can help you.
You cannot use a simple select query like this. You have to use a PL/SQL block like below -
DECLARE NUM_CNT NUMBER := 0;
BEGIN
SELECT Count(1)
INTO NUM_CNT
FROM wf_item_activity_statuses_v t
WHERE t.activity_label IN ('WAITING_DISB_REQ',
'LOG_DDE',
'LOG_SENDBACK_DDE')
AND t.item_key IN(SELECT r.i_item_key
FROM wf_t_item_xref r
WHERE r.sz_appl_uniqueid = '20400000988');
IF NUM_CNT = 0 THEN
delete
from t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_item_key = '648197'
AND p.i_document_srno = '27';
ELSIF NUM_CNT = 1 THEN
DELETE
FROM t_col_val_document_uploaded p
WHERE p.sz_application_no = '20400000988'
AND p.sz_collateral_id = 'PROP000000000PRO1701'
AND p.i_document_srno = '28' )
END IF;
END;

Creating a Procedure in Oracle to create View

I am trying to create a procedure in oracle, which upon calling from PL SQL block will create a view in database from which i will query data for a report. I am new to Oracle and need help with this code.
CREATE OR REPLACE PROCEDURE CREATE_VIEW
(
TO_DT IN Date
) AS
BEGIN
Create or Replace view BORR_DUR As
SELECT e."Deal_No", (Select "DeskName" From MM_S_DESK Where e."DeskCode" = MM_S_DESK."DeskCode") Facility, e."Remarks" Counterparty,
m."MaturityDate", m."PriRedem" Principal,
(select MAX("INTEREST_RATE") from MM_BOR_PLA_PAR d
WHERE e."Deal_No" = d."DEAL_NO" and "INTERESTINPUTDATE" <= to_dt)/100 yield, (m."MaturityDate" - To_date(to_dt,'dd/mm/yyyy')) Days_to_Mat,
Round(((m."MaturityDate" - To_date(to_dt,'dd/mm/yyyy'))/365)/ (1+((select MAX("INTEREST_RATE") from MM_BOR_PLA_PAR d
WHERE e."Deal_No" = d."DEAL_NO" and "INTERESTINPUTDATE" <= to_dt)/100)),4) MDURATION
FROM MM_T_BORROWING e, MM_T_BORROWING_PM_DETAIL m
Where e."DeskCode" in ('10','11','12','13') and e."Value_Date" <= to_dt and e."Maturity_Date" > to_dt and e."Status" not in ('C', 'D', 'Z', '0','X')
and e."Deal_No" = m."Deal_No" and "PriRedem" > '0' and m."MaturityDate" > to_dt;
END CREATE_VIEW;
On Compilation, i get PLS00103 error which says
encountered the symbol "Create" when expecting one of the
following....
Any help in solving this issue will be greatly appreciated.
When you want execute SQL statement which is dynamic you have to use EXECUTE IMMEDIATE statement
First , you don't need double quotes in fields name , after that you can try the query of the view and check if it runs without errors .
Put the create replace view... statement in an variable and in your procedure call :
BEGIN
EXECUTE IMMEDIATE view_string_variable ;
END;
/

Firedac multiparametric query with macro

I created the main query that returns values for a whole, with 2 secondary conditions to restrict choice to be taken in the side combo box.
Everything works with the set parameters. I wish I could turn off or turn on these conditions with side combo box, how should I proceed?
my code is in Delphi:
procedure TForm1.Button3Click(Sender: TObject);
begin
FDQuery3.Close;
FDquery3.Params[0].Value := Datetimepicker1.Date;
FDquery3.Params[1].Value := Datetimepicker2.Date;
FDQuery3.Params[2].Value := Combobox3.Items [Combobox3.Itemindex];
FDQuery3.Params[3].Value := Combobox5.Items [Combobox5.Itemindex];
FDQuery3.Open;
end;
SQL text is:
select
G.NUM_PROG,T.DATA,T.ORA,C.DESCRIZIONE,
(select DESKEY from ANAFORN where CODKEY=T.CODICE ) as Cliente,
O.NOMINATIVO, T.TERMINALE,T.INCASSO
from LG_RIGHE G
inner join LG_TESTA T on G.NUM_PROG =T.NUM_PROG
inner join OPERATORI O on T.OPERATORE = O.CODICE
inner join LG_CAUSA C on T.CAUSALE = C.CODICE
where T.DATA >= :data1
and T.DATA <= :data2
and T.INCASSO = :pagamento
and T.TERMINALE = :terminale
order by G.NUM_PROG
i want turn on/off only Params[2][ and Params[3] (name: pagamento, terminale)
1) The typical way to optionally ignore a condition is to add one more "toggle" parameter. Consider this Delphi code
Result := True; // or False. Actually - some previous part of formula
If Need_Check_Option_A then
Result := Result and ( Option_A > 20 );
If Need_Check_Option_B then
Result := Result and ( Option_B < 10 );
Got the idea?
But very long that is, is there a more concise way to write it ?
Result := .....some other parts....
and (Ignore_Option_A or (Option_A > 20 ))
and (Ignore_Option_B or (Option_A < 10 ))
and ....
Now let's re-phrase it from Delphi to SQL WHERE clause
WHERE (.......) and (......)
AND ( ( :Use_pagamento = 0 ) or ( T.INCASSO = :pagamento ) )
AND ( ( :Use_terminale = 0 ) or ( T.TERMINALE = :terminale ) )
Whether you set that USE_xxxx parameter to zero (similar to false) then the second check would be shortcut out, ignored.
And the calling code would be something like
FDquery3.ParamByName('data1').AsDate := Datetimepicker1.Date;
FDquery3.ParamByName('data2').AsDate := Datetimepicker2.Date;
FDQuery3.ParamByName('pagamento').AsString := Combobox3.Items [Combobox3.Itemindex];
FDQuery3.ParamByName('terminale').AsString := Combobox5.Items [Combobox5.Itemindex];
FDQuery3.ParamByName('Use_pagamento').AsSmallInt := Ord( CheckBox3.Checked );
FDQuery3.ParamByName('Use_terminale').AsSmallInt := Ord( CheckBox5.Checked );
Some more suggestions follow:
2) using names like ComboBox3 are bad. You would not understand what they mean, what was they intended to be for. Look at your SQL - you give names there! You do not make it like
SELECT FIELD1, FIELD2 FROM TABLE1 WHERE FIELD3 < :PARAM1
And you have to give reasonable names to your Delphi objects too!
That FDQuery3, that Checkbox3 that Combobox5 - rename them all, give them some meaningful names!
3) you have a nested select there as the Cliente column. Unless very special circumstances that is slow and inefficient - change it to JOIN too (maybe to LEFT JOIN, if sometimes there is no matching value)
select
G.NUM_PROG,T.DATA,T.ORA,C.DESCRIZIONE,
-- (select DESKEY from ANAFORN where CODKEY=T.CODICE ) as Cliente,
A.DESKEY as Cliente,
O.NOMINATIVO, T.TERMINALE,T.INCASSO
from LG_RIGHE G
inner join LG_TESTA T on G.NUM_PROG =T.NUM_PROG
inner join OPERATORI O on T.OPERATORE = O.CODICE
inner join LG_CAUSA C on T.CAUSALE = C.CODICE
/* left */ join ANAFORN A on A.CODKEY=T.CODICE
where T.DATA >= :data1
and T.DATA <= :data2
AND ( ( :Use_pagamento = 0 ) or ( T.INCASSO = :pagamento ) )
AND ( ( :Use_terminale = 0 ) or ( T.TERMINALE = :terminale ) )
order by G.NUM_PROG
4) Depending on the circumstances you may just want to alter the SQL text.
If the parameter would be ignored - then simply remove it!
This option is not universal, it has good and bad sides though.
But in your case it would rather do good or nothing - because you have human to re-open the query and human would not be able to do it more often than once per second.
Good: then the server gets your SQL text it prepares the QUERY PLAN. The internal program of how to fetch your data. And it does not know yet what your parameters would be, so it prepares the PLAN to always check those parameters. Even if you later would ignore them. Sometimes it might make server choose slow PLAN where it could choose faster one if it knew the parameter would be not used. Sometimes it would make no difference. Game of luck.
Bad: if you keep the SQL text the same, then you can PREPARE the query once and the server would not build different PLAN when you re-open the query with different parameters. But if you do change the SQL text, then server would have to parse that new query and PREPARE the PLAN again before it would give you data. Sometimes it would take considerable time when you open-close queries, say, 1000 times per second. OF course, when you use a human to set those checkboxes, comboboxes and then press buttons, he would not do it that frequently, so in this case that risk is moot.
So in your case you might do something like this instead of introducing those toggle-parameters:
var qt: TStrings; // SQL query text
.....
qt := FDQuery3.SQL;
qt.Clear; // changing SQL Text would auto-close the query
qt.Add('select G.NUM_PROG,T.DATA,T.ORA,C.DESCRIZIONE, ');
qt.Add(' A.DESKEY as Cliente, O.NOMINATIVO, T.TERMINALE,T.INCASSO ');
qt.Add('from LG_RIGHE G ');
qt.Add(' join LG_TESTA T on G.NUM_PROG = T.NUM_PROG ');
qt.Add(' left join ANAFORN A on A.CODKEY=T.CODICE');
qt.Add(' join OPERATORI O on T.OPERATORE = O.CODICE ');
qt.Add(' join LG_CAUSA C on T.CAUSALE = C.CODICE ');
qt.Add('where T.DATA >= :data1 and T.DATA <= :data2 ');
if CheckBox3.Checked then
qt.Add(' and T.INCASSO = :pagamento ');
if CheckBox5.Checked then
qt.Add(' and T.TERMINALE = :terminale ');
qt.Add('order by G.NUM_PROG');
FDquery3.ParamByName('data1').AsDate := Datetimepicker1.Date;
FDquery3.ParamByName('data2').AsDate := Datetimepicker2.Date;
if CheckBox3.Checked then
FDQuery3.ParamByName('pagamento').AsString := Combobox3.Items [Combobox3.Itemindex];
if CheckBox3.Checked then
FDQuery3.ParamByName('terminale').AsString := Combobox5.Items [Combobox5.Itemindex];
FDQuery3.Open;
In this option you do not introduce extra toggle-parameters, but instead you only add value-parameters when user checked to use them. If user unchecked them - then you do not include them into your SQL text and consequently you do not assign them any values (they would not be found anyway).
5) you may use BETWEEN - it may be easier to read.
...
where ( T.DATA BETWEEN :data1 AND :data2 )
and T.INCASSO = :pagamento
....

Searching in the source of a particular schema(PL/SQL)

In the source code if I want to find out something, say where a particular column is getting updated. I am using the below query to find where the column(BUCKET) of table(LEA_AGREEMENT_DTL)is getting updated.
select * from user_source where upper(text) like '%UPDATE%LEA_AGREEMENT_DTL%BUCKET%';
Now if the source in that paticular schem is written as below my query will tell me in which procedure the code is written :
Update Lea_agreement_dtl Set Dpd = No_Days_OverDuE, bucket=V_bucket
where ProposalID = T_ProposalID;
But if the code is written as below my query will not give any result :
Update Lea_agreement_dtl
Set Dpd = No_Days_OverDuE,
bucket=V_bucket
where ProposalID = T_ProposalID;
My question is how should I modify my query to search in the source code of a particular schema/user so that I get successful result in both the cases. Basically I want to find all the procedure's/objects where this column is getting updated in that particular schema.
As per my analysis if the whole query is written in one line then i am able to search it otherwise it doesn't work.
You can use this view.
CREATE OR REPLACE VIEW V_UPDATE_USER_SOURCE AS
SELECT TYPE,
NAME,
line,
LISTAGG(regexp_replace(text,'[[:space:]]',' '), ' ') WITHIN GROUP(ORDER BY norder) text
FROM (SELECT a.TYPE,
a.NAME,
a.line,
b.text,
b.line norder
FROM (SELECT line,
TYPE,
NAME,
text
FROM user_source
WHERE regexp_like(text, '[[:space:]]update[[:space:]]', 'i')) a,
user_source b
WHERE a.type = b.TYPE
AND a.name = b.name
AND b.line BETWEEN a.line AND (SELECT MIN(g.line)
FROM user_source g
WHERE regexp_like(g.TEXT, ';', 'i')
AND g.TYPE = a.TYPE
AND g.NAME = a.name
AND g.line >= a.line)
ORDER BY b.TYPE,
b.NAME,
b.line) c
GROUP BY TYPE,
NAME,
line
LISTAGG working on Oracle 11g or higher.
If you using previous version Oracle, you need this view
CREATE OR REPLACE VIEW V_UPDATE_USER_SOURCE AS
SELECT TYPE,
NAME,
line,
XMLAGG(XMLELEMENT(E, regexp_replace(text, '[[:space:]]', ' ') || ' ')).EXTRACT('//text()') text
FROM (SELECT a.TYPE,
a.NAME,
a.line,
b.text,
b.line norder
FROM (SELECT line,
TYPE,
NAME,
text
FROM user_source
WHERE regexp_like(text, '[[:space:]]update[[:space:]]', 'i')) a,
user_source b
WHERE a.type = b.TYPE
AND a.name = b.name
AND b.line BETWEEN a.line AND (SELECT MIN(g.line)
FROM user_source g
WHERE regexp_like(g.TEXT, ';', 'i')
AND g.TYPE = a.TYPE
AND g.NAME = a.name
AND g.line >= a.line)
ORDER BY b.TYPE,
b.NAME,
b.line)
GROUP BY TYPE,
NAME,
line;
It returns the data set, which contains all the update is in line with a number, in which the update started.
View can be used with regexp_like:
select * from V_UPDATE_USER_SOURCE t where regexp_like(text,'clients.*STATE','i')
Description:
clients - table.
STATE - column for update.
There are 3 main approaches to this problem:
Hack something together with string functions and regular expressions. This is the most common solution but is also full of holes. Those holes may not matter depending on why you're searching for the code. This is good enough for finding where to start coding but is probably not sufficient for proving to someone that the code is covered.
Tokenize the input and loop through the tokens looking for a pattern. A lexer can take care of some problems that are not easily handled by single regular expressions, like comments and the alternative quoting syntax. With a good understanding of Oracle syntax it's possible to build a highly-accurate solution. It would still miss extremely broken code (for example, it's possible to create code with UPDATE as a variable), dynamic SQL, and recursive references through synonyms and views.
Parse the input and walk an abstract syntax tree looking for a pattern. This would be a nice 100%-accurate solution. Unfortunately there are no high-quality PL/SQL parsers available in PL/SQL.
The solution below uses an open-source PL/SQL lexer I created to solve problems like this.
Sample Procedure
The string pattern, UPDATE-LEA_AGREEMENT_DTL-BUCKET, occurs three times below. But only the first UPDATE on line 4 really satisfies the conditions. (The third update may look weird in the Stackoverflow syntax highlighting, but in real PL/SQL that second quotation mark does not close the string.)
create or replace procedure search_test is
begin
--Real match.
Update Lea_agreement_dtl Set Dpd = No_Days_OverDuE,
bucket=V_bucket
where ProposalID = T_ProposalID;
--Exclude - ignore comments.
/*Update Lea_agreement_dtl Set Dpd = No_Days_OverDuE, bucket=V_bucket
where ProposalID = T_ProposalID;*/
--Exclude - watch out for alternative quoting syntax.
Update Lea_agreement_dtl Set Dpd = q'[No_Days_OverDuE', bucket=V_bucket ]'
where ProposalID = T_ProposalID;
end;
/
Anonymous Block to Find the Lines
--Find lines that update LEA_AGREEMENT_DTL.BUCKET.
--Does not search dynamic SQL and does not recurse through view or synonyms.
declare
v_tokens token_table;
v_update_line_number number;
v_has_update boolean := false;
v_has_table boolean := false;
v_has_column boolean := false;
begin
--Get source and tokenize it.
v_tokens := tokenizer.tokenize(dbms_metadata.get_ddl('PROCEDURE', 'SEARCH_TEST'));
--Loop through tokens and look for UPDATE/LEA_AGREEMENT_DTL/BUCKET between semicolons.
for i in 1 .. v_tokens.count loop
--Reset if a semicolon is found.
if v_tokens(i).value = ';' then
v_has_update := false;
v_has_table := false;
v_has_column := false;
--Look for relevant tokens, in order.
elsif upper(v_tokens(i).value) = 'UPDATE' then
v_update_line_number := v_tokens(i).line_number;
v_has_update := true;
elsif v_has_update and upper(v_tokens(i).value) = 'LEA_AGREEMENT_DTL' then
v_has_table := true;
elsif v_has_table and upper(v_tokens(i).value) = 'BUCKET' then
v_has_column := true;
end if;
--Success if all conditions are met.
if v_has_update and v_has_table and v_has_column then
--Subtract 1 because DBMS_METADATA put a blank line at the beginning.
dbms_output.put_line('Found on line '||to_char(v_update_line_number-1));
v_has_update := false;
v_has_table := false;
v_has_column := false;
end if;
end loop;
end;
/
Results
Found on line 4

ORA-06502 Error when creating a view

I am trying to create a view on my production server which will not compile -- however, the view already exists on our test server with no error.
I am getting this error:
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 27
However, whats very confusing is the fact that the error itself points to the view column definition. I'm not really sure how to approach this, again considering the fact that the same routine exists in our test environment with no issues.
Here is the view, with a warning that it is pretty large:
CREATE OR REPLACE FORCE VIEW V2RPT.VW_DM
(
ACCESSION_LABEL,
RECEIVED_DATE,
ACCESSIONING_TS,
TTR_TUMOR_TYPE_INFO,
SPEC_TYPE,
TUMOR_TYPE,
TUMOR_SUBTYPE,
PRIM_MET,
TUMOR_SITE,
EXTRACT_DATE,
CELL_SOURCE_STATUS,
MIXTURE_STATUS,
PLATE_STATUS,
CS_TERM_REASON,
ASSAYS_ORDERED,
ASSAYS_REPORTED,
AOF_GEN_TS,
AOF_TRANS_TS,
AOF_PROC_TS,
FIRST_TERM_REPORT_TRANS_TS,
COMPLETE_WITHOUT_REPORT_TS,
RELATED_CELL_SOURCE,
FACILITY,
RELEASED_DATE,
IHC_DATE, --Error is happening here
T,
M,
N,
TUMOR_STAGE,
TUMOR_GRADE,
TUMOR_DIFF,
I_COUNT,
R_COUNT,
N_COUNT,
MIXTURE_ID,
PLATED_TS,
TREATED_TS,
FIXED_STAINED_TS,
SCANNED_TS,
COUNTED_TS,
ASSAYS_PLATED,
CELL_YIELD,
EXPLANTED_BY,
REPLATE,
AVG_CONTROL,
CELL_SUSPENSION_CREATOR,
CELL_SUSPENSION_TS,
IN_CULTURE_TS,
ENOUGH_CELLS_TS,
MIXTURE_ON_PLATE_TS,
TERM_MIXTURE_TS,
MIXTURE_TERM_REASON,
COMPLETE_TS,
VALIDATED_TS,
SALES_REP,
DRUG_SEL_TS,
DRUGS_ON_PANEL,
FINAL_PATH_COMP_TS,
PHYSICIAN,
CELL_SOURCE_TYPE_ID,
LXWXH,
PCT_SOLID,
PCT_FATTY,
PCT_FIBROUS,
PCT_BLOODY,
PCT_NECROTIC,
PCT_OTHER,
LESS_THAN_100MG,
OVERSIZED,
UNDERSIZED,
FLASK_TYPE,
VITROGEN_COATED,
AB_WASH_REQUIRED,
DIM_X,
DIM_Y,
DIM_Z,
MANUAL_PLATE,
LAB_SITE_ABBR,
REGION_TERRITORY,
MEDIUM_TYPE,
TUMOR_TYPE_FP,
TUMOR_TYPE_PP,
CR_ENTRY_CREATOR,
CR_ENTRY_CREATED_TS,
ICC_ENTRY_CREATOR,
ICC_ENTRY_CREATED_TS,
AOF_TRANS_CREATOR
)
AS
SELECT cs.accession_label,
cs.received_date,
cs.created_timestamp AS ACCESSIONING_TS,
PW.TTR_TUMOR_TYPE_INFO,
VW_CS.SPEC_TYPE,
VW_CS.TUMOR_TYPE,
VW_CS.TUMOR_SUBTYPE,
VW_CS.PRIM_MET,
VW_CS.TUMOR_SITE,
VW_CS.EXTRACT_DATE,
VW_CS.CELL_SOURCE_STATUS,
VW_CS.MIXTURE_STATUS,
VW_CS.PLATE_STATUS,
VW_CS.CS_TERM_REASON,
VW_CS.ASSAYS_ORDERED,
VW_CS.ASSAYS_REPORTED,
VW_CS.AOF_GEN_TS,
VW_CS.AOF_TRANS_TS,
VW_CS.AOF_PROC_TS,
VW_CS.FIRST_TERM_REPORT_TRANS_TS,
VW_CS.COMPLETE_WITHOUT_REPORT_TS,
VW_CS.RELATED_CELL_SOURCE,
VW_CS.VW_CS.FACILITY,
VW_CS.RELEASED_DATE,
VW_CS.IHC_DATE,
VW_CS.T,
VW_CS.M,
VW_CS.N,
VW_CS.TUMOR_STAGE,
VW_CS.TUMOR_GRADE,
VW_CS.TUMOR_DIFF,
VW_CS.I_COUNT,
VW_CS.R_COUNT,
VW_CS.N_COUNT,
MIXTURE.TERM_MC_MIXTURE_ID AS Mixture_ID,
MIXTURE.PLATED_TS,
MIXTURE.TREATED_TS,
MIXTURE.FIXED_STAINED_TS,
MIXTURE.SCANNED_TS,
MIXTURE.COUNTED_TS,
Mixture.Assays_Plated,
Mixture.CELL_YIELD,
Mixture.EXPLANTED_BY,
NVL (Mixture.REPLATE, 0) Replate,
Mixture.AVG_CONTROL,
Mixture.CELL_SUSPENSION_CREATOR,
Mixture.CELL_SUSPENSION_TS,
Mixture.IN_CULTURE_TS,
Mixture.ENOUGH_CELLS_TS,
Mixture.MIXTURE_ON_PLATE_TS,
Mixture.TERM_MIXTURE_TS,
Mixture.MIXTURE_TERM_REASON,
Mixture.COMPLETE_TS,
Mixture.VALIDATED_TS,
PW.SALES_REP,
PW.DRUG_SEL_TS,
PW.DRUGS_ON_PANEL,
PW.FINAL_PATH_COMP_TS,
PW.PHYSICIAN,
CS.CELL_SOURCE_TYPE_ID,
VW_CS.LXWXH,
VW_CS.PCT_SOLID,
VW_CS.PCT_FATTY,
VW_CS.PCT_FIBROUS,
VW_CS.PCT_BLOODY,
VW_CS.PCT_NECROTIC,
VW_CS.PCT_OTHER,
VW_CS.LESS_THAN_100MG,
VW_CS.OVERSIZED,
VW_CS.UNDERSIZED,
MIXTURE.FLASK_TYPE,
MIXTURE.VITROGEN_COATED,
VW_CS.AB_WASH_REQUIRED,
VW_CS.DIM_X,
VW_CS.DIM_Y,
VW_CS.DIM_Z,
MIXTURE.MANUAL_PLATE,
CS.LAB_SITE_ABBR,
V2.CRM_ACCOUNT_ADDRESS.STATE REGION_TERRITORY,
MIXTURE.MEDIUM_TYPE,
VW_CS.TUMOR_TYPE_FP,
VW_CS.TUMOR_TYPE_PP,
MIXTURE.CR_ENTRY_CREATOR,
MIXTURE.CR_ENTRY_CREATED_TS,
MIXTURE.ICC_ENTRY_CREATOR,
MIXTURE.ICC_ENTRY_CREATED_TS,
VW_CS.AOF_TRANS_CREATOR
FROM V2.cell_Source cs
INNER JOIN V2RPT.TEMP_DM_CS_TYPE
ON CS.CELL_SOURCE_TYPE_ID =
V2RPT.TEMP_DM_CS_TYPE.CELL_SOURCE_TYPE_ID
LEFT OUTER JOIN V2RPT.TEMP_DM_CS VW_CS
ON CS.CELL_SOURCE_ID = VW_CS.CELL_SOURCE_ID
LEFT OUTER JOIN V2RPT.TEMP_DM_MIXTURE MIXTURE
ON MIXTURE.cell_Source_id = CS.CELL_SOURCE_ID
LEFT OUTER JOIN V2RPT.VW_DM_PW PW
ON PW.cell_source_ID = cs.cell_source_ID
LEFT OUTER JOIN V2.CRM_ACCOUNT
ON V2.CRM_ACCOUNT.CRM_ACCOUNT_ID = CS.CRM_ACCOUNT_ID
LEFT OUTER JOIN ( SELECT MAX (
V2.CRM_ACCOUNT_ADDRESS.
CRM_ACCOUNT_ADDRESS_ID)
Max_AA_ID,
V2.CRM_ACCOUNT_ADDRESS.CRM_ACCOUNT_ID
FROM V2.CRM_ACCOUNT_ADDRESS
GROUP BY V2.CRM_ACCOUNT_ADDRESS.CRM_ACCOUNT_ID) Max_AA
ON Max_AA.CRM_ACCOUNT_ID = V2.CRM_ACCOUNT.CRM_ACCOUNT_ID
LEFT OUTER JOIN V2.CRM_ACCOUNT_ADDRESS
ON V2.CRM_ACCOUNT_ADDRESS.CRM_ACCOUNT_ADDRESS_ID =
max_aa.Max_AA_ID;
I'm a tad lost -- any ideas? I mean, there aren't even any variables to assign values to, so I don't know how the 'string buffer can be too small'
Appreciate the help.
Have you got any triggers on the database that are firing when the view is created? To me, the line error occurred at recursive SQL level 1 suggests an error in a trigger. Perhaps there's some kind of auditing trigger that is auditing objects being created and the view you created was too large for this trigger to cope with?
Here's a demonstration of how to generate an error similar to yours when creating a view. First, we create a trigger that causes a character string buffer too small error when you attempt to create something. Chances are that the trigger that appears to be causing your problem isn't quite this stupid:
SQL> create or replace trigger error_trigger
2 before create on database
3 declare
4 a varchar(1);
5 begin
6 a := '12';
7 end;
8 /
Trigger created.
Now, when we attempt to create a view, we get an error:
SQL> create view some_view as select * from dual;
create view some_view as select * from dual
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4
This view has nothing to do with PL/SQL or character string buffers, nor does it even have a line 4, but we still get the above error because of the trigger we created. With this trigger, line 1 (declare) is the first line of the trigger itself, as opposed to the create trigger statement that creates it, so line 4 is the line a := '12';.
To track down this trigger, we can query the dba_triggers data dictionary view. In the example below, it turns up in the bottom row:
SQL> select trigger_name, trigger_type, owner from dba_triggers
2 where trigger_type in ('BEFORE EVENT', 'AFTER EVENT');
TRIGGER_NAME TRIGGER_TYPE OWNER
------------------------------ ---------------- ------------------------------
AW_DROP_TRG AFTER EVENT SYS
AW_TRUNC_TRG AFTER EVENT SYS
AW_REN_TRG AFTER EVENT SYS
XDB_PI_TRIG BEFORE EVENT SYS
SDO_DROP_USER AFTER EVENT MDSYS
SDO_ST_SYN_CREATE BEFORE EVENT MDSYS
SDO_TOPO_DROP_FTBL BEFORE EVENT MDSYS
ERROR_TRIGGER BEFORE EVENT LUKE