equivalent to INSERT INTO TABLE SET in Oracle - oracle11g

I want to add data to table STATISTICS using INSERT statements.
I also want to move new counts to old counts and new date to old date as the new data comes in.
This is where it gets lil tricky because I don't know if there is such a thing as INSERT INTO table with SET in Oracle.
INSERT INTO STATISTICS
SET
MODEL = '&MY_MODEL',
NEW_COUNT =
(
SELECT COUNT(*)
FROM TABLE CLIENTS
),
NEW_DATE = SYSDATE,
OLD_COUNT = NEW_COUNT,
OLD_DATE = NEW_DATE,
PRNCT_CHANGE = ((NEW_COUNT) - (OLD_COUNT)) / (NEW_COUNT)*100
);
How do I accomplish this in Oracle?

This should upsert statistics, adding new ones as you go. It presumes a unique key on MODEL; if that's not true, then you'd have to do inserts as Angelina said, getting only the most recent row for a single MODEL entry.
MERGE INTO STATISTICS tgt
using (SELECT '&MY_MODEL' AS MODEL,
(SELECT COUNT(*) FROM CLIENTS) AS NEW_COUNT,
SYSDATE AS DATE_COUNT,
NULL AS OLD_COUNT,
NULL OLD_DATE,
NULL AS PRCNT_CHANGE
FROM DUAL) src
on (TGT.MODEL = SRC.MODEL)
WHEN MATCHED THEN UPDATE
SET TGT.NEW_COUNT = SRC.NEW_COUNT,
TGT.NEW_DATE = SRC.NEW_DATE,
TGT.OLD_COUNT = TGT.NEW_COUNT,
TGT.OLD_DATE = TGT.NEW_DATE,
TGT.PRCNT_CHG = 100 * (SRC.NEW_COUNT - TGT.NEW_COUNT) / (SRC.NEW_COUNT)
-- NEEDS DIV0/NULL CHECKING
WHEN NOT MATCHED THEN INSERT
(MODEL, NEW_COUNT, NEWDATE, OLD_COUNT, OLD_DATE, PRCNT_CHANGE)
VALUES
(src.MODEL, src.NEW_COUNT, src.NEWDATE, src.OLD_COUNT, src.OLD_DATE, src.PRCNT_CHANGE);

INSERT INTO STATISTICS(MODEL,NEW_COUNT,NEW_DATE,OLD_COUNT,OLD_DATE,PRNCT_CHANGE)
SELECT MODEL,
( SELECT COUNT(*)
FROM TABLE(USERS)
),
SYSDATE,
NEW_COUNT,
NEW_DATE,
(((NEW_COUNT) - (OLD_COUNT)) / (NEW_COUNT)*100)
FROM SEMANTIC.COUNT_STATISTICS
WHERE MODEL = '&MY_MODEL'
AND trunc(NEW_DATE) = trunc(NEW_DATE -1)
;

Related

SQLite UPDATE only one record matching a WHERE clause, with MAX on another filed

