I get the error
ORA-00904: ggCategory: invalid identifier.
If I run the select normally, it works without any problems and returns the correct values. Does anyone know where the syntax error is?
execute immediate 'create table TEST_TABLE as (
select
category.name l_category,
u.*
from
User u
inner join listtext_view category on u.categoryID=category.ID and category.ident='||'ggCategory'||'
)';
If ggCategory is meant to be a string literal then:
execute immediate 'create table TEST_TABLE as (
select
category.name l_category,
u.*
from
User u
inner join listtext_view category on u.categoryID=category.ID and category.ident=''ggCategory''
)';
If it is meant to be a variable then:
execute immediate 'create table TEST_TABLE as (
select
category.name l_category,
u.*
from
User u
inner join listtext_view category on u.categoryID=category.ID and category.ident='||ggCategory||'
)';
Assuming, in this later case, that it is a number or something else that does not need quoting; or, if it does need quoting:
execute immediate 'create table TEST_TABLE as (
select
category.name l_category,
u.*
from
User u
inner join listtext_view category on u.categoryID=category.ID and category.ident='''||ggCategory||'''
)';
What is ggcategory? I presume it is a variable (or a parameter); if so, it shouldn't be enclosed into single quotes, i.e.
execute immediate 'create table TEST_TABLE as (
select
category.name l_category,
u.*
from User u inner join listtext_view category on
u.categoryID=category.ID and category.ident=' || ggCategory ||')';
----------
Besides, table name certainly isn't User as it is reserved word for Oracle's function.
Related
I have the query below, I am trying to select inner_query.ship_codes.
If I do inner_query.item_id_alias it works fine, but how can I select the ship_codes from my inner_query ?
SELECT inner_query.item_id_alias
FROM (
SELECT li.item_id as item_id_alias,
LISTAGG(a.ship_code, '; ')
WITHIN GROUP (ORDER BY a.ship_code) as "ship_codes"
FROM (
SELECT DISTINCT
ship_code,
MAX(order_id) as order_id
FROM orders o
WHERE o.order_id in (
SELECT li2.order_id
FROM line_items li2
GROUP BY li2.order_id
)
GROUP BY ship_code
)a
INNER JOIN line_items li ON a.order_id = li.order_id
GROUP BY li.item_id
) inner_query;
Use the column alias. Since you have used a quoted identifier in the sub-query then you need to use the quoted identifier in the outer query (and anywhere else you may want to reference it):
SELECT inner_query.item_id_alias,
inner_query."ship_codes"
FROM (
SELECT li.item_id as item_id_alias,
LISTAGG(a.ship_code, '; ')
WITHIN GROUP (ORDER BY a.ship_code) as "ship_codes"
FROM (
SELECT DISTINCT
ship_code,
MAX(order_id) as order_id
FROM orders o
WHERE o.order_id in (
SELECT li2.order_id
FROM line_items li2
GROUP BY li2.order_id
)
GROUP BY ship_code
)a
INNER JOIN line_items li ON a.order_id = li.order_id
GROUP BY li.item_id
) inner_query;
Alternatively, you can use a wildcard:
SELECT *
FROM (...) inner_query
or a wildcard with the alias for the sub-query:
SELECT inner_query.*
FROM (...) inner_query
or the identifiers without the alias for the sub-query:
SELECT item_id_alias,
"ship_codes"
FROM (...) inner_query
(Note: using DISTINCT and GROUP BY in the same SELECT statement is pointless. You can remove the DISTINCT and the output will not change.)
How to 'group by' a query using an alias, for example:
select count(*), (select * from....) as alias_column
from table
group by alias_column
I get 'alias_column' : INVALID_IDENTIFIER error message. Why? How to group this query?
select
count(count_col),
alias_column
from
(
select
count_col,
(select value from....) as alias_column
from
table
) as inline
group by
alias_column
Grouping normally works if you repeat the respective expression in the GROUP BY clause. Just mentioning an alias is not possible, because the SELECT step is the last step to happen the execution of a query, grouping happens earlier, when alias names are not yet defined.
To GROUP BY the result of a sub-query, you will have to take a little detour and use an nested query, as indicated above.
Nest the query with the alias column:
select count(*), alias_column
from
( select empno, (select deptno from emp where emp.empno = e.empno) as alias_column
from emp e
)
group by alias_column;
select count(*), (select * from....) as alias_column
from table
group by (select * from....)
In Oracle you cannot use an alias in a group by clause.
To use an alias in Oracle you need to ensure that the alias has been defined by your query at the point at which the alias is being used.
The most straightforward way to do this is to simply treat the original query as a subquery -- in this case,
select count(*), (select * from....) as alias_column
from table
group by (select * from....)
becomes
select count, alias_column
from
(select count(*) as count, (select * from....) as alias_column
from table)
group by alias_column
I can't speak to the performance implications, but it's very quick to write if you're trying to re-use an alias in your query - throw everything in parentheses and jump up a level...
If you don't have to use an alias you could do it this way:
select
EXTRACT(year from CURRENT_DATE), count(*) from something
group by EXTRACT(year from CURRENT_DATE)
order by EXTRACT(year from CURRENT_DATE)
Instead of using alias and subquery.
I have a case where I have to choose 100 columns out of 240 columns in select statement for that I have used below query to get those 100 column but couldn't use them in select statement
Query:
select listagg(column_name,',') within group (order by column_name) as col_name
from all_tab_cols
where lower(column_name) like 'test%'
Result:
col_name
-----------------------------
test1,test2,test3,....test100
Expected output:
use those resulted values in select statement
select test1,test2,test3.... test100
from table;
Thanks in advance
Dynamic query is what you wanted here. You can use below two query inside Stored Procedure or Functions.
select listagg(column_name,',') WITHIN GROUP (ORDER BY column_name) as col_name INTO VAR_COL_DETAILS
from all_tab_cols
where lower(column_name) like 'test%'
execute IMMIDEATE 'SELECT '||VAR_COL_DETAILS|| 'FROM TABLE_NAME';
I just recently found out that subqueries are not allowed in INSERT statements that are inside stored procedures. This is my script:
begin
execute immediate 'truncate table itcustadm.GL_DTPJ_TEST2';
insert into GL_DTPJ_TEST2
(rule_no,
posted_by_user_id,
transaction_id,
transaction_sr_no,
dr_amount,
cr_amount,
tran_crncy_code,
bkdt_tran_flg,
bank_desc
)
select
tq.rule_no,
tq.posted_by_user_id,
tq.transaction_id,
tq.transaction_sr_no,
tq.dr_amount,
tq.cr_amount,
tq.tran_crncy_code,
tq.bkdt_tran_flg,
(select ent.bank_desc from crmuser.end ent where ent.bank_id = gam.bank_id);
But since the (select ent.bank_desc from crmuser.end ent where ent.bank_id = gam.bank_id) at the bottom of the SELECT statement is not allowed by Oracle, what's the best way to accomplish this?
I actually have this code right before the INSERT statement, but I don't know how to exactly use it:
get_bank_desc := '(select ent.bank_desc from crmuser.end ent ' ||
'where ent.bank_id = gam.bank_id)';
I am not sure what you are exactly trying for, but below code may be useful for you, you can achieve inserting a SubQuery output into a table using below query sample, but make sure output of the SubQuery is a single row o/p, so that you can escape from "ORA-01427: single-row SubQuery returns more than one row" ERROR.
insert into test_ins1
values(1,(SELECT COL2 FROM TEST_INS WHERE COL1=1 ));
Even then you can use rownum in where condition and take the single value.
Please let me know in case of any doubts
declare
bank_desc_temp bank_desk_type; /* the type defined in crmuser.ent for bank_desc*/
begin
select ent.bank_desc into bank_desc_temp from crmuser.end ent where ent.bank_id = gam.bank_id;
execute immediate 'truncate table itcustadm.GL_DTPJ_TEST2';
insert into GL_DTPJ_TEST2
(rule_no,
posted_by_user_id,
transaction_id,
transaction_sr_no,
dr_amount,
cr_amount,
tran_crncy_code,
bkdt_tran_flg,
bank_desc
)
select
tq.rule_no,
tq.posted_by_user_id,
tq.transaction_id,
tq.transaction_sr_no,
tq.dr_amount,
tq.cr_amount,
tq.tran_crncy_code,
tq.bkdt_tran_flg,
bank_desc_temp;
end;
When you say "not allowed" what do you mean? Did you get an error?
I ask, because subqueries are definitely allowed inside an insert as select statement, providing you have the syntax correct (and the subquery returns at most one row), e.g.:
create table test_tab (col1 number, col2 varchar2(10));
begin
insert into test_tab
select 1,
(select 'Yes' from dual d2 where d.dummy = d2.dummy)
from dual d;
commit;
end;
/
select * from test_tab;
COL1 COL2
---------- ----------
1 Yes
There are some syntax issues with the code you provided - where is the from clause, and where are the tq and gam aliases defined?
There are two syntax you can use in your insert statement:
(I)
INSERT INTO table_name( column1, column2....columnN)
VALUES ( value1, value2....valueN);
(II)
INSERT INTO table (column1, column2, ... )
SELECT expression1, expression2, ...
FROM source_table(s)
WHERE conditions;
In your example, you should choose the second approach:
insert into GL_DTPJ_TEST2 (rule_no,
posted_by_user_id,
transaction_id,
transaction_sr_no,
dr_amount,
cr_amount,
tran_crncy_code,
bkdt_tran_flg,
bank_desc
)
select tq.rule_no,
tq.posted_by_user_id,
tq.transaction_id,
tq.transaction_sr_no,
tq.dr_amount,
tq.cr_amount,
tq.tran_crncy_code,
tq.bkdt_tran_flg,
ent.bank_desc
from crmuser.gam
join crmuser.end ent
on ent.bank_id = gam.bank_id
;
basically, if you want to add records using an insert statement, you should use a full select statement first. Here is how I would do it:
(1)
select *
from table1;
(2)
select column1
,column2
,column3
from table1;
(3)
select t1.column1
,t1.column2
,t1.column3
,t2.column4
,t2.column5
from table1 t1
join table2 t2
on t2.id = t1.id
;
(4)
insert into table3 (col1
,col2
,col3
,col4
,col5)
select t1.column1
,t1.column2
,t1.column3
,t2.column4
,t2.column5
from table1 t1
join table2 t2
on t2.id = t1.id
;
I want to write a SQK script with insert query in Oracle where one of the value will be fetched from cursor and rest all will be retrieved from table.
For example, consider Employee table:
Emp_No | Emp_Name
1 | AAA
...........
I am reading the table into a cursor.
Cursor c1 is select emp_no, emp_name from employee;
I am iterating the cursor and adding to a table along with information from another table.
for empCur in c1
loop
insert into employee_info(emp_no, emp_name, address, age, ... ) values (empCur.emp_no, empCur.emp_name, select t.address, t.age, ... from employee_temp_table t where t.emp_no=empCur.emp_no)
end loop;
Is my script valid? If not is there any other way to achieve it? Since few values are in cursor and few are in another table I am not sure how to handle this.
Your script isn't correct because this
select t.address, t.age, ... from employee_temp_table t where t.emp_no=empCur.emp_no
is not a valid expression. You may use a scalar subquery (one-row, one-column subquery) only, like this:
insert into t1(col1, col2, col3) values (1, (select col1 from t2), (select col2 from t2));
Or you may try insert from select:
for empCur in c1 loop
insert into employee_info(emp_no, emp_name, address, age, ... )
select empCur.emp_no, empCur.emp_name, t.address, t.age, ... from employee_temp_table t where t.emp_no=empCur.emp_no;
end loop;
If you want to use the cursor, why not just join the tables inside the cursor?
for empCur in ( select e.emp_no, e.emp_name, t.address, t.age ...
from employee e join employee_temp_table t on ( t.emp_no = e.emp_no )
) loop
insert into employee_info(...) values ( empCur.emp_no, ...);
end loop;
Or with a sql insert: (if you can choose sql over pl/sql - T Kyte says do it)
insert into employee_info
select e.emp_no, e.emp_name, t.address, t.age ...
from employee e join employee_temp_table t on ( t.emp_no = e.emp_no );