I try to use ORDER BY inside the Oracle Decode function
The compiler says missing right parenthesis
DECODE(controlNumber, NULL, myOldNUmber, (SELECT myNewNumber FROM tableA A, tableB B WHERE A.control_id = B.control_id AND A.other_id = B.other_id) ) AS finalnumber,
Seems it is the same query did not see why the ORDER BY is not accepted here:
DECODE(controlNumber, NULL, myOldNUmber, (SELECT myNewNumber FROM tableA A, tableB B WHERE A.control_id = B.control_id AND A.other_id = B.other_id ORDER BY createdTime)) AS finalnumber,
I am not able to test currently, but please try...
DECODE(controlNumber, NULL, myOldNUmber, (SELECT myNewNumber FROM (SELECT myNewNumber FROM tableA A, tableB B WHERE A.control_id = B.control_id AND A.other_id = B.other_id ORDER BY createdTime) WHERE rownum=1) AS finalnumber
Related
I am new to PostgreSQL and was wondering if there is a table which matches Oracle's user_cons_columns table which provides a column position column similar to user_cons_columns.position. Essentially, I am trying to convert the following oracle code to PostgreSQL. It attains the PK columns in order of PK definition:
Oracle Code (Original):
select a.table_name tab_name,
a.colum_name col_name,
a.position col_order
from user_cons_columns a,
user_constraints b
where a.table_name = b.table_name
and a.constraint_name = b.constraint_name
and b.constraint_type = 'P'
and a.table_name = 'some_table_name';
PostgreSQL Code (Oracle Equiv):
/* Below is my attempt at the PostgreSQL conversion */
select isc.table_name tab_name,
isc.column_name col_name,
isc.ordinal_position col_order
from pg_attribute as pga
inner join pg_class as pgc on pga.attrelid = pgc.oid
inner join pg_namespace as pgn on pgn.oid = pgc.relnamespace
inner join information_schema.columns as isc on isc.column_name = pga.attname
and isc.table_name = pgc.relname
where isc.table_name = 'sometablename';
In my PostgreSQL conversion attempt I am missing the relationship between the constraint and its position but use the column position. Which is not the same. Is there a way to do the former? Thanks in advance!
The column numbers of a constraint and their order are stored in pg_constraint.conkey; for foreign keys, the corresponding numbers of the target columns are in pg_constraint.confkey.
The description of table columns is in pg_attribute; the column number is stored in attnum.
Below is the solution that I derived thanks to the answer from #Laurenz Albe.
select isc.table_name tab_name,
isc.col_name col_name,
pgco.conkey[1] col_order
from pg_attribute as pga
inner join pg_class as pgc on pga.attrelid = pgc.oid
inner join pg_namespace as pgn on pgn.oid = pgc.relnamespace
inner join information_schema.columns as isc on isc.column = pga.attname
and isc.table_name = pgc.relname
inner join pg_constraint as pgco on pgco.conkey[1] = pga.attnum
and pgco.connamespace = pgc.relnamespace
and pgco.conrelid = pga.attrelid
where isc.table_name = 'sometablename'
and pgco.contype ='p';
Hope this is useful to someone else.
I dont understand why its giving Sql Command not properly ended,
Update Table1
Set LS.SECU_CHECKER_CODE = '1000',
LS.SECU_CHECKER_DATE = To_Char(SysDate, 'YYYYMMDDHH24MISS'),
LS.SECU_RECORD_STATUS = 98
From Table1 LS
Join Table2 LS2
On LS2.SECC_SECURITY_ID = LS.SECU_SECURITY_ID
Where LS2.SECC_LIMIT_ID = '00010101010101';
The syntax for updating from a view is different in Oracle from the syntax you are using. However, you shouldn't even update from a view in your case, because you are not using the other table's content, but merely check for existence of a record for which you should rather use EXISTS or IN:
update table1
set secu_checker_code = '1000'
, secu_checker_date = to_char(sysdate, 'yyyymmddhh24miss')
, secu_record_status = 98
where secu_security_id in
(
select secc_security_id
from table2
where secc_limit_id = '00010101010101'
);
It looks like you are trying to update a selection of table 1. You need a where clause.
Possibly something like this:
update table1 t1
set ls.secu_checker_code = '1000'
,ls.secu_checker_date = to_char(sysdate, 'YYYYMMDDHH24MISS')
,ls.secu_record_status = 98
where t1.secu_security_id in (select t2.secc_security_id
from table2 t2
where t2.secc_limit_id = '00010101010101');
This is also working fine
UPDATE table1
SET (SECU_CHECKER_CODE,
SECU_CHECKER_DATE,
SECU_RECORD_STATUS) = (
Select '1000',
To_Date(SysDate),
98
From table1
Join table2
On SECC_SECURITY_ID = SECU_SECURITY_ID
Where SECC_LIMIT_ID = '00010101010101')
When i execute the following query, i get the message like
Ora-01427 single-row subquery returns more than one row
I am trying to update "City" column in Table A From another table.
How would I do this?
table A: Name, PER_code(it also has duplicated value or null), city, PD_code
table B: Name, PER_code(No duplicated value,Maybe null), city, Postal_code
The update statement:
UPDATE A
SET (A.city) =
(SELECT B.city
FROM B
INNER JOIN A
ON A.per_code=B.per_code
WHERE A.per_code is not null)
Since there are duplicate values but you select only one field, you modify your query from
UPDATE A SET (A.city) = (SELECT B.city FROM B INNER JOIN A ON
A.per_code=B.per_code WHERE A.per_code is not null)
to
UPDATE A SET (A.city) = (SELECT DISTINCT B.city FROM B INNER JOIN A ON
A.per_code=B.per_code WHERE A.per_code is not null)
The distinct operator will allow you to keep a single value if it's duplicated in the table B. If there are multiple distinct values, you will have to look at your data and make a decision about which value should be used in the other table.
You can also try MERGE INTO selecting DISTINCT records.
MERGE INTO A d
USING
( SELECT DISTINCT per_code, city FROM B ) s
ON ( s.per_code = d.per_code )
WHEN MATCHED THEN UPDATE SET d.City = s.City
WHERE d.per_code IS NOT NULL;
I think you intend a correlated subquery:
UPDATE A
SET city = (SELECT B.city
FROM B
WHERE A.per_code = B.per_code
)
WHERE A.per_code is not null;
EDIT:
The above should work given the constraints in the original question. If it does not, it is easily adaptable:
UPDATE A
SET city = (SELECT B.city
FROM B
WHERE A.per_code = B.per_code AND rownum = 1
)
WHERE A.per_code is not null;
select col_1,
col_2
from tbl_a A,
tbl_b B,
( select col_1,col_2 from tbl_c where clo_c_1 <> '1' ) C
where A.col_1 = B.col_1
and A.col_2 = B.col_2
and (A.col_2 = B.col_2
or C.col_2 = A.col_2);
My environment is Oracle,when I run this SQL,if the sub SQL C hasn't got a result,then the entire SQL returns NULL.Whereas if C has a result(not null) which fits other condions,there could be a result.Would somebody explain why sub SQL at the from area need to be not NULL?Thanks very much.
You need to bring yourself into the 90s and start using standard joins:
select col_1,
col_2
from tbl_a A
inner join
tbl_b B
on A.col_1 = B.col_1
and A.col_2 = B.col_2
left join
( select col_1,col_2 from tbl_c where clo_c_1 <> '1' ) C
on
C.col_2 = A.col_2
As a guess. I'm not entirely sure what your join conditions should be but that's my first attempt.
This is expected behaviour. When you join two result sets, you only want to get results where the join criteria is satisfied. If the criteria are not satisfied, you should get no results.
If I run the query "get me all the employees older than 65, and get their departments", if there are no employees older than 65, you would not expect to get any results, even if there are some departments in the database.
SELECT emp.name, dept.dept_name
FROM emp
JOIN dept
ON (emp.dept_no = dept.dept_no)
WHERE emp.age > 65;
As the others said, if you actually want to get rows regardless of whether the subquery has any results, you need to use an outer join.
I've inherited a schema so don't have complete knowledge/confidence in what is there.
I have a project table with a projectId. There are a whole bunch of other tables that reference this table by project id. What I want to do is run a query to establish:
Which tables have foreign key references to the project table on
the project id
Which tables have a column called project id (in
case foreign keys are not set up).
If it was SQL Server I know how to query the metadata but how do I do this in Oracle?
1)
select table_name
from all_constraints
where r_constraint_name = [your pk/uk constraint on PROJECTS(id)]
2)
select table_name
from all_tab_columns
where column_name = 'PROJECT_ID'
You may want to add an extra predicate containing the OWNER column.
Regards,
Rob.
Ok. Here a request that give you the referenced table and column :
SELECT
c_list.CONSTRAINT_NAME as NAME,
substr(c_src.COLUMN_NAME, 1, 20) as SRC_COLUMN,
c_dest.TABLE_NAME as DEST_TABLE,
substr(c_dest.COLUMN_NAME, 1, 20) as DEST_COLUMN
FROM ALL_CONSTRAINTS c_list, ALL_CONS_COLUMNS c_src, ALL_CONS_COLUMNS c_dest
WHERE c_list.CONSTRAINT_NAME = c_src.CONSTRAINT_NAME
AND c_list.OWNER = c_src.OWNER
AND c_list.R_CONSTRAINT_NAME = c_dest.CONSTRAINT_NAME
AND c_list.OWNER = c_dest.OWNER
AND c_list.CONSTRAINT_TYPE = 'R'
AND c_src.OWNER = '<your-schema-here>'
AND c_src.TABLE_NAME = '<your-table-here>'
GROUP BY c_list.CONSTRAINT_NAME, c_src.TABLE_NAME,
c_src.COLUMN_NAME, c_dest.TABLE_NAME, c_dest.COLUMN_NAME;
Which give you something like this:
NAME |SRC_COLUMN |DEST_TABLE | DEST_COLUMN
----------------------|----------------|----------------------|-----------
CFK_RUB_FOR |FOR_URN |T03_FORMAT |FOR_URN
CFK_RUB_RUB |RUB_RUB_URN |T01_RUBRIQUE |RUB_URN
CFK_RUB_SUP |SUP_URN |T01_SUPPORT |SUP_URN
CFK_RUB_PRD |PRD_URN |T05_PRODUIT |PRD_URN
You can forget the substr() function if the result is usable without. This is not my case.
1): SELECT * FROM USER_CONSTRAINTS WHERE CONSTRAINT_NAME='R' and R_CONSTRAINT_NAME='xxx'
where xxx is the name of the primary key constraint on the project table
2): SELECT * FROM USER_TAB_COLUMNS WHERE COLUMN_NAME='PROJECT_ID'
The r_constraint_name answers here didn't seem to work for me, not sure why as I'm new to Oracle myself, but this worked:
SELECT * FROM ALL_CONSTRAINTS WHERE CONSTRAINT_NAME = '<constraint>';
My problem was slightly different. I have a table and I wanted to programatically know which other tables/columns it references.
I started with Stan's response above but this didn't give me exactly what I needed, so I came up with this, which I post here in case anyone else has my problem:
WITH src as
(SELECT ac.table_name, ac.constraint_name, accs.column_name, accs.position, ac.r_constraint_name
FROM ALL_CONSTRAINTS ac, all_cons_columns accs
WHERE ac.owner = '<owner>'
AND ac.constraint_type = 'R'
AND ac.table_name = '<src_table>'
AND accs.owner = ac.owner
AND accs.table_name = ac.table_name
AND accs.constraint_name = ac.constraint_name
ORDER BY ac.table_name, ac.constraint_name, accs.position),
dst as
(SELECT ac.table_name, ac.constraint_name, accs.column_name, accs.position
FROM ALL_CONSTRAINTS ac, all_cons_columns accs
WHERE ac.owner = '<owner>'
AND accs.owner = ac.owner
AND accs.table_name = ac.table_name
AND accs.constraint_name = ac.constraint_name
ORDER BY ac.table_name, ac.constraint_name, accs.position)
SELECT src.table_name as src_table,
dst.table_name as dst_table,
src.constraint_name as src_constraint,
src.column_name as src_column,
dst.column_name as dst_column,
src.position as position
FROM src,dst
WHERE src.r_constraint_name = dst.constraint_name
AND src.position = dst.position
Use this query.
select b.TABLE_NAME,b.CONSTRAINT_NAME ,a.COLUMN_NAME
from all_constraints b, all_cons_columns a
where r_constraint_name = 'Constraint_Name' and a.CONSTRAINT_NAME=b.CONSTRAINT_NAME;