I am trying to update a column based on virtual dataset created via a WITH statement. I have simplified the statement as much as possible to get to the root issue. It appears that UPDATE does not work when using a WITH statement, but I can't believe this is accurate. The error I am getting is
ORA-00928: missing SELECT keyword
Here is my SQL statement.
with TEMP1 as (
select NN_NAME
from SMB.ACCOUNTS
)
update SALES_PLAY_MATRIX_WORKING
set FY16_FOCUS = 'Y' where NN_NAME in ( select TEMP1.NN_NAME from TEMP1)
If I convert the 2nd portion of the statement to just a pure SELECT, it works...
with TEMP1 as (
select NN_NAME
from SMB.ACCOUNTS
)
(
select TEMP1.NN_NAME
from TEMP1)
In Oracle, with does not go just at the beginning of a query. It can go before any select. So:
update SALES_PLAY_MATRIX_WORKING
set FY16_FOCUS = 'Y'
where NN_NAME in (
with TEMP1 as (
select NN_NAME
from SMB.ACCOUNTS
)
select TEMP1.NN_NAME
from TEMP1
);
I will suggest go for nested query that may solve your issue
UPDATE SALES_PLAY_MATRIX_WORKING
SET FY16_FOCUS = 'Y'
WHERE NN_NAME IN ( SELECT NN_NAME FROM SMB.ACCOUNTS)
You could use a merge statement:
MERGE INTO SALES_PLAY_MATRIX_WORKING dst
USING ( SELECT NN_NAME FROM SMB.ACCOUNTS ) src
ON ( dst.NN_NAME = src.NN_NAME )
WHEN MATCHED THEN
UPDATE SET FY16_FOCUS = 'Y';
or more simply:
MERGE INTO SALES_PLAY_MATRIX_WORKING dst
USING SMB.ACCOUNTS src
ON ( dst.NN_NAME = src.NN_NAME )
WHEN MATCHED THEN
UPDATE SET FY16_FOCUS = 'Y';
Related
I am trying to update the one field in the final table. i have logic down here. I have to update the last_version_flag when it meets certain scenario. how to use WITH CTE concept in snowflake. thank you in advance.
update dw.tb_fidctp_order
set last_version_flag = 'N'
from dw.tb_fidctp_order
where (with my_cte as (
select order_id, MAX(cast(VERSION as NUMBER(18,0))) as max_version
from stg.tb_fidctp_order_input
group by order_id))
DW.tb_fidctp_order.order_id = my_cte.order_id and DW.tb_fidctp_order.version < my_cte.max_version
The correct syntax is UPDATE target_table
SET col_name = value
FROM additional_tables
WHERE condition :
CREATE TABLE tb_fidctp_order(version INT, order_id INT, last_version_flag TEXT);
CREATE TABLE tb_fidctp_order_input(version INT,order_id INT, last_version_flag TEXT);
update tb_fidctp_order
set last_version_flag = 'N'
from (
WITH cte AS (
select order_id, MAX(cast(VERSION as NUMBER(18,0))) as max_version
from tb_fidctp_order_input
group by order_id
)
SELECT * FROM cte
) AS my_cte
where tb_fidctp_order.order_id = my_cte.order_id
and tb_fidctp_order.version < my_cte.max_version;
I'm trying to do an update using data from another table. I've tried this answer (the second part), but it is not working for me. I'm receiving a generic error message of syntax error.
I've also tried this solution and received a syntax error message too.
If I try to update just one column, it works:
UPDATE dogs
SET name =
(
SELECT 'Buddy'
FROM systables
WHERE tabid = 1
);
But I need to update multiples columns. Unfortunately, this is not working:
UPDATE dogs
SET (name, breed) =
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
);
Informix version is 12.10.FC8
You are missing 1 more set of parentheses around the subquery.
From the Informix manual:
The subquery must be enclosed between parentheses. These parentheses
are nested within the parentheses that immediately follow the equal (
= ) sign. If the expression list includes multiple subqueries, each subquery must be enclosed between parentheses, with a comma ( , )
separating successive subqueries:
UPDATE ... SET ... = ((subqueryA),(subqueryB), ... (subqueryN))
The following examples show the use of subqueries in the SET clause:
UPDATE items
SET (stock_num, manu_code, quantity) =
(
(
SELECT stock_num, manu_code
FROM stock
WHERE description = 'baseball'
),
2
)
WHERE item_num = 1 AND order_num = 1001;
UPDATE table1
SET (col1, col2, col3) =
(
(
SELECT MIN (ship_charge), MAX (ship_charge)
FROM orders
),
'07/01/2007'
)
WHERE col4 = 1001;
So in order for your update to be accepted by Informix it has to be:
UPDATE dogs
SET (name, breed) =
(
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
)
);
I have the following table:
CREATE TABLE t_overview
(
obj_uid uuid,
obj_parent_uid uuid,
obj_no integer,
obj_text text,
obj_path text,
isdir integer,
intid bigint,
intparentid bigint
)
I want to move from uuid to bigint and created the new columns intid and intparentid. I need a unique integer (obj_uid is the primary key) for intid, so I just wanted to update with row_number() over (order by ...).
Did not seem to work. So I tried to write the results into a temp table, and update via join. But I got 1 for every intid.
But when I select from the join where I do the update, I get 1, 2, 3, 4, 5, 6 etc. What am I missing?
DROP TABLE IF EXISTS mytable;
CREATE TEMP TABLE mytable AS
WITH CTE AS
(
SELECT obj_uid, obj_parent_uid, obj_no
, obj_text, obj_path, isdir
, intid as cteIntId
, intparentid as cteParentId
, row_number() over (order by obj_uid) as rn
FROM T_Overview
)
SELECT * FROM CTE;
UPDATE T_Overview SET intid = mytable.rn
FROM T_Overview AS bt
INNER JOIN mytable
ON mytable.obj_uid = bt.obj_uid
-- UPDATE T_Overview SET intid = CTE.rn FROM CTE;
-- UPDATE T_Overview SET intparentid = CTE.intid FROM CTE;
#Frank already provided an explanation for your error.
But you don't need the temporary table at all:
BEGIN;
LOCK T_Overview; -- if there is concurrent write access
WITH cte AS (
SELECT obj_uid, obj_parent_uid
, row_number() OVER (ORDER BY obj_uid) AS intid
FROM T_Overview
)
UPDATE T_Overview t
SET intid = upd.intid
, intparentid = upd.intparentid
FROM (
SELECT t1.*, t2.intid AS intparentid
FROM cte t1
LEFT JOIN cte t2 ON t2.obj_uid = t1.obj_parent_uid
) upd
WHERE t.obj_uid = upd.obj_uid;
COMMIT;
The transaction wrapper and the explicit lock are only needed if there can be concurrent write access. (Even more so with a temp table, where you have a much bigger time slot in between.)
Assuming referential integrity - a FK constraint from T_Overview.obj_parent_uid to T_Overview.obj_uid. NULL values in obj_parent_uid are translated to NULL in intparentid.
Your update is wrong, there is no relation between T_Overview and (T_Overview + mytable).
This one should work:
UPDATE T_Overview SET intid = mytable.rn
FROM mytable
WHERE mytable.obj_uid = T_Overview.obj_uid;
Offtopic: Your CTE doesn't make much sense, a plain SELECT would give you the same results.
I'm new in this site and I have another question. In this case, it is from Oracle SQL, Insert operation with a CASE.
My SQL insert's code is:
INSERT WHEN (SELECT TB0083_DS_TIPODISPOSITIVO FROM TB0083_TIPODISPOSITIVO WHERE TB0083_ID_TIPODISPOSITIVO = (SELECT FOR_DISPOSITIVO FROM TFORPD01 WHERE FOR_CODIGO = &FORNECEDOR))='TIV' THEN
INTO TTRAPD01 (TRA_CODIGO,TRA_CODBARRA,TRA_CODLOC,TRA_CODCON,TRA_DATLOC,TRA_CODCAIXA,TRA_STATCOND,TRA_DT_CRIACAO,TRA_NM_USUARIOCRIACAO,TRA_DT_ALTERACAO,TRA_NM_USUARIOALTERACAO,TRA_CD_CONTA,TRA_CODCTR,TRA_TRANSACAO_ONLINE,TRA_TIV_HEXA,TRA_TIV_BINARIO,TRA_CD_DISPOSITIVO,TRA_DATSINC,TRA_ID_TPSEGREG,TRA_FORNECEDOR,TRA_STATUS)
VALUES (&NUMEROIDENTIFICADOR,&CODIGOBARRAIDENTIFICADOR,&CODIGOPONTOVENDALARM,259,SYSDATE,&CODIGOCAIXA,0,SYSDATE,&USUARIOLOGUEADO,SYSDATE,&USUARIOLOGUEADO,422,1,0,&TIVHEXA,&TIVBINARIO,423,SYSDATE,3,&FORNECEDOR,1)
ELSE
INTO TTRAPD01 (TRA_CODIGO,TRA_CODBARRA,TRA_CODLOC,TRA_CODCON,TRA_DATLOC,TRA_CODCAIXA,TRA_STATCOND,TRA_DT_CRIACAO,TRA_NM_USUARIOCRIACAO,TRA_DT_ALTERACAO,TRA_NM_USUARIOALTERACAO,TRA_CD_CONTA,TRA_CODCTR,TRA_TRANSACAO_ONLINE,TRA_TIV_HEXA,TRA_TIV_BINARIO,TRA_CD_DISPOSITIVO,TRA_DATSINC,TRA_ID_TPSEGREG,TRA_FORNECEDOR,TRA_STATUS)
VALUES (&NUMEROIDENTIFICADOR,&CODIGOBARRAIDENTIFICADOR,&CODIGOPONTOVENDALARM,259,SYSDATE,&CODIGOCAIXA,0,SYSDATE,&USUARIOLOGUEADO,SYSDATE,&USUARIOLOGUEADO,422,1,0,&TIVHEXA,&TIVBINARIO,423,SYSDATE,2,&FORNECEDOR,1);
This script doesn't found.
I need to fix it, because I need to change the value of field TRA_ID_TPSEGREG depends on the value of:
SELECT TB0083_DS_TIPODISPOSITIVO FROM TB0083_TIPODISPOSITIVO WHERE TB0083_ID_TIPODISPOSITIVO = (SELECT FOR_DISPOSITIVO FROM TFORPD01 WHERE FOR_CODIGO = &FORNECEDOR)
If value is 'TIV' then it inserts 3 in that position, else it inserts 2 in those field.
Thanks!!
There's PL/SQL INSERT WHEN command:
Try this:
INSERT FIRST
WHEN TB0083_DS_TIPODISPOSITIVO = 'TIV' THEN
INTO TTRAPD01
(
<COLUMN_NAME1>,<COLUMN_NAME2>......
)
VALUES
(
<COLUMN_VALUE1>,<COLUMN_VALUE2>.....
)
ELSE
INTO TTRAPD01
(
<COLUMN_NAME1>,<COLUMN_NAME2>......
)
VALUES
(
<COLUMN_VALUE1>,<COLUMN_VALUE2>.....
)
SELECT TB0083_DS_TIPODISPOSITIVO
FROM TB0083_TIPODISPOSITIVO
WHERE TB0083_ID_TIPODISPOSITIVO =
(SELECT FOR_DISPOSITIVO FROM TFORPD01 WHERE FOR_CODIGO = &FORNECEDOR
);
For eg:
CREATE TABLE TEST ( ID NUMBER);
INSERT FIRST
WHEN dummy = 'Y' THEN
INTO TEST
VALUES(222)
ELSE
INTO TEST
VALUES(555)
select dummy from dual;
The above query will insert 1 ROW on the very first condition satisfy. See more: >>here<<
I have a SQL select statement which is comparing two tables. I am getting the values where the rows are the same. Now I have got this in the procedure I need to add these into a new table (coftReconciliationMatches). The table has all the same columns but one additional one 'MatchOrNoMatch'. I need to pass through the values of the row that are matched and also need to pass through 'Match' to the column 'MatchOrNoMatch'
This is the current part of the SQL script I have;
SELECT *
FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS (SELECT *
FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK
AND a.ExtRef1 = b.ExtRef1
AND a.SedolRef = b.SedolRef
AND a.ValLatest = b.ValLatest
AND a.Totunits = b.Totunits
AND a.FundsOrCash = b.FundsOrCash )
When comparing a lot of columns, the SELECT INTERSECT and SELECT EXCEPT commands can save you a lot of effort:
INSERT dbo.coftReconcilliationMatches
(Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, MatchOrNoMatch)
select Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, 'Match'
from dbo.coftReconciliationFileInfo
intersect select Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, 'Match'
from dbo.coftPreReconciliationFileInfo
(Check for typos!)
If you are creating the table on the fly (something I wouldn't recommend doing), you'd use SELECT INTO.
INSERT INTO [table] ([col1], [col2]) SELECT colx, ...
Use Select Into for this. See here http://www.w3schools.com/sql/sql_select_into.asp
Try something like:
INSERT INTO <your table> (<list of columns>)
SELECT <list of columns from select>, '<the additional column>' FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS(SELECT * FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK AND a.ExtRef1 = b.ExtRef1 AND a.SedolRef = b.SedolRef AND a.ValLatest = b.ValLatest AND a.Totunits = b.Totunits AND a.FundsOrCash = b.FundsOrCash )
also see http://www.1keydata.com/sql/sqlinsert.html
you need to do:
INSERT INTO Table (column1, column2..)
(SELECT column1, column2 ....
FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS (SELECT *
FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK
AND a.ExtRef1 = b.ExtRef1
AND a.SedolRef = b.SedolRef
AND a.ValLatest = b.ValLatest
AND a.Totunits = b.Totunits
AND a.FundsOrCash = b.FundsOrCash ))