主頁 > 軟體設計 > 創建一個程式來計算Oracle中表名串列中每一列的每一行?

創建一個程式來計算Oracle中表名串列中每一列的每一行?

2022-09-14 02:12:47 軟體設計

我有一個串列,包括:表名、列名

我需要一個可以計算每個表中每列的value_rowsnull_rows的程序。

假設每個表的列數將來可能會發生變化。

呼叫程序時強制使用程序并顯示結果(不要使用DML方法更新或創建另一個表)

我的想法是在 2 個回圈中使用 2 個變數:@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;

我知道我的代碼是語法錯誤,但我真的不知道如何處理,然后我無法完成撰寫完整的程式,即使我已經在 youtube 上搜索并觀看了一些視頻,但仍然很難做到。

預期輸出如下:在此處輸入影像描述

我在 Oracle 資料庫中使用 PL/SQL Developer 12 軟體,然后在這里應用其他程式的代碼非常困難。

您的解決方案將極大地幫助我提高我在 Oracle 開發方面的技能,

非常感謝,祝您有美好的一天。

下面的代碼創建示例表

/* 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;

uj5u.com熱心網友回復:

每個表的列一個“立即執行”,有點矯枉過正......不是嗎?

這個模板應該做的作業:

SELECT * FROM (
    SELECT 
        COUNT(colname) AS n_colname
        [, ....]
    FROM table_name
)
UNPIVOT (
    non_nulls
    FOR colname IN (
        n_colname AS 'n_colname'
        [,...]
    )
);

每列中的 NULL 數是 count(PrimaryKey) - 查詢結果中列的 non_nulls ......如果你的表中有主鍵......但你為什么不應該......(你會在 all_constraints 中找到 PK 作為“P”型別的約束,注意多列的約束)

為 EXECUTE IMMEDIATE 生成 SQL 有點復雜,但應該更快。

uj5u.com熱心網友回復:

你的代碼有很多問題。

  • 您不需要declare程序的關鍵字;
  • 您的第一個宣告以逗號而不是分號結尾,而您的第二個宣告沒有分號;
  • 您的第一個回圈查詢缺少右括號;
  • 兩個回圈都針對同USER_TAB_COLUMNS一張表,最終會產生比您預期更多的結果;
  • 兩個宣告的變數都沒有實際使用,因為您的回圈具有相同的獨立名稱并且具有優先權;
  • 您不能在dbms_output呼叫中進行查詢 -put_line()接受字串值,而不是查詢;
  • 輸出呼叫后沒有分號;
  • 你也沒有end loop
  • @variable 不是 Oracle 語法;
  • 您需要參考回圈記錄中的表/列名欄位,而不是整個記錄;
  • 無論如何,您不能在靜態查詢中使用變數作為表/列名,因此它必須是動態 SQL;
  • count(*)計算所有行,而不僅僅是那些有值的行(這似乎是你想要的)。

所以要使用兩個這樣的回圈,你可以這樣做:

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;
/

或者你可以用一個回圈來做到這一點:

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;
/

兩者都生成輸出:

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

您也可以使用 XML 技巧在沒有回圈和 PL/SQL 的情況下執行此操作,這對于您的問題來說有點離題,但很有趣:

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;

這會生成更有用的結果集:

TABLE_NAME COLUMN_NAME VALUE_ROWS NULL_ROWS
CTHD 超高清 51 0
CTHD MASP 51 0
CTHD SL 51 0
霍頓 超高清 25 0
霍頓 NGHD 25 0
霍頓 麥可 23 2
霍頓 MANV 25 0
霍頓 特里賈 25 0
卡昌 麥可 10 0
卡昌 熱騰騰 10 0
卡昌 DCHI 10 0
卡昌 SODT 10 0
卡昌 NGSINH 10 0
卡昌 NGDK 10 0
卡昌 多安索 10 0
楠薇 MANV 6 0
楠薇 熱騰騰 6 0
楠薇 SODT 6 0
楠薇 NGVL 6 0
桑帕姆 MASP 25 0
桑帕姆 TENSP 25 0
桑帕姆 深靜脈血栓形成 25 0
桑帕姆 NUOCSX 25 0
桑帕姆 GIA 25 0

db<>小提琴


正如@p3consulting 指出的那樣,為每一列運行單獨的計數查詢似乎效率低下;而且我沒有考慮過不旋轉,這很整潔。任何一種方法都可以修改為像這樣作業,但使用 XML 方法,您可以這樣做:

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;

得到相同的輸出。

db<>fiddle(包括一些中間 XML 可能會使其更清晰。)

uj5u.com熱心網友回復:

這是一個完整的解決方案,不受 LISTAGG 和 GETXMLTYPE 對引數長度的限制(4000 char 除非資料庫中使用“擴展型別”)

CREATE OR REPLACE TYPE t_tablestats AS OBJECT (
      table_name  VARCHAR2(64),
      column_name  VARCHAR2(128),
      value_rows  NUMBER(19,0),
      null_rows  NUMBER(19,0)
    );
    /
    
CREATE OR REPLACE TYPE t_tablestats_tab AS TABLE OF t_tablestats ;
    /
  


CREATE OR REPLACE FUNCTION gen_stats_tablecolumns_str( i_table_name IN VARCHAR2)
RETURN CLOB 
AS
  w_result CLOB ;
BEGIN
  SELECT
    q'~SELECT '~' || i_table_name || q'~' AS table_name, d.* FROM ( SELECT ~' ||
    REPLACE( REPLACE( REPLACE(
      JSON_ARRAYAGG( 
        q'~COUNT('~' || column_name || q'~') AS V_~' || column_name || q'~, COUNT(CASE WHEN ~' || column_name || q'~ IS NULL THEN 1 END) AS N_~' || column_name
        RETURNING CLOB)
      , '["', ''), '","', ',' || CHR(10)), '"]', '')
     || ' FROM ' || table_name 
     || ') UNPIVOT( (value_rows,null_rows) FOR column_name IN (' 
     || REPLACE( REPLACE( REPLACE(
        JSON_ARRAYAGG( '(V_' || column_name || ', N_' || column_name || ')' RETURNING CLOB)
      , '["', ''), '","', ',' || CHR(10)), '"]', '')  || ')) d'
    INTO w_result
  FROM user_tab_columns
  WHERE table_name = i_table_name
  AND column_id is not null
  GROUP BY table_name
  ;

  RETURN w_result ;
END ;
/

-- i_table_names  comma sep list of table names
    CREATE OR REPLACE FUNCTION gen_statscolvalues( i_table_names IN VARCHAR2)
    RETURN t_tablestats_tab
    PIPELINED
    IS
      w_query CLOB ;
      curs_dynamic    sys_refcursor ;
      w_result t_tablestats := t_tablestats(null,null,null,null) ;
    BEGIN
      FOR rec IN (
        SELECT CAST(REGEXP_SUBSTR(i_table_names ,'[^,] ',1,LEVEL) AS VARCHAR2(64)) AS table_name FROM DUAL
        CONNECT BY REGEXP_SUBSTR(i_table_names ,'[^,] ', 1,LEVEL) IS NOT NULL
      )
      LOOP
        SELECT gen_stats_tablecolumns_str( rec.table_name ) INTO w_query FROM DUAL ;
        OPEN curs_dynamic FOR w_query ;
        LOOP
          FETCH curs_dynamic INTO w_result.table_name, w_result.column_name, w_result.value_rows, w_result.null_rows  ;
          w_result.column_name := SUBSTR(w_result.column_name,3, INSTR( w_result.column_name, '_N_')-3) ;
          
          EXIT WHEN curs_dynamic%NOTFOUND ;
          PIPE ROW(w_result) ;
          
        END LOOP ;
        CLOSE curs_dynamic;
      END LOOP ;
      
      RETURN ;
    END ;
    /

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/506877.html

標籤:甲骨文 循环 数数 程序

上一篇:Oracle11g所需的下表輸出

下一篇:oracleSQL計數器在時差>x時重新啟動

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more