I have a list consisting of: table names, column names.
I need a procedure that can count value_rows and null_rows of each column in each table.
Assume the number of columns of each table may change in the future.
Force to use procedure and display results when calling procedure (don't use DML method to update or create another table)
My idea for this is to use 2 variables in 2 loop: @v_table_name, @v_column_name
create or replace procedure hc_test
as
declare
v_table_name varchar2(255),
v_column_name varchar2(255)
BEGIN
for v_table_name in (select table_name FROM USER_TAB_COLUMNS WHERE table_name IN ('CTHD','HOADON','KHACHHANG','NHANVIEN','SANPHAM')
loop
for v_column_name in (select column_name from USER_TAB_COLUMNS WHERE table_name = v_table_name)
loop
dbms_output.put_line
(
select
@v_table_name as table_name,
@v_column_name as column_name,
count(@v_column_name)as row_num,
count(*) - count(@v_column_name) as null_row
from @v_table_name
)
END;
I know my code is syntax error, but i really dont know how to handle, then I can't finish writing a complete procedure, even though I've searched and watched some videos on youtube it's still hard to do.
Expected output like this: enter image description here
I use PL/SQL Developer 12 software for Oracle database, then it's very difficult to apply code from other programs here.
Your solution will help me so much in increase my skill in Oracle dev,
Thank you so much, and have a nice day.
Below code to create sample table
/* SQLINES DEMO *** le CTHD Script Date: 18/04/2020 1:16:47 PM ******/
CREATE TABLE CTHD(
SOHD Number(10) NOT NULL,
MASP char(4) NOT NULL,
SL Number(10) NULL,
CONSTRAINT pk_cthd PRIMARY KEY
(
SOHD,
MASP
)
) ;
/* SQLINES DEMO *** le HOADON Script Date: 18/04/2020 1:16:47 PM ******/
CREATE TABLE HOADON(
SOHD Number(10) NOT NULL,
NGHD Timestamp NULL,
MAKH char(4) NULL,
MANV char(4) NULL,
TRIGIA Number NULL,
CONSTRAINT pk_hd PRIMARY KEY
(
SOHD
)
) ;
/* SQLINES DEMO *** le KHACHHANG Script Date: 18/04/2020 1:16:47 PM ******/
CREATE TABLE KHACHHANG(
MAKH char(4) NOT NULL,
HOTEN Varchar2(40) NULL,
DCHI Varchar2(50) NULL,
SODT Varchar2(20) NULL,
NGSINH Timestamp NULL,
NGDK Timestamp NULL,
DOANHSO Number NULL,
CONSTRAINT pk_kh PRIMARY KEY
(
MAKH
)
) ;
/* SQLINES DEMO *** le NHANVIEN Script Date: 18/04/2020 1:16:47 PM ******/
CREATE TABLE NHANVIEN(
MANV char(4) NOT NULL,
HOTEN Varchar2(40) NULL,
SODT Varchar2(20) NULL,
NGVL Timestamp NULL,
CONSTRAINT pk_nv PRIMARY KEY
(
MANV
)
) ;
/* SQLINES DEMO *** le SANPHAM Script Date: 18/04/2020 1:16:47 PM ******/
CREATE TABLE SANPHAM(
MASP char(4) NOT NULL,
TENSP Varchar2(40) NULL,
DVT Varchar2(20) NULL,
NUOCSX Varchar2(40) NULL,
GIA Number NULL,
CONSTRAINT pk_sp PRIMARY KEY
(
MASP
)
) ;
INSERT CTHD (SOHD, MASP, SL) SELECT 1001, N'BC01', 5 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1001, N'BC02', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1001, N'ST01', 5 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1001, N'ST08', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1001, N'TV02', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1002, N'BB01', 20 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1002, N'BB02', 20 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1002, N'BC04', 20 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1003, N'BB03', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1004, N'TV01', 20 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1004, N'TV02', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1004, N'TV03', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1004, N'TV04', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1005, N'TV05', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1005, N'TV06', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1006, N'ST01', 30 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1006, N'ST02', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1006, N'TV07', 20 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1007, N'ST03', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1008, N'ST04', 8 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1009, N'ST05', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1010, N'ST04', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1010, N'ST07', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1010, N'ST08', 100 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1010, N'TV03', 100 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1010, N'TV07', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1011, N'ST06', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1012, N'ST07', 3 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1013, N'ST08', 5 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1014, N'BB01', 50 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1014, N'BB02', 100 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1014, N'BC02', 80 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1014, N'BC04', 60 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1015, N'BB02', 30 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1015, N'BB03', 7 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1016, N'TV01', 5 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1017, N'TV02', 1 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1017, N'TV03', 1 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1017, N'TV04', 5 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1018, N'ST04', 6 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1019, N'ST05', 1 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1019, N'ST06', 2 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1020, N'ST07', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1021, N'ST08', 5 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1021, N'TV01', 7 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1021, N'TV02', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1022, N'ST07', 1 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1023, N'ST04', 6 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1024, N'BB05', 10 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1025, N'BC05', 8 FROM dual;
commit;
INSERT CTHD (SOHD, MASP, SL) SELECT 1026, N'BB06', 5 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1001, to_date('2006-07-23 ', 'YYYY-MM-DD'), N'KH01', N'NV01', 320000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1002, to_date('2006-08-12 ', 'YYYY-MM-DD'), N'KH01', N'NV02', 840000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1003, to_date('2006-08-23 ', 'YYYY-MM-DD'), N'KH02', N'NV01', 100000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1004, to_date('2006-09-01 ', 'YYYY-MM-DD'), N'KH02', N'NV01', 180000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1005, to_date('2006-10-20 ', 'YYYY-MM-DD'), N'KH01', N'NV02', 3800000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1006, to_date('2006-10-16 ', 'YYYY-MM-DD'), N'KH01', N'NV03', 2430000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1007, to_date('2006-10-28 ', 'YYYY-MM-DD'), N'KH03', N'NV03', 510000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1008, to_date('2006-10-28 ', 'YYYY-MM-DD'), N'KH01', N'NV03', 440000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1009, to_date('2006-10-28 ', 'YYYY-MM-DD'), N'KH03', N'NV04', 200000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1010, to_date('2006-11-01 ', 'YYYY-MM-DD'), N'KH01', N'NV01', 5200000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1011, to_date('2006-11-04 ', 'YYYY-MM-DD'), N'KH04', N'NV03', 250000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1012, to_date('2006-11-30 ', 'YYYY-MM-DD'), N'KH05', N'NV03', 21000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1013, to_date('2006-12-12 ', 'YYYY-MM-DD'), N'KH06', N'NV01', 5000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1014, to_date('2006-12-31 ', 'YYYY-MM-DD'), N'KH03', N'NV02', 3150000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1015, to_date('2007-01-01 ', 'YYYY-MM-DD'), N'KH06', N'NV01', 910000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1016, to_date('2007-01-01 ', 'YYYY-MM-DD'), N'KH07', N'NV02', 12500.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1017, to_date('2007-01-02 ', 'YYYY-MM-DD'), N'KH08', N'NV03', 35000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1018, to_date('2007-01-13 ', 'YYYY-MM-DD'), N'KH08', N'NV03', 330000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1019, to_date('2007-01-13 ', 'YYYY-MM-DD'), N'KH01', N'NV03', 30000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1020, to_date('2007-01-14 ', 'YYYY-MM-DD'), N'KH09', N'NV04', 70000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1021, to_date('2007-01-16 ', 'YYYY-MM-DD'), N'KH10', N'NV03', 67500.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1022, to_date('2007-01-16 ', 'YYYY-MM-DD'), NULL, N'NV03', 7000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1023, to_date('2007-01-17 ', 'YYYY-MM-DD'), NULL, N'NV01', 330000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1025, to_date('2020-04-17 ', 'YYYY-MM-DD'), N'KH12', N'NV3 ', 800000.0000 FROM dual;
commit;
INSERT HOADON (SOHD, NGHD, MAKH, MANV, TRIGIA) SELECT 1026, to_date('2020-04-17 ', 'YYYY-MM-DD'), N'KH10', N'NV4 ', 500000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH01', N'Nguyen Van A', N'731 Tran Hung Dao, Q5, TpHCM', N'8823451', to_date('1960-10-22 ', 'YYYY-MM-DD'), to_date('2006-07-22 ', 'YYYY-MM-DD'), 13060000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH02', N'Tran Ngoc Han', N'23/5 Nguyen Trai, Q5, TpHCM', N'908256478', to_date('1974-04-03 ', 'YYYY-MM-DD'), to_date('2006-07-30 ', 'YYYY-MM-DD'), 280000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH03', N'Tran Ngoc Linh', N'45 Nguyen Canh Chan, Q1, TpHCM', N'938776266', to_date('1980-06-12 ', 'YYYY-MM-DD'), to_date('2006-05-08 ', 'YYYY-MM-DD'), 3860000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH04', N'Tran Minh Long', N'50/34 Le Dai Hanh, Q10, TpHCM', N'917325476', to_date('1965-03-09 ', 'YYYY-MM-DD'), to_date('2006-02-10 ', 'YYYY-MM-DD'), 250000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH05', N'Le Nhat Minh', N'34 Truong Dinh, Q3, TpHCM', N'8246108', to_date('1950-03-10 ', 'YYYY-MM-DD'), to_date('2006-10-28 ', 'YYYY-MM-DD'), 21000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH06', N'Le Hoai Thuong', N'227 Nguyen Van Cu, Q5, TpHCM', N'8631738', to_date('1981-12-31 ', 'YYYY-MM-DD'), to_date('2006-11-24 ', 'YYYY-MM-DD'), 915000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH07', N'Nguyen Van Tam', N'32/3 Tran Binh Trong, Q5, TpHCM', N'916783565', to_date('1971-04-06 ', 'YYYY-MM-DD'), to_date('2006-01-12 ', 'YYYY-MM-DD'), 12500.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH08', N'Phan Thi Thanh', N'45/2 An Duong Vuong, Q5, TpHCM', N'938435756', to_date('1971-01-10 ', 'YYYY-MM-DD'), to_date('2006-12-13 ', 'YYYY-MM-DD'), 365000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH09', N'Le Ha Vinh', N'873 Le Hong Phong, Q5, TpHCM', N'8654763', to_date('1979-09-03 ', 'YYYY-MM-DD'), to_date('2007-01-14 ', 'YYYY-MM-DD'), 70000.0000 FROM dual;
commit;
INSERT KHACHHANG (MAKH, HOTEN, DCHI, SODT, NGSINH, NGDK, DOANHSO) SELECT N'KH10', N'Ha Duy Lap', N'34/34B Nguyen Trai, Q1, TpHCM', N'8768904', to_date('1983-05-02 ', 'YYYY-MM-DD'), to_date('2007-01-16 ', 'YYYY-MM-DD'), 67500.0000 FROM dual;
commit;
INSERT NHANVIEN (MANV, HOTEN, SODT, NGVL) SELECT N'NV01', N'Nguyen Nhu Nhut', N'927345678', to_date('2006-04-13 ', 'YYYY-MM-DD') FROM dual;
commit;
INSERT NHANVIEN (MANV, HOTEN, SODT, NGVL) SELECT N'NV02', N'Le Thi Phi Yen', N'987567390', to_date('2006-04-21 ', 'YYYY-MM-DD') FROM dual;
commit;
INSERT NHANVIEN (MANV, HOTEN, SODT, NGVL) SELECT N'NV03', N'Nguyen Van B', N'997047382', to_date('2006-04-27 ', 'YYYY-MM-DD') FROM dual;
commit;
INSERT NHANVIEN (MANV, HOTEN, SODT, NGVL) SELECT N'NV04', N'Ngo Thanh Tuan', N'913758498', to_date('2006-06-24 ', 'YYYY-MM-DD') FROM dual;
commit;
INSERT NHANVIEN (MANV, HOTEN, SODT, NGVL) SELECT N'NV05', N'Nguyen Thi Truc Thanh', N'918590387', to_date('2006-07-20 ', 'YYYY-MM-DD') FROM dual;
commit;
INSERT NHANVIEN (MANV, HOTEN, SODT, NGVL) SELECT N'NV06', N'Le Ngoc Tram', N'987828019', to_date('2020-04-17 ', 'YYYY-MM-DD') FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BB01', N'But bi', N'cay', N'Viet Nam', 5000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BB02', N'But bi', N'cay', N'Trung Quoc', 7000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BB03', N'But bi', N'hop', N'Thai Lan', 100000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BB06', N'But bi', N'cay', N'USA', 120000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BC01', N'But chi', N'cay', N'Singapore', 3000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BC02', N'But chi', N'cay', N'Singapore', 5000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BC03', N'But chi', N'cay', N'Viet Nam', 3500.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'BC04', N'But chi', N'hop', N'Viet Nam', 30000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST01', N'So tay 500 trang', N'quyen', N'Trung Quoc', 40000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST02', N'So tay loai 1', N'quyen', N'Viet Nam', 55000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST03', N'So tay loai 2', N'quyen', N'Viet Nam', 51000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST04', N'So tay', N'quyen', N'Thai Lan', 55000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST05', N'So tay mong', N'quyen', N'Thai Lan', 20000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST06', N'Phan viet bang', N'hop', N'Viet Nam', 5000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST07', N'Phan khong bui', N'hop', N'Viet Nam', 7000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST08', N'Bong bang', N'cai', N'Viet Nam', 1000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST09', N'But long', N'cay', N'Viet Nam', 5000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'ST10', N'But long', N'cay', N'Trung Quoc', 7000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV01', N'Tap 100 giay mong', N'quyen', N'Trung Quoc', 2500.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV02', N'Tap 200 giay mong', N'quyen', N'Trung Quoc', 4500.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV03', N'Tap 100 giay tot', N'quyen', N'Viet Nam', 3000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV04', N'Tap 200 giay tot', N'quyen', N'Viet Nam', 5500.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV05', N'Tap 100 trang', N'chuc', N'Viet Nam', 23000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV06', N'Tap 200 trang', N'chuc', N'Viet Nam', 53000.0000 FROM dual;
commit;
INSERT SANPHAM (MASP, TENSP, DVT, NUOCSX, GIA) SELECT N'TV07', N'Tap 100 trang', N'chuc', N'Trung Quoc', 34000.0000 FROM dual;
commit;
CodePudding user response:
One 'execute immediate' per table's column, is a bit overkilling... is it not ?
This template should do the work:
SELECT * FROM (
SELECT
COUNT(colname) AS n_colname
[, ....]
FROM table_name
)
UNPIVOT (
non_nulls
FOR colname IN (
n_colname AS 'n_colname'
[,...]
)
);
The number of NULLs in each column being the count(PrimaryKey) - the non_nulls for the column in the result of the query... if you have primary keys in your table... but why should you not... (you will find the PK in all_constraints as constraint of type 'P', be careful with multi columns ones)
It's a bit more complicated to generate the SQL for the EXECUTE IMMEDIATE but should be much faster.
CodePudding user response:
There are lots of issues with your code.
- you don't need the
declare
keyword for a procedure; - your first declaration ends with a comma instead of a semicolon, and your second doesn't have a semicolon;
- your first loop query is missing a closing parenthesis;
- both loops are against the same
USER_TAB_COLUMNS
table, which will end up generating more results than you expect; - neither declared variable is actually used because your loops have independent names which are the same and take precedence;
- you can't have a query within a
dbms_output
call -put_line()
takes a string value, not a query; - you don't have a semicolon after your output call;
- you don't have either
end loop
; - @variable isn't Oracle syntax;
- you need to refer to the table/column name field within the loop record, not the entire record;
- you can't use variables for table/column names in a static query anyway, so it would have to be dynamic SQL;
count(*)
counts all rows, not just those with values (which seems to be what you want).
So to use two loops like that you could do:
create or replace procedure hc_test
as
v_sql varchar2(4000);
v_count number;
v_null_count number;
begin
for v_tables in (
select table_name
FROM USER_TABLES
WHERE table_name IN ('CTHD','HOADON','KHACHHANG','NHANVIEN','SANPHAM')
)
loop
for v_columns in (
select column_name
from USER_TAB_COLUMNS
WHERE table_name = v_tables.table_name
)
loop
v_sql := 'select count("' || v_columns.column_name || '"),'
|| ' count(case when "' || v_columns.column_name || '" is null then 1 end)'
|| ' from "' || v_tables.table_name || '"';
execute immediate v_sql into v_count, v_null_count;
dbms_output.put_line (
v_tables.table_name
|| ' ' || v_columns.column_name
|| ' ' || v_count
|| ' ' || v_null_count
);
end loop;
end loop;
end;
/
Or you could do it with a single loop:
create or replace procedure hc_test
as
v_sql varchar2(4000);
v_count number;
v_null_count number;
begin
for v_tab_cols in (
select table_name, column_name
from USER_TAB_COLUMNS
WHERE table_name IN ('CTHD','HOADON','KHACHHANG','NHANVIEN','SANPHAM')
)
loop
v_sql := 'select count("' || v_tab_cols.column_name || '"),'
|| ' count(case when "' || v_tab_cols.column_name || '" is null then 1 end)'
|| ' from "' || v_tab_cols.table_name || '"';
execute immediate v_sql into v_count, v_null_count;
dbms_output.put_line (
v_tab_cols.table_name
|| ' ' || v_tab_cols.column_name
|| ' ' || v_count
|| ' ' || v_null_count
);
end loop;
end;
/
Both generate the output:
CTHD SOHD 51 0
CTHD MASP 51 0
CTHD SL 51 0
HOADON SOHD 25 0
HOADON NGHD 25 0
HOADON MAKH 23 2
HOADON MANV 25 0
HOADON TRIGIA 25 0
KHACHHANG MAKH 10 0
KHACHHANG HOTEN 10 0
KHACHHANG DCHI 10 0
KHACHHANG SODT 10 0
KHACHHANG NGSINH 10 0
KHACHHANG NGDK 10 0
KHACHHANG DOANHSO 10 0
NHANVIEN MANV 6 0
NHANVIEN HOTEN 6 0
NHANVIEN SODT 6 0
NHANVIEN NGVL 6 0
SANPHAM MASP 25 0
SANPHAM TENSP 25 0
SANPHAM DVT 25 0
SANPHAM NUOCSX 25 0
SANPHAM GIA 25 0
You could also do it without loops and without PL/SQL, using an XML trick, which is a bit off-topic for your question but for fun:
with cte (table_name, column_name, xml) as (
select table_name,
column_name,
dbms_xmlgen.getxmltype(
'select count("' || column_name || '") as value_rows,'
|| ' count(case when "' || column_name || '" is null then 1 end) as null_rows'
|| ' from "' || table_name || '"'
)
from user_tab_columns
where table_name IN ('CTHD','HOADON','KHACHHANG','NHANVIEN','SANPHAM')
)
select cte.table_name, cte.column_name, x.value_rows, x.null_rows
from cte
cross apply xmltable(
'/ROWSET/ROW'
passing cte.xml
columns value_rows number path 'VALUE_ROWS',
null_rows number path 'NULL_ROWS'
) x;
which generates a more useful result set:
TABLE_NAME | COLUMN_NAME | VALUE_ROWS | NULL_ROWS |
---|---|---|---|
CTHD | SOHD | 51 | 0 |
CTHD | MASP | 51 | 0 |
CTHD | SL | 51 | 0 |
HOADON | SOHD | 25 | 0 |
HOADON | NGHD | 25 | 0 |
HOADON | MAKH | 23 | 2 |
HOADON | MANV | 25 | 0 |
HOADON | TRIGIA | 25 | 0 |
KHACHHANG | MAKH | 10 | 0 |
KHACHHANG | HOTEN | 10 | 0 |
KHACHHANG | DCHI | 10 | 0 |
KHACHHANG | SODT | 10 | 0 |
KHACHHANG | NGSINH | 10 | 0 |
KHACHHANG | NGDK | 10 | 0 |
KHACHHANG | DOANHSO | 10 | 0 |
NHANVIEN | MANV | 6 | 0 |
NHANVIEN | HOTEN | 6 | 0 |
NHANVIEN | SODT | 6 | 0 |
NHANVIEN | NGVL | 6 | 0 |
SANPHAM | MASP | 25 | 0 |
SANPHAM | TENSP | 25 | 0 |
SANPHAM | DVT | 25 | 0 |
SANPHAM | NUOCSX | 25 | 0 |
SANPHAM | GIA | 25 | 0 |
as @p3consulting pointed out, running a separate count query for each column does seem a bit inefficient; and I hadn't thought about unpivoting, which is neat. Either approach could be modified to work like that, but with the XML approach you could do:
with cte (table_name, xml) as (
select table_name,
dbms_xmlgen.getxmltype(
'select * from ( select '
|| listagg('count("' || column_name || '") as "V_' || column_name || '",'
|| ' count(case when "' || column_name || '" is null then 1 end) as "N_' || column_name || '"', ', ') within group (order by column_id)
|| ' from "' || table_name || '"'
|| ') unpivot ((value_rows, null_rows) for column_name in ('
|| listagg('("V_' || column_name || '", "N_' || column_name || '") as ''' || column_name || '''', ', ') within group (order by column_id)
|| '))'
)
from user_tab_columns
where table_name IN ('CTHD','HOADON','KHACHHANG','NHANVIEN','SANPHAM')
and column_id is not null
group by table_name
)
select cte.table_name, x.value_rows, x.null_rows
from cte
cross apply xmltable(
'/ROWSET/ROW'
passing cte.xml
columns column_name varchar2(30) path 'COLUMN_NAME',
value_rows number path 'VALUE_ROWS',
null_rows number path 'NULL_ROWS'
) x;
which gets the same output.
db<>fiddle (including some of the intermediate XML to maybe make it slightly clearer.)