У меня есть процедура, которая выполняет INSERT INTO
, а затем UPDATE
некоторых полей (как в одной процедуре), я использую этот ответ от @Clive Количество строк, затронутых ОБНОВЛЕНИЕМ в PL / SQL, чтобы узнать количество данных, которые были обновлены для помещения в журнал, но он дает мне общее количество строк, а не только записи, которые были обновлены.
Это что правильный способ узнать?
Мне нужно знать, сколько строк было ВСТАВЛЕНО из INSERT STATEMENT
и сколько строк было ОБНОВЛЕНО из UPDATE STATEMENT
.
Мой запрос:
CREATE OR REPLACE PROCEDURE OWNER.TABLE_NAME
AS
-- VARIABLE
v_qtd_regs number := 0;
v_code number;
v_errm VARCHAR2(500);
start_time pls_integer;
end_time pls_integer;
elapse_time number;
proc_name varchar2(100);
i NUMBER;
BEGIN
proc_name := 'PRDWBI_CGA_D_COLUMNS';
start_time := dbms_utility.get_time;
DS_FUNCESP.PRDSBI_GRAVA_LOG( 'I', 'DataWarehouse', proc_name, 'Início Carga' );
-- INSERT INTO TABLE:
INSERT INTO OWNER.TABLE_NAME
(COLUMN_ID, COLUMNS_NAME, COLUMN_NAME2)
(SELECT 1 AS COLUMN_ID, 'TEST' AS COLUMN_NAME, SYSDATE AS COLUMN_NAME2 FROM DUAL);
COMMIT;
-- UPDATE SOME COLUMNS I NEED
UPDATE OWNER.TABLE_NAME y
SET (y.COLUMNS_NAME, y.COLUMN_NAME2) =
(SELECT 'TEST2' AS COLUMN_NAME, SYSDATE AS COLUMN_NAME2 FROM DUAL x WHERE x.COLUMN_ID = y.COLUMN_ID)
WHERE EXISTS (SELECT 'TEST2' AS COLUMN_NAME, SYSDATE AS COLUMN_NAME2 FROM DUAL x WHERE x.COLUMN_ID = y.COLUMN_ID);
-- TO KNOW HOW MANY ROWS WERE UPDATED
i := SQL%rowcount;
COMMIT;
--dbms_output.Put_line(i);
SELECT COUNT(1) INTO v_qtd_regs FROM OWNER.TABLE_NAME where LinData >= TRUNC(SYSDATE);
end_time := dbms_utility.get_time;
elapse_time := ((end_time - start_time)/100);
v_errm := SUBSTR(SQLERRM, 1 , 500);
DS_FUNCESP.PRDSBI_GRAVA_LOG('T', 'DataWarehouse', proc_name, v_errm, v_qtd_regs, elapse_time );
COMMIT;
EXCEPTION
WHEN OTHERS THEN
v_code := SQLCODE;
v_errm := SUBSTR(SQLERRM, 1 , 500);
DS_FUNCESP.PRDSBI_GRAVA_LOG('E', 'Error', proc_name, v_errm);
END;
ВОПРОС ИЗМЕНЕНО, ЧТОБЫ ПОКАЗАТЬ НАСТОЯЩИЙ ПРИМЕР:
Я создал таблицу, которая берет данные из «SYS.DBA_TAB_COLUMNS» просто для использования в качестве пример, как показано ниже:
CREATE TABLE "DW_FUNCESP"."D_TEST"
(
"ID_COLUMN" NUMBER(10,0) GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1
START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE,
"NM_OWNER" VARCHAR2(500 CHAR) NOT NULL ENABLE ,
"NM_TABLE" VARCHAR2(500 CHAR) NOT NULL ENABLE ,
"CD_COLUMN" NUMBER(20,0) NOT NULL ENABLE ,
"NM_COLUMN" VARCHAR2(500 CHAR) NOT NULL ENABLE ,
"DS_COLUMN" VARCHAR2(500 CHAR) NOT NULL ENABLE ,
"LINDATE" DATE DEFAULT SYSDATE NOT NULL ENABLE ,
"LINORIGIN" VARCHAR2(100 CHAR) NOT NULL ENABLE
)
Затем я создал процедуру для идентификации вставленных и обновленных записей, как показано ниже:
CREATE OR REPLACE PROCEDURE DW_FUNCESP.PRDWBI_CGA_D_TEST
AS
-- variaveis de suporte as informações que deve gravar
rows_inserted integer;
rows_updated integer;
BEGIN
-- Insert Into table
INSERT INTO DW_Funcesp.D_TEST
(NM_OWNER, NM_TABLE, CD_COLUMN, NM_COLUMN, DS_COLUMN, LINDATE, LINORIGIN)
(SELECT
NVL(x.NM_OWNER ,'NOT FOUND') AS NM_OWNER ,
NVL(x.NM_TABLE ,'NOT FOUND') AS NM_TABLE ,
NVL(x.CD_COLUMN ,-1) AS CD_COLUMN ,
NVL(x.NM_COLUMN ,'NOT FOUND') AS NM_COLUMN ,
NVL(x.DS_COLUMN ,x.NM_COLUMN) AS DS_COLUMN ,
SYSDATE AS LINDATE ,
'SYS.DBA_TAB_COLUMNS' AS LINORIGIN
FROM
(
SELECT
d.OWNER AS NM_OWNER ,
d.TABLE_NAME AS NM_TABLE ,
d.COLUMN_ID AS CD_COLUMN,
d.COLUMN_NAME AS NM_COLUMN,
e.COMMENTS AS DS_COLUMN
FROM SYS.DBA_TAB_COLUMNS d
LEFT JOIN SYS.DBA_COL_COMMENTS e
ON e.OWNER = d.OWNER
AND e.TABLE_NAME = d.TABLE_NAME
AND e.COLUMN_NAME = d.COLUMN_NAME
WHERE d.OWNER = 'DW_FUNCESP'
) x
LEFT JOIN DW_FUNCESP.D_TEST y
ON y.NM_OWNER = x.NM_OWNER
AND y.NM_TABLE = x.NM_TABLE
AND y.NM_COLUMN = x.NM_COLUMN
WHERE y.ID_COLUMN IS NULL);
rows_inserted := sql%rowcount;
-- Update the table
UPDATE DW_FUNCESP.D_TEST z
SET (z.NM_COLUMN, z.DS_COLUMN, z.LINDATE) =
(SELECT
NVL(x.NM_COLUMN ,'NOT FOUND') AS NM_COLUMN ,
NVL(x.DS_COLUMN ,x.NM_COLUMN) AS DS_COLUMN ,
SYSDATE AS LINDATE
FROM
(
SELECT
d.OWNER AS NM_OWNER ,
d.TABLE_NAME AS NM_TABLE ,
d.COLUMN_ID AS CD_COLUMN,
d.COLUMN_NAME AS NM_COLUMN,
e.COMMENTS AS DS_COLUMN
FROM SYS.DBA_TAB_COLUMNS d
LEFT JOIN SYS.DBA_COL_COMMENTS e
ON e.OWNER = d.OWNER
AND e.TABLE_NAME = d.TABLE_NAME
AND e.COLUMN_NAME = d.COLUMN_NAME
WHERE d.OWNER = 'DW_FUNCESP'
) x
WHERE z.NM_OWNER = x.NM_OWNER
AND z.NM_TABLE = x.NM_TABLE
AND z.CD_COLUMN = x.CD_COLUMN)
WHERE EXISTS (SELECT
NVL(x.NM_COLUMN ,'NOT FOUND') AS NM_COLUMN ,
NVL(x.DS_COLUMN ,x.NM_COLUMN) AS DS_COLUMN ,
SYSDATE AS LINDATE
FROM
(
SELECT
d.OWNER AS NM_OWNER ,
d.TABLE_NAME AS NM_TABLE ,
d.COLUMN_ID AS CD_COLUMN,
d.COLUMN_NAME AS NM_COLUMN,
e.COMMENTS AS DS_COLUMN
FROM SYS.DBA_TAB_COLUMNS d
LEFT JOIN SYS.DBA_COL_COMMENTS e
ON e.OWNER = d.OWNER
AND e.TABLE_NAME = d.TABLE_NAME
AND e.COLUMN_NAME = d.COLUMN_NAME
WHERE d.OWNER = 'DW_FUNCESP'
) x
WHERE z.NM_OWNER = x.NM_OWNER
AND z.NM_TABLE = x.NM_TABLE
AND z.CD_COLUMN = x.CD_COLUMN);
rows_updated := sql%rowcount;
dbms_output.Put_line('inserted=>' || to_char(rows_inserted) || ', updated=>' || to_char(rows_updated));
COMMIT;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
Итак, мой первый вывод вставки был:
вставлено => 2821, обновлено => 2821
Итак, я выбрал данные для ча nged, и он был обновлен, я сделал следующий выбор, чтобы выбрать, какие данные следует обновить, чтобы снова ввести вывод СУБД:
SELECT * FROM DW_FUNCESP.D_TEST WHERE NM_TABLE = 'D_TEST';
![Data origin](https://i.stack.imgur.com/jJxEV.png)
Я прокомментировал в столбце, как показано на изображении, чтобы внести обновление:
COMMENT ON COLUMN DW_FUNCESP.D_TEST.LINORIGIN IS 'The origin of the data';
Я снова запустил процедуру, и результат был:
вставлено => 0 , updated => 2821
Результат для этого обновления:
![Result](https://i.stack.imgur.com/cQdBd.png)
Разве вы не принесли только 1 обновление данные на выходе, как только 1 обновлено? И не все строки?
например: вставлено => 0, обновлено => 1
Итак, мой вопрос остается, я его задаю правильно? Можно ли получить такой результат такой же процедурой? Это неправильное обновление (несмотря на обновление данных)?