Need to modify the data in an SQLite database that has fields similar to:
hash (string)
modTime (long, time in ms)
data (any data, e.g. string)
I know the hash value of the record to set the data for (it's really xxHash of some binary blob). There can be several records with the same hash, but I need to modify only the one with MAX(modTime) value with the matching hash... Can't figure out how to construct the UPDATE command.
You can use NOT EXISTS in the WHERE clause:
UPDATE tablename
SET data = new_data
WHERE hash = ?
AND NOT EXISTS (SELECT 1 FROM tablename t WHERE t.hash = tablename.hash AND t.modTime > tablename.modTime)
Or use the column rowid to find the row that you want to update:
UPDATE tablename
SET data = new_data
WHERE rowid = (SELECT rowid FROM tablename WHERE hash = ? ORDER BY modTime DESC LIMIT 1)
or with FIRST_VALUE() window function:
UPDATE tablename
SET data = new_data
WHERE rowid = (SELECT DISTINCT FIRST_VALUE(rowid) OVER (ORDER BY modTime DESC) FROM tablename WHERE hash = ?)
Replace new_data with the new value of data and ? with the value of hash you search for.

PLSQL Procedure to load data into dimension table from multiple tables

I have a requirement to load distinct costcenternum and a seq_key to be inserted. I wrote a procedure but this is failing one is distinct and even after removing distinct not able to run this procedure.
Please help me to correct this query to generate a seq key and also distinct cost numbers into the division table.
CREATE OR REPLACE
PROCEDURE POPULATE_DIVISION_DIM AS
BEGIN
INSERT INTO DIVISION(
"COST_CENTER_KEY"
,"COST_CENTER_NUM"
,"COST_CENTER_DESC"
,"DIVISION_CODE"
,"DIVISION_DESC"
,"COMPANY_CODE"
,"INSERT_DT"
,"UPDATE_DT"
)
(
SELECT
cc_sequence.nextval cost_center_key
, distinct (pcaf.segment4) costcenter_num
,ffvv.description costcenter_desc
,hoi.org_information9 division
,(SELECT description
FROM hr_lookups
WHERE lookup_type = 'CAT'
AND lookup_code = hoi.org_information9)
division_desc
, ppg.segment1 company
,TRUNC(SYSDATE) insert_dt
,TRUNC(SYSDATE) update_dt
FROM
hr_organization_information hoi
, hr_all_organization_units haou
, pay_cost_allocation_keyflex pcaf
, fnd_flex_values_vl ffvv
, per_all_assignments_f paaf
, pay_people_groups ppg
WHERE 1=1
AND paaf.people_group_id = ppg.people_group_id
AND haou.cost_allocation_keyflex_id =
pcaf.cost_allocation_keyflex_id(+)
AND pcaf.segment4 = ffvv.flex_value(+)
AND (ffvv.FLEX_VALUE_SET_ID is null or ffvv.FLEX_VALUE_SET_ID=
(SELECT FLEX_VALUE_SET_ID FROM FND_FLEX_VALUE_SETS WHERE
FLEX_VALUE_SET_NAME = 'ABCD'))
AND ffvv.enabled_flag(+) = 'Y'
AND haou.organization_id = hoi.organization_id
AND hoi.org_information_context = 'XX'
)
;
COMMIT;
END POPULATE_DIVISION_DIM;

How to segregate a stored procedure into a table row by row?

There is a stored procedure which contains many insert, update, delete and truncate statements. I want to group all the statements one by one into a table.
For example:
create proc Get_Tables as
begin
UPDATE BB_FMCTransactionsTwo SET wsTradeDate = wsSettleDate WHERE wsEntryCode = 'NRT'
UPDATE BB_FMCTransactionsTwo SET wsOK = 1, wsSpecialLogic = SpecialLogic FROM BB_EntryCode INNER JOIN BB_FmcTransactionsTwo ON EntryCode = wsEntryCode
UPDATE BB_FMCTransactionsTwo SET wsFMCFtNt = '' FROM BB_EntryCode INNER JOIN BB_FmcTransactionsTwo ON EntryCode = wsEntryCode WHERE wsBS <> 'B' AND ( FMCFtNtB IS NULL OR FMCFtNtB = 'PR' )
UPDATE BB_B204_Tran SET AMOUNT = dbo.BCA_AMT(Desc1, Desc2, Desc3, Udesc1, Udesc2, Udesc3) WHERE TRANIND = 14 AND PORTTYPE IN (2,3)
DELETE BB_B204_Tran WHERE TRANIND = 14 AND PORTTYPE IN(2,3) AND (Quantity IS NULL OR ISNUMERIC(Quantity) = 0 OR Quantity = -1 OR ISNUMERIC(AMOUNT) = 0
end
Required:
I want to insert the update statements, delete statements into a table one by one...
Create a stored procedure which divides the stored procedure based on type of statements (Insert, Update, Truncate) and inserts that into a table row by row. So that the table looks like below.
Table:
Sl.No Statement
1 UPDATE BB_FMCTransactionsTwo SET wsTradeDate = wsSettleDate WHERE wsEntryCode = 'NRT'
2 DELETE BB_B204_Tran WHERE TRANIND = 14 AND PORTTYPE IN(2,3)
I have implemented for your first update statement and assume that your AuditTable will have one column SQLData and so you need to store these SQL Statements in your store procedure and if you have used any variable then you need to store into SQL Data variable and insert into Audit Table. it may help you.
declare ##SQL1 varchar(max)
UPDATE BB_FMCTransactionsTwo SET wsTradeDate = wsSettleDate WHERE wsEntryCode = 'NRT'
set ##SQL1 = 'UPDATE BB_FMCTransactionsTwo SET wsTradeDate = wsSettleDate WHERE wsEntryCode = ''NRT'''
insert into AuditTable (SQLData) values(##SQL1)
For Variable:
DECLARE ##wsEntryCode VARCHAR(100)
SET ##wsEntryCode='NRT'
PRINT 'UPDATE BB_FMCTransactionsTwo SET wsTradeDate = wsSettleDate WHERE wsEntryCode = ''' + ##wsEntryCode + ''''
insert into AuditTable (SQLData) values(##SQL1)

single-row subquery returns more than one row .what should i do in such case

UPDATE STG_ABS_DSD_RECEIPTS_PI_WRK1 A
SET
(
RECEIPT_HEADER_KEY,
ORIG_ACNTNG_EFF_DATE,
GL_DEPT_ID,
RECEIPT_DATE,
RECEIPT_TIME,
TOTAL_INVOICE_COST_HDR,
SUM_EXTENDED_COST_AMT
) =
(SELECT
HDR_RECEIPT_HEADER_KEY,
HDR_ORIG_ACNTNG_EFF_DATE,
HDR_GL_DEPT_ID,
HDR_RECEIPT_DATE,
HDR_RECEIPT_TIME,
HDR_SUM_TOTAL_INVOICE_COST,
PIEDW_EXTENDED_COST_AMT
FROM
STG_ABS_DSD_RECEIPTS_PI_WRK4 B
WHERE
A.SUPPLIER_KEY = B.PIEDW_SUPPLIER_KEY
AND
A.STORE_KEY = B.PIEDW_STORE_KEY
AND
RTRIM(LTRIM(A.SUPPLIER_INVOICE_NBR,0)) = RTRIM(LTRIM(B.PIEDW_SUPPLIER_INVOICE_NBR,0))
AND
TO_DATE(A.PIEDW_INV_TRAN_DATE,'YYYYMMDD') = B.PIEDW_INVOICE_DATE
AND
B.HDR_FOUND_FLAG IN ('N', 'MY'))
WHERE EXISTS
(SELECT 1 FROM STG_ABS_DSD_RECEIPTS_PI_WRK4 B
WHERE
A.SUPPLIER_KEY = B.PIEDW_SUPPLIER_KEY
AND
A.STORE_KEY = B.PIEDW_STORE_KEY
AND
RTRIM(LTRIM(A.SUPPLIER_INVOICE_NBR,0)) = RTRIM(LTRIM(B.PIEDW_SUPPLIER_INVOICE_NBR,0))
AND
TO_DATE(A.PIEDW_INV_TRAN_DATE,'YYYYMMDD') = B.PIEDW_INVOICE_DATE
AND
B.HDR_FOUND_FLAG IN ('N', 'MY'));
You should ensure that the subquery only returns the row that you want by providing the correct joins from the table you are updating, or if you just want one row out of many that might be returned then use "WHERE ROWNUM = 1" (or a LIMIT clause in other RDBMSs or Oracle 12c)

Copy a subset of column data from one table to another

I have two tables with identical schema. Let's name them TestTable and TestTableTemp. I need to copy just two columns from TestTableTemp to TestTable without disrupting other data. The rows in TestTable are a subset of those in TestTableTemp. Let's say the columns that I need to copy are named Column1 and Column2 and that they have identical primary keys reference by column primaryKey.
In mysql I believe this could be done as such or something similar:
UPDATE TestTable, TestTableTemp
SET TestTable.Column1 = TestTableTemp.Column1, TestTable.Column2 = TestTableTemp.Column2
WHERE TestTable.primaryKey = TestTableTemp.primaryKey
Sqlite does not allow for multiple tables to be defined on the update statement as can been seen in their reference data here: http://www.sqlite.org/lang_update.html
The best I could come up with is such:
UPDATE TestTable SET
Column1 = (select TestTableTemp.Column1 from TestTableTemp, TestTable where TestTable.primaryKey = TestTableTemp.primaryKey),
Column2 = (select TestTableTemp.Column2 from TestTableTemp, TestTable where TestTable.primaryKey = TestTableTemp.primaryKey)
WHERE EXISTS(select * from TestTableTemp where TestTable.primaryKey = TestTableTemp.primaryKey"
This gives me a syntax error near "." I am guessing this is because I cannot reference TestTable in the scalar expressions.
Can anyone point me in the right direction? Any help is much appreciated.
EDIT:
I cleaned up the second query a bit. It seems to just set the Column1 and Column2 to the first row from that column from TestTableTemp.
Your original query for comparison:
UPDATE TestTable, TestTableTemp
SET TestTable.Column1 = TestTableTemp.Column1
, TestTable.Column2 = TestTableTemp.Column2
WHERE TestTable.primaryKey = TestTableTemp.primaryKey
Here is the working query (I just slightly changed your version):
http://sqlfiddle.com/#!5/f3a19/9
UPDATE TestTable
SET
Column1 = ( SELECT TestTableTemp.Column1
FROM TestTableTemp
WHERE TestTableTemp.primaryKey = TestTable.primaryKey )
,Column2 = ( SELECT TestTableTemp.Column2
FROM TestTableTemp
WHERE TestTableTemp.primaryKey = TestTable.primaryKey )
WHERE EXISTS( SELECT NULL
FROM TestTableTemp
WHERE TestTableTemp.primaryKey = TestTable.primaryKey )
;

Resources