我有2个数据库连接:a
和b
,它们都共享相同的架构,但不一定共享相同的数据。我需要使用循环检查每个表的两个数据库的总行数,并比较它们的计数。
到目前为止,我尝试使用嵌套表集合:
DECLARE
TYPE nt_rows IS TABLE OF NUMBER;
nt_rows1 nt_num := nt_num();
nt_rows2 nt_num := nt_num();
counter INT := 0;
CURSOR c_tables1 IS
SELECT TABLE_NAME
FROM ALL_TABLES
WHERE OWNER IN ('a')
ORDER BY TABLE_NAME ASC;
CURSOR c_tables2 IS
SELECT TABLE_NAME
FROM ALL_TABLES
WHERE OWNER IN ('b')
ORDER BY TABLE_NAME ASC;
BEGIN块:遍历每个游标并将它们添加到每个数组
BEGIN
FOR i IN c_tables1 LOOP
nt_rows1.extend;
SELECT COUNT(*) FROM a.i.TABLE_NAME INTO nt_rows1(counter);
END LOOP;
最后一行不起作用,其中'a'是数据库连接名称,而i是每个table_name的索引。 我也尝试过:
nt_rows1(counter) := SELECT COUNT(*) FROM a.i.TABLE_NAME;
它也不起作用,任何建议都值得赞赏。
答案 0 :(得分:1)
如果要从名称为字符串(例如,局部变量或游标字段)的表中查询数据,因此在编译时未知,则将需要使用动态SQL。
尝试替换行
SELECT COUNT(*) FROM a.i.TABLE_NAME INTO nt_rows1(counter);
使用
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM a.' || i.TABLE_NAME INTO nt_rows1(counter);
还请注意,您的代码没有递增counter
变量。由于您将counter
设置为0
,并且0
不是嵌套表中的有效索引,因此建议您在添加counter
之前添加一行以递增--setup emailDomain table
if OBJECT_ID('tempdb..#emailDomain') is not NULL
drop table #emailDomain
create table #emailDomain (
id int IDENTITY(1,1) PRIMARY KEY,
domain varchar(50) not null
)
insert into #emailDomain
--id is automatic generated
values('aol.com')
,('att.net')
,('comcast.net')
,('facebook.com')
,('gmail.com')
,('gmx.com')
--setup allowedChar table
if OBJECT_ID('tempdb..#allowedChar') is not NULL
drop table #allowedChar
create table #allowedChar(
id int IDENTITY(1,1) PRIMARY KEY,
aChar char(1) not null
)
insert into #allowedChar
values('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i'),('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q')
,('r'),('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z'),('1'),('2'),('3'),('4'),('5'),('6'),('9'),('7'),('0'),('8')
--setup allowedSpecialChar table
if OBJECT_ID('tempdb..#allowedSpecialChar') is not NULL
drop table #allowedSpecialChar
create table #allowedSpecialChar(
id int IDENTITY(1,1) PRIMARY KEY,
asChar char(1)
)
insert into #allowedSpecialChar
VALUES('_'),('-'),('.')
declare @countDomains as int = (select count(*) from #emailDomain)
declare @countallowedChars as int = (select count(*) from #allowedChar)
declare @countallowedSpecialChars as int = (select count(*) from #allowedSpecialChar);
if OBJECT_ID('tempdb..#rowsWithRandomCharsNrs') is not NULL
drop table #rowsWithRandomCharsNrs;
--generate with recursion 50 rows, with an id and a random length for the e-mail address
with
baseRowsWithEmailLength as (
select 1 as idMail, round(RAND(CHECKSUM(NEWID())) * 60 + 1,0) as strLength
union all
select idMail + 1 as idMail, round(RAND(CHECKSUM(NEWID())) * 60 + 1,0) as strLength
from baseRowsWithEmailLength
where idMail < 50
)
--generate with recursion a random number (indexChar) for every char in the string, which is an id to join with the table allowedChar
,rowsWithRandomCharsNrs as(
select idMail, strLength, 1 as idchar, round(RAND(CHECKSUM(NEWID())) * (@countallowedChars-1) +1,0) as indexChar
from baseRowsWithEmailLength
union all
select idMail, strLength, idchar + 1 as idchar, round(RAND(CHECKSUM(NEWID())) *(@countallowedChars-1) +1,0) as indexChar
from rowsWithRandomCharsNrs
where idchar < strLength
)
select *
into #rowsWithRandomCharsNrs
from rowsWithRandomCharsNrs
SELECT idMail
,concat(left(mailRandStr, firstMailPartLength),aspc.asChar,RIGHT(mailRandStr, StrLength - firstMailPartLength), '@', ed.domain) as Mail
FROM(
SELECT idMail
,strLength
,firstMailPartLength
,mailRandStr
--generate a random number to join a random Domain and specialchar
,round(RAND(CHECKSUM(NEWID())) * (@countDomains-1) +1,0) as idDomain
,round(RAND(CHECKSUM(NEWID())) * (@countallowedSpecialChars-1) +1,0) as idSpecialChar
FROM (
SELECT DISTINCT
idMail
,StrLength
,round(StrLength * 0.75,0) as firstMailPartLength
--concat all chars to a single string via for xml path
,(
select ''+ac.aChar
from #rowsWithRandomCharsNrs sub
join #allowedChar ac on sub.indexChar = ac.id
where sub.idMail = m.idMail
FOR XML PATH('')
)as mailRandStr
FROM #rowsWithRandomCharsNrs m
) sub
)sub
left join #emailDomain ed on sub.idDomain = ed.id
left join #allowedSpecialChar aspc on sub.idSpecialChar = aspc.id
上面的行。