Oracle cols_as_rows 比對資料
AskTom提供的指令碼,用於比對資料.
create or replace type myscalartype as object
( rnum number, cname varchar2(30), val varchar2(4000) )
/
create or replace type mytabletype as table of myscalartype
/
create or replace
function cols_as_rows( p_query in varchar2 ) return mytabletype
-- This function is designed to be installed ONCE per database, and
-- it is nice to have ROLES active for the dynamic sql, hence the
-- AUTHID CURRENT_USER.
authid current_user
-- This function is a pipelined function, meaning that it'll send
-- rows back to the client before getting the last row itself.
-- In 8i, we cannot do this.
pipelined
as
l_thecursor integer default dbms_sql.open_cursor;
l_columnvalue varchar2(4000);
l_status integer;
l_colcnt number default 0;
l_desctbl dbms_sql.desc_tab;
l_rnum number := 1;
begin
-- Parse, describe and define the query. Note, unlike print_table,
-- I am not altering the session in this routine. The
-- caller would use to_char() on dates to format and if they
-- want, they would set cursor_sharing. This routine would
-- be called rather infrequently. I did not see the need
-- to set cursor sharing therefore.
dbms_sql.parse( l_thecursor, p_query, dbms_sql.native );
dbms_sql.describe_columns( l_thecursor, l_colcnt, l_desctbl );
for i in 1 .. l_colcnt loop
dbms_sql.define_column( l_thecursor, i, l_columnvalue, 4000 );
end loop;
-- Now, execute the query and fetch the rows. iterate over
-- the columns and "pipe" each column out as a separate row
-- in the loop. Increment the row counter after each
-- dbms_sql row.
l_status := dbms_sql.execute(l_thecursor);
while ( dbms_sql.fetch_rows(l_thecursor) > 0 )
loop
for i in 1 .. l_colcnt
loop
dbms_sql.column_value( l_thecursor, i, l_columnvalue );
pipe row
(myscalartype( l_rnum, l_desctbl(i).col_name, l_columnvalue ));
end loop;
l_rnum := l_rnum+1;
end loop;
-- Clean up and return...
dbms_sql.close_cursor(l_thecursor);
return;
end cols_as_rows;
/
create or replace function
cols_as_rows8i( p_query in varchar2 ) return mytabletype
authid current_user
as
l_thecursor integer default dbms_sql.open_cursor;
l_columnvalue varchar2(4000);
l_status integer;
l_colcnt number default 0;
l_desctbl dbms_sql.desc_tab;
l_data mytabletype := mytabletype();
l_rnum number := 1;
begin
dbms_sql.parse( l_thecursor, p_query, dbms_sql.native );
dbms_sql.describe_columns( l_thecursor, l_colcnt, l_desctbl );
for i in 1 .. l_colcnt loop
dbms_sql.define_column( l_thecursor, i, l_columnvalue, 4000 );
end loop;
l_status := dbms_sql.execute(l_thecursor);
while ( dbms_sql.fetch_rows(l_thecursor) > 0 )
loop
for i in 1 .. l_colcnt
loop
dbms_sql.column_value( l_thecursor, i, l_columnvalue );
l_data.extend;
l_data(l_data.count) :=
myscalartype( l_rnum, l_desctbl(i).col_name, l_columnvalue );
end loop;
l_rnum := l_rnum+1;
end loop;
dbms_sql.close_cursor(l_thecursor);
return l_data;
end cols_as_rows8i;
/
以HR表為例,比對員工編號200和201的員工資料
column val format a20;
select a.cname,a.val,b.val from
table(cols_as_rows('select * from hr.employees where employee_id=200')) a,
table(cols_as_rows('select * from hr.employees where employee_id=201')) b
where a.cname=b.cname and (a.val is not null or b.val is not null)
order by a.cname;
create or replace type myscalartype as object
( rnum number, cname varchar2(30), val varchar2(4000) )
/
create or replace type mytabletype as table of myscalartype
/
create or replace
function cols_as_rows( p_query in varchar2 ) return mytabletype
-- This function is designed to be installed ONCE per database, and
-- it is nice to have ROLES active for the dynamic sql, hence the
-- AUTHID CURRENT_USER.
authid current_user
-- This function is a pipelined function, meaning that it'll send
-- rows back to the client before getting the last row itself.
-- In 8i, we cannot do this.
pipelined
as
l_thecursor integer default dbms_sql.open_cursor;
l_columnvalue varchar2(4000);
l_status integer;
l_colcnt number default 0;
l_desctbl dbms_sql.desc_tab;
l_rnum number := 1;
begin
-- Parse, describe and define the query. Note, unlike print_table,
-- I am not altering the session in this routine. The
-- caller would use to_char() on dates to format and if they
-- want, they would set cursor_sharing. This routine would
-- be called rather infrequently. I did not see the need
-- to set cursor sharing therefore.
dbms_sql.parse( l_thecursor, p_query, dbms_sql.native );
dbms_sql.describe_columns( l_thecursor, l_colcnt, l_desctbl );
for i in 1 .. l_colcnt loop
dbms_sql.define_column( l_thecursor, i, l_columnvalue, 4000 );
end loop;
-- Now, execute the query and fetch the rows. iterate over
-- the columns and "pipe" each column out as a separate row
-- in the loop. Increment the row counter after each
-- dbms_sql row.
l_status := dbms_sql.execute(l_thecursor);
while ( dbms_sql.fetch_rows(l_thecursor) > 0 )
loop
for i in 1 .. l_colcnt
loop
dbms_sql.column_value( l_thecursor, i, l_columnvalue );
pipe row
(myscalartype( l_rnum, l_desctbl(i).col_name, l_columnvalue ));
end loop;
l_rnum := l_rnum+1;
end loop;
-- Clean up and return...
dbms_sql.close_cursor(l_thecursor);
return;
end cols_as_rows;
/
create or replace function
cols_as_rows8i( p_query in varchar2 ) return mytabletype
authid current_user
as
l_thecursor integer default dbms_sql.open_cursor;
l_columnvalue varchar2(4000);
l_status integer;
l_colcnt number default 0;
l_desctbl dbms_sql.desc_tab;
l_data mytabletype := mytabletype();
l_rnum number := 1;
begin
dbms_sql.parse( l_thecursor, p_query, dbms_sql.native );
dbms_sql.describe_columns( l_thecursor, l_colcnt, l_desctbl );
for i in 1 .. l_colcnt loop
dbms_sql.define_column( l_thecursor, i, l_columnvalue, 4000 );
end loop;
l_status := dbms_sql.execute(l_thecursor);
while ( dbms_sql.fetch_rows(l_thecursor) > 0 )
loop
for i in 1 .. l_colcnt
loop
dbms_sql.column_value( l_thecursor, i, l_columnvalue );
l_data.extend;
l_data(l_data.count) :=
myscalartype( l_rnum, l_desctbl(i).col_name, l_columnvalue );
end loop;
l_rnum := l_rnum+1;
end loop;
dbms_sql.close_cursor(l_thecursor);
return l_data;
end cols_as_rows8i;
/
以HR表為例,比對員工編號200和201的員工資料
column val format a20;
select a.cname,a.val,b.val from
table(cols_as_rows('select * from hr.employees where employee_id=200')) a,
table(cols_as_rows('select * from hr.employees where employee_id=201')) b
where a.cname=b.cname and (a.val is not null or b.val is not null)
order by a.cname;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1609294/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle Mysql PostgreSQL 資料庫的對比OracleMySql資料庫
- 資料庫選型比對 Oracle vs sqlserver資料庫OracleSQLServer
- Oracle、NoSQL和NewSQL 資料庫技術對比OracleSQL資料庫
- Oracle和MySQL資料庫CTAS等操作對比OracleMySql資料庫
- Oracle、NoSQL和NewSQL 資料庫技術對比(一)OracleSQL資料庫
- 【SQL】Oracle資料庫變更後sql效能對比SQLOracle資料庫
- MySQL 資料對比MySql
- Oracle、NoSQL和NewSQL 資料庫技術對比(二)- 終結OracleSQL資料庫
- TSPython操作MySQL MongoDB Oracle三大資料庫深入對比oeePythonMySqlMongoDBOracle大資料資料庫
- 直播強勢來襲:Oracle nologgiing;資料庫上雲;國產資料庫比對Oracle資料庫
- ORACLE PL/SQL 物件、表資料對比功能儲存過程簡單實現OracleSQL物件儲存過程
- Oracle和sqlserver資料型別對應OracleSQLServer資料型別
- 漫談“資料拆分層次對比”
- 關聯式資料庫與文件資料庫對比資料庫
- Oracle vs PostgreSQL,研發注意事項(8)- Oracle資料比較規則OracleSQL
- Oracle資料型別對應Java型別Oracle資料型別Java
- Oracle 對某列的部分資料建立索引Oracle索引
- 小程式與Vue對比·資料繫結Vue
- openGauss資料與PostgreSQL的差異對比SQL
- 資料庫訪問幾種方式對比資料庫
- 幾款分散式資料庫的對比分散式資料庫
- oracle partition by group by,詳解partition by和group by對比Oracle
- 用Jupyter+pandas資料分析,6種資料格式效率對比
- BI工具對比|Smartbi與億信ABI兩款BI資料看板軟體對比
- 大資料教程系列之Kafka和activemq對比大資料KafkaMQ
- PostgreSQL 資料庫結構(DDL)比對工具 pgquarrelSQL資料庫
- 手寫一個業務資料比對庫
- 主備資料庫狀態手工比對(一)資料庫
- 主備資料庫狀態手工比對(二)資料庫
- 資料資產價值評估常用方法及對比
- 資料湖選型指南|Hudi vs Iceberg 資料更新能力深度對比
- 全自動化資料洞察!資料分佈對比視覺化!⛵視覺化
- oracle 資料庫對於多列求最大值Oracle資料庫
- 磁碟排序對Oracle資料庫效能的影響PT排序Oracle資料庫
- smtools軟體提取比對到和未比對到參考基因組上的bam資料
- 大資料儲存系統對比:Ceph VS Gluster大資料
- ETL資料整合工具DataX、Kettle、ETLCloud特點對比Cloud
- python 兩個資料夾裡的檔名對比Python
- 大資料流處理:Flume、Kafka和NiFi對比大資料KafkaNifi