I'm being asked to create a script that basically does the same thing as the describe command.
I have figured out how to write the script and get the output I want, but the second part of the assignment is to "duplicate the format of the describe command" I'm stumped, is there really a way to simply duplicate that format?
Assuming your query is something like (note that I'm not bothering to handle every different data type)
select column_name "Name",
(case when nullable = 'N'
then 'NOT NULL'
else null
end) "Null?",
(case when data_type = 'DATE'
then data_type
when data_type = 'NUMBER' and data_scale > 0
then data_type || '(' || data_precision || ',' || data_scale || ')'
when data_type = 'NUMBER' and data_scale = 0
then data_type || '(' || data_precision || ')'
when data_type = 'VARCHAR2'
then data_type || '(' || data_length || ')'
end) "Type"
from dba_tab_cols
where table_name = 'EMP'
order by column_id
You can issue some SQL*Plus commands to format the output
SQL> column "Nmae" format a30;
SQL> column "Null?" format a8;
SQL> column "Type" format a30;
and then the output of your query will match up with the output of the DESCRIBE command
SQL> ed
Wrote file afiedt.buf
1 select column_name "Name",
2 (case when nullable = 'N'
3 then 'NOT NULL'
4 else null
5 end) "Null?",
6 (case when data_type = 'DATE'
7 then data_type
8 when data_type = 'NUMBER' and data_scale > 0
9 then data_type || '(' || data_precision || ',' || data_scale || ')'
10 when data_type = 'NUMBER' and data_scale = 0
11 then data_type || '(' || data_precision || ')'
12 when data_type = 'VARCHAR2'
13 then data_type || '(' || data_length || ')'
14 end) "Type"
15 from dba_tab_cols
16 where table_name = 'EMP'
17* order by column_id
SQL> /
Name Null? Type
------------------------------ -------- ------------------------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)
8 rows selected.
Related
I have a SEARCH package with several functions within that each return a pipelined table.
I am getting the following error:
ORA-29902: error in executing ODCIIndexStart() routine
ORA-06512: at "<SCHEMA_NAME>.SEARCH", line 955
ORA-06512: at "<SCHEMA_NAME>.SEARCH", line 216
ORA-06512: at line 1
ORA-06512: at "<SCHEMA_NAME>.SEARCH", line 1143
ORA-06512: at line 1
29902. 00000 - "error in executing ODCIIndexStart() routine"
*Cause: The execution of ODCIIndexStart routine caused an error.
*Action: Examine the error messages produced by the indextype code and
take appropriate action.
The command that I use to get this error is:
select * from table(search.user_search(10000003, '', 1, 20, 5, '', '', ''));
Here is the code around line 1143 of the SEARCH body:
FUNCTION USER_SEARCH(p_user_id number, p_search varchar2, p_page number, p_num_results number, p_concept_type_id number := null, p_standard_org varchar2 := null, p_standard_title varchar2 := null, p_standard_number varchar2 := null) RETURN SEARCH_RESULTS_TABLE AS
v_sub char(1);
v_rtn search_results_table := search_results_table();
v_user_id number;
v_page number;
v_num_results number;
v_query varchar2(4000);
cursor c_concept is
select * from table(search.concept_new(v_user_id, v_query, v_page, v_num_results, p_concept_type_id, p_standard_org, p_standard_title, p_standard_number));
BEGIN
v_page := p_page;
v_num_results := p_num_results;
v_query := p_search;
if (v_query = '') then
v_query := null;
end if;
-- ONLY DURING DEVELOPMENT
v_user_id := p_user_id;
if v_user_id = 0 then
v_user_id := 2;
end if;
if v_page = null then
v_page := 1;
end if;
if v_num_results = null then
v_num_results := -1;
end if;
select security.has_permission(p_user_id, 'UNLIMITED_RESULTS') into v_sub from dual;
case v_sub
when 'N' then
v_rtn := search.term(v_user_id, p_search, 1, 20, P_concept_type_id, p_standard_org, p_standard_title, p_standard_number);
when 'Y' then
for r_concept in c_concept loop -- line 1143
v_rtn.extend;
v_rtn(v_rtn.last) := search_results_row(r_concept.SCORE, r_concept.FROM_TABLE, r_concept.ID, r_concept.IN_DICTIONARY);
end loop;
end case;
return v_rtn;
END USER_SEARCH;
The code around line 216:
FUNCTION CONCEPT_NEW(p_user_id number, p_search varchar2, p_page number := 1, p_num_results number := -1, p_concept_type_id number := null, p_standard_org varchar2 := null, p_standard_title varchar2 := null, p_standard_number varchar2 := null) RETURN SEARCH_RESULTS_TABLE PIPELINED AS
out_rec search_results_row := search_results_row(null,null,null,null);
v_num_pages number;
v_num_results number;
cursor c_count is
select count(*) cnt, ceil(count(*) / p_num_results) num_pages from (
select * from (
select rownum rn, bb.* from (
select * from (
select sum(score) score, concept_id from
(
(
select
sum(score) score,
concept_id
from
(
select
s.score + (case
when c.eotd = 'N' then
200
else
0
end) score,
ct.concept_id
from
table(search.synonym_search(p_search)) s,
term_synonym ts,
concept_term ct,
concept c
where
c.eotd = 'N' and
s.table_id = ts.synonym_id and
ts.term_id = ct.term_id and
c.concept_id = ct.concept_id
)
group by
concept_id
)
union all
(
select
sum(score) score,
concept_id
from
(
select
s.score + (case
when c.eotd = 'N' then
200
else
0
end) score,
cd.concept_id
from
table(search.definition_search(p_search)) s,
concept_definition cd,
concept c
where
c.eotd = 'N' and
s.table_id = cd.definition_id and
c.concept_id = cd.concept_id
)
group by
concept_id
)
)
group by concept_id
) order by score desc
) bb) where score > 100) where rn < 1000;
-- another cursor here called c_search (removed for cleanliness)
v_added boolean;
v_in_dict varchar(1);
v_concept_id number;
cursor c_in_dict is
select * from dictionary_concept where concept_id = v_concept_id and dictionary_id in (select dictionary_id from company_dictionary where client_company_id in (select client_company_id from users where users_id = p_user_id));
v_in_dict_result c_in_dict%rowtype;
BEGIN
open c_count;
fetch c_count into v_num_results, v_num_pages; -- line 216
close c_count;
out_rec.SCORE := v_num_results;
out_rec.FROM_TABLE := 'HEADER';
out_rec.ID := v_num_pages;
out_rec.IN_DICTIONARY := 'N';
pipe row(out_rec);
-- more code here but been removed
RETURN;
END CONCEPT_NEW;
The code around line 995:
FUNCTION STANDARD_SEARCH(p_search varchar2) RETURN RESULT_TABLE
PIPELINED
AS
out_rec result_type := result_type(null, null);
cursor c_search is
select
45 score,
source_id
from
source
where
source_title = p_search or
standard_number = p_search
union all
select
40,
source_id
from
source
where
lower(source_title) = lower(p_search) or
lower(standard_number) = lower(p_search)
union all
select
35,
source_id
from
source
where
lower(source_title) like lower(p_search) || '%' or
lower(standard_number) like lower(p_search) || '%'
union all
select
30,
source_id
from
source
where
lower(source_title) like '%' || lower(p_search) || '%' or
lower(standard_number) like '%' || lower(p_search) || '%'
union all
select
10 * contains(source_title, lower(p_search)),
source_id
from
source
where
contains(source_title, lower(p_search)) > 1
union all
select
10 * contains(standard_number, lower(p_search)),
source_id
from
source
where
contains(standard_number, lower(p_search)) > 1;
BEGIN
for r_search in c_search loop -- line 995
out_rec.SCORE := r_search.SCORE;
out_rec.TABLE_ID := r_search.SOURCE_ID;
pipe row(out_rec);
end loop;
return;
END;
Change = null to is null. Zero-length strings in Oracle are already NULL so = '' is also incorrect.
Those are some obvious bugs but the code is so complex I'm not sure if they are directly related to the errors. You may need to shrink your code down until it can fit inside a small, reproducible test case. That can take hours of work sometimes.
Another suggestion is to rethink whether you need to use pipelined functions. In my experience pipelined functions are buggy and over-used. Sometimes they can be replaced by regular SQL statements. Sometimes they can be replaced by a simpler function that returns a complete collection, instead of returning it one row at a time. Unless the collection is so ginormous that it can't reasonably fit in memory, or you need the function to return the first N results so they can be processed immediately, the pipelined feature doesn't help.
I have multiple columns in Azure Machine Learning that each have an hour, year, day, minute, etc for a date. I need to convert this hour from UTC to EDT, and then make it a date string such as
YYYY/MM/DD HH:SS
This way, I can do an inner join. I've tried using CAST, CONVERT, and other SQLite functions, but none of these combos work. Here is where I am now:
select *
CAST([Col11] as int) -4 as EDTHour
([Col8] || '/' || [Col9] || '/' || [Col10] || ' ' || EDTHour|| ':' || [Col12]) as WeatherTime from t1
select 'Time Stamp' as secondTableTime from t2
SELECT *
FROM t1
INNER JOIN t2
ON t1.WeatherTime=t2.secondTableTime
However, It never lets me cast the varchar column Col11 to a integer or decimal. What am I missing?
Not sure you can use the column alias in your concatenation in another column.
Try this instead:
select ([Col8] || '/' || [Col9] || '/' || [Col10] || ' ' || (Cast([Col11] as int) - 4) || ':' || [Col12]) as WeatherTime
Maybe that will get you where you want to go.
TASK:
define PL/SQL table, which elements is records. The Record structure should be the same like in Subjects talbe. Initiate 5 elements of new table, using consequent and increment index, starting from 1. Input values into every record. Print (output) inputted data, describing it in readable way.
Subjects table structure is:
Id NUMBER(3), //primary key
Subj_name VARCHAR2(40),
Description VARCHAR2(200)
This is my attempt:
SET serveroutput on;
CREATE TABLE Subject
(
IdSubj NUMBER(3),
SubjName VARCHAR2(40),
Descr VARCHAR2(500)
);
BEGIN
For i IN 1..5 LOOP
INSERT INTO Subject(IdSubj, SubjName, Descr)
VALUES(i, 'Subject number: ' || TO_CHAR(i), 'Description of subject ');
dbms_output.put_line('Id subj: ' || i || ', Subject:' || ', Descr: ');
END LOOP;
END;
Questions:
1) Did I initiate SubjName record in correct way ('Subject number: ' || TO_CHAR(i))?
2) How to output 2nd and 3rd values?
If by "output 2nd and 3rd values" you mean the values you inserted into the SUBJNAME and DESCR columns you could use the RETURNING clause to save the inserted values and then output the values from the variables, as in:
DECLARE
strSubjname SUBJECT.SUBJNAME%TYPE;
strDescr SUBJECT.DESCR%TYPE;
BEGIN
For i IN 1..5 LOOP
INSERT INTO SUBJECT(IdSubj, SubjName, Descr)
VALUES(i, 'Subject number: ' || TO_CHAR(i), 'Description of subject ')
RETURNING SUBJNAME, DESCR INTO strSubjname, strDescr;
dbms_output.put_line('Id subj: ' || i ||
', Subject:' || strSubjname ||
', Descr: ' || strDescr);
END LOOP;
END;
Share and enjoy.
Anyone can help me with this issue
declare
lv2_sql VARCHAR2(32767);
cursor c_scv is
select financial_code, object_id, daytime from stream_category_version;
begin
for r_scv in c_scv LOOP
IF r_scv.financial_code = 'PURCHASE' THEN
lv2_sql := 'UPDATE stream_category_version ' || CHR(10) ||
'set REVN_PURCHASES_IND = ''Y'', last_updated_by = nvl(last_updated_by, created_by) ' || CHR(10) ||
'WHERE object_id = r_scv.object_id AND daytime = r_scv.daytime';
ecdp_dynsql.execute_statement(lv2_sql);
ELSIF r_scv.financial_code = 'SALE' THEN
lv2_sql := 'UPDATE stream_category_version ' || CHR(10) ||
'set REVN_SALES_IND = ''Y'', last_updated_by = nvl(last_updated_by, created_by) ' || CHR(10) ||
'WHERE object_id = r_scv.object_id AND daytime = r_scv.daytime';
ecdp_dynsql.execute_statement(lv2_sql);
END IF;
END LOOP;
end;
I have code as shown above, but i got error saying 'ORA-00904: R_SCV.DAYTIME: invalid identifier'. I have checked the table definition for 'stream_category_version' and found the column DAYTIME as shown below
SQL> desc stream_category_version
Name Type Nullable Default Comments
------------------ -------------- -------- ------- --------
OBJECT_ID VARCHAR2(32)
DAYTIME DATE
END_DATE DATE Y
NAME VARCHAR2(240) Y
FINANCIAL_CODE VARCHAR2(32) Y
SORT_ORDER NUMBER Y
COMMENTS VARCHAR2(2000) Y
Then i am confused with the error. Anyone can help me ?
Thanks in advance.
Shortly speaking - Oracle is case sensitive...
... probably during table creation column was typed UPPERCASE in quotation marks like that:
"DAYTIME"
and in your sql i see this column in lowercase
so you should verify your column name and best change it to version without quotation marks.
Other option is to call this column like that:
= r_scv.DAYTIME
I have a table with the following fields and example value:
coursecode BIO 101
a_code FA
b_code SP
c_code SU
d_code
e_code
I'm trying to populate a field in another table (using coursecode as the key) with a comma separated list of all the "code" fields that have values (i.e. "FA, SP, SU"). I am accomplishing this successfully with the following code, but it is messy and was wondering if there was a more elegant way to accomplish this (esp. without all the UNION statements):
SELECT coursecode, group_concat(codes)
FROM (
SELECT
coursecode,
a_code AS codes
FROM scbsupp
WHERE coursecode="BIO 317"
UNION
SELECT coursecode,
b_code AS codes
FROM scbsupp
WHERE coursecode="BIO 317"
UNION
SELECT
coursecode,
c_code AS codes
FROM scbsupp
WHERE coursecode="BIO 317"
UNION
SELECT coursecode,
d_code AS codes
FROM scbsupp
WHERE coursecode="BIO 317"
UNION
SELECT coursecode,
e_code AS codes
FROM scbsupp
WHERE coursecode="BIO 317"
) WHERE codes != "";
For my own knowledge I would like to know if there's a better way to do this, I appreciate any help!
You can do:
SELECT coursecode,
LTRIM(
CASE WHEN (a_code IS NOT NULL AND a_code <> '') THEN a_code ELSE '' END ||
CASE WHEN (b_code is NOT NULL AND b_code <> '') THEN ',' || b_code ELSE '' END ||
CASE WHEN (c_code IS NOT NULL AND c_code <> '') THEN ',' || c_code ELSE '' END ||
CASE WHEN (d_code IS NOT NULL AND d_code <> '') THEN ',' || d_code ELSE '' END ||
CASE WHEN (e_code IS NOT NULL AND e_code <> '') THEN ',' || e_code ELSE '' END, ','
) AS code
FROM scbsupp
WHERE coursecode="BIO 317"
;