PostgreSQL- how to update table from three tables - sql

i want to update the value of the column name of the output table C. i combine the value of C.name and B. user_name in the set statement.
desired result:i expect that the result of the select statement will replace the value of the set statement and finally update it to the output table.
update output_table as C
set C.name = name || ',' || B.user_name || ','
(select A.fullname from tableA as A , tableB as B
where A.service_code = B.service_code
and A.systime is null)
and C.name is not null ;
i have written the above code and the error shown as below.
ERROR: relation "b" does not exist [ErrorId: 1-6392e438-52c1cc0d2221a06d1d417996]

Related

getting ORA-01407:cannot update to null error

i am getting ORA-01407:cannot update to null error for below query, Please help on this.
UPDATE PS_CT_IQN_ACC_STG stg
SET (CTS_WO_ID,CTS_WO_END_DATE,CTS_WO_REG_RATE,CTS_WO_OT_RATE,VENDOR_ID) = (select CT_WORK_ORDER_ID,END_DATE,CT_WO_RATEREGULAR,CT_WO_RATEOVERTIME,CT_WO_VENDOR_ID from ps_cts_iqn_empl_wo WO1
where WO1.CT_WORK_ORDER_ID= (select max(CT_WORK_ORDER_ID) from ps_cts_iqn_empl_wo WO where WO.cts_peoplesoft_id = STG.EMPLID
AND WO.ct_wo_project_id = STG.project_id and stg.report_due_date between WO.start_date and WO.end_date )
and WO1.lastupddttm = (select max(lastupddttm) from ps_cts_iqn_empl_wo WO2 where WO2.cts_peoplesoft_id = STG.EMPLID
AND WO2.ct_wo_project_id = STG.project_id and stg.report_due_date between WO2.start_date and WO2.end_date ))
Your query is updating the following 5 columns of the table PS_CT_IQN_ACC_STG:
CTS_WO_ID
CTS_WO_END_DATE
CTS_WO_REG_RATE
CTS_WO_OT_RATE
VENDOR_ID
SELECT Query to update the column values must be returning NULL for one of the columns for which NOT NULL constraint OR check of not null is applied.
You can check this from the following dictionary views:
USER_TAB_COLS -- NULLABLE column will be N for not null columns
USER_CONSTRAINTS -- Type will be C with Search_condition like <COLUMN_NAME> IS NOT NULL for not null columns.
Cheers!!

Three tables A,B and C exist where in I need to add or concatenate values from C based on formula present in B into A

I have 3 tables A, B and C. I have to insert values into table A which are available in table C based on formula present in table B.
Example:
TableA::
Person loc Address
--------------------
abc usa NULL
def uk NULL
Tableb::
loc formula
--------------------
usa a1+a2+a3
uk a1+a3
Tablec::
person a1 a2 a3
----------------------------------------
abc dadad sadada dadada
def fkjfkans kjdvbnskdnb
execute immediate '
SELECT
a.person,
'b.'||replace(formula,'+','||b.') as new_Add,
c.loc,c.a1,c.a2,c.a3
from TableA a,
TableC c,
TableB b
WHERE
a.person = c.Person
and a.loc = b.loc;';
I know my query is not complete, but I would like to know if this approach works?
This is a truly poor database design and whoever came up with it(if it's not you) should have a word with me. You have already seen how nightmarish it was to deal with quotes in your query. Moreover, Programs written in Dynamic SQL are always hard to debug and difficult to maintain. I would recommend you to change the model if possible. Remember this whenever you use this code.
DECLARE
v_addr VARCHAR2(1000);
BEGIN
FOR rec IN (
SELECT
a.person,
a.loc,
replace(formula,'+','||') AS true_formula
FROM
tablea a
JOIN tableb b ON a.loc = b.loc
JOIN tablec c ON a.person = c.person
) LOOP
EXECUTE IMMEDIATE 'SELECT '
|| rec.true_formula
|| ' FROM Tablec WHERE person = :b_person'
INTO v_addr
USING rec.person;
EXECUTE IMMEDIATE 'UPDATE tablea
SET
address =:b_addr
WHERE
person =:b_person
AND loc =:b_loc'
USING v_addr,rec.person,rec.loc;
END LOOP;
END;
/
Demo
If you have a similar model (conditions restricted to a1, a2 and a3), you can use the below query to generate the kind of data you need for table B:
select a.loc,
trim(trailing '+' from (
trim(trailing from (
case when c.a1 IS NOT NULL
THEN 'a1 + '
end ||
case when c.a2 IS NOT NULL
THEN 'a2 + '
end ||
case when c.a3 IS NOT NULL
THEN 'a3'
end ))))
from A a, C c where a.person = c.person;

T-SQL Query to get table dependencies for all tables in database

I have the start of a query below which gives me dependencies of a particular table:
SELECT DISTINCT OBJECT_NAME(object_id) AS referencing_object_name
FROM sys.sql_dependencies
WHERE referenced_major_id = OBJECT_ID('TABLE_NAME_HERE')
But is there a way to alter this to show:
1) The above with a column with tablename being populated
2) The above relating to ALL tables within a set database (not just a single table as the original query shows)
3) All results on a single row
Final output looking like image below:
screenshotoffinalquery
.
.
.
EDIT:
I seem to be very close with this, but last column is duplicating a single result
SELECT DISTINCT b.name, a.referenced_major_id, b.object_id,
substring((
SELECT ' || ' +OBJECT_NAME(a.object_id)
FROM sys.sql_dependencies a JOIN sys.tables b ON a.referenced_major_id = b.object_id
For XML PATH ('')
), 2, 1000) AS [TextLine]
FROM sys.sql_dependencies a JOIN sys.tables b ON a.referenced_major_id = b.object_id
ORDER BY b.name ASC

How to replace NULL value in select with subquery

Hi I'm performing a left join on two tables. If a particular column is NULL I want to run a subquery to get a value from a completely different table. Here's what I have now:
SELECT A.ACCOUNT_NUM, A.USER_ID,
CASE B.PREFERRED_NAME
WHEN '' THEN RTRIM(B.FIRST_NAME) || ' ' || B.LAST_NAME
ELSE RTRIM(B.PREFERRED_NAME) || ' ' || B.LAST_NAME
END AS NAME
FROM TABLE_A A
LEFT JOIN TABLE_B B
ON A.USER_ID = B.USER_ID
TABLE_B sometimes doesn't contain a record that matches with TABLE_A, so I want to run a subquery from TABLE_C that contains usernames and will match on A.USER_ID.
I thought I could do something like:
CASE B.PREFERRED_NAME
WHEN NULL THEN subquery here
But I get this error:
ERROR [42703] [IBM][DB2] SQL0206N "NULL" is not valid in the context where it is used.
Probably because NULLs are not allowed for that column.
SOLVED
Thanks for the help. This is how I solved my issue:
SELECT A.ACCOUNT_NUM, A.USER_ID,
CASE
WHEN B.PREFERRED_NAME IS NULL THEN C.USER_ID
WHEN B.PREFERRED_NAME IS NOT NULL THEN
CASE PREFERRED_NAME
WHEN '' THEN RTRIM(B.FIRST_NAME) || ' ' || B.LAST_NAME
ELSE RTRIM(B.PREFERRED_NAME) || ' ' || B.LAST_NAME
END
END AS NAME
FROM TABLE_A A
LEFT JOIN TABLE_B B
ON A.USER_ID = B.USER_ID
JOIN TABLE_C C
ON A.USER_ID = C.USER_ID
Depending on your query, you can probably just add your third table as another LEFT JOIN, then add the column you want to a COALESCE function:
Also, it looks like you're storing the preferred name as spaces if there isn't one, in which case you can use the NULLIF function to convert it to a NULL, which will work with your COALESCE.
Here's an example of what I mean:
SELECT
A.ACCOUNT_NUM
,A.USER_ID
,COALESCE(
NULLIF(B.PREFERRED_NAME,'')
,B.FIRST_NAME
,C.OTHER_NAME
) || ' ' || B.LAST_NAME AS NAME
FROM TABLE_A A
LEFT JOIN TABLE_C C
ON C.USER_ID = A.USER_ID
LEFT JOIN TABLE_B B
ON A.USER_ID = B.USER_ID
If you know there is always going to be a row in C that matches A, then you could convert that to a regular (inner) JOIN.
The reason you're getting the error, though is because you can't use NULL like that in a CASE statement. If you want to have a NULL case, then you have to do it like #Abecee said in the comment with CASE WHEN B.PREFERRED_NAME IS NULL THEN ...

Find all tables with a field containing xml string values

I have an SQL 2005 database and I know that in the database there is a table which has got some xml strings in it. How can I find this table(s)?
If the fields are actually of type XML, then this query will give you what you're looking for:
select * from information_schema.columns
where DATA_TYPE = 'XML'
Marc
Run this:
select 'select distinct ''' || a.name || '.' || b.name
|| ''' from ' || b.name
|| 'where ' || b.name || ' like ''%<%/>%'' union '
from systable a
join syscolumns b on (a.id = b.id)
join systypes c on (b.type = c.xtype)
where a.type ='U' and c.name = ('CHAR', 'CHARN', 'VARCHAR', 'VARCHARN');
The first result set will have one row per character column in the database:
select distinct 'table.column' from table where column like '%<%/>%' union
Take that resultset, snip off the last union, and run the resultset as a SQL statement. It'll bring back the table name and column name for any column that has one or more rows that look XML-ish.
Edit: this is from memory; the join to systypes and the type names may be wrong, so select from systypes and check.