pl / sql - сравнить количество записей в двух таблицах пользователя - PullRequest
2 голосов
/ 13 сентября 2011

У меня есть таблица 'stf_table' в схеме 'staff' с именем пользователя 'staff'.

У меня есть таблица 'emp_table' в схеме 'employee' с именем пользователя 'employee'.

Оба они находятся под одним и тем же SID / хостом / портом базы данных, но пользователь 'staff' не имеет привилегий для запроса таблиц в схеме 'employee' и наоборот (т. Е. Пользователь 'employee' не имеет привилегий для таблицы запросов по схеме «штат»). Но каждый пользователь может запросить таблицу по своей схеме. Примечание: я не могу предоставить дополнительные привилегии, и мне не нужно выкидывать обе таблицы в локальную схему.

Можно ли написать процесс или пакет PL / SQL, который бы делал следующее?

 select count(*) from stf_table;
 select count(*) from emp_table;

затем выведите оба значения в файл (т. Е. В формате .txt или .dat) следующим образом:

stf_table count: 47830
emp_table count: 36462
difference: 11368
counts match: FALSE

Ответы [ 3 ]

8 голосов
/ 13 сентября 2011

Если вы не хотите предоставлять дополнительные привилегии ни одному из пользователей, у вас не так много вариантов.

Вы можете создать процедуру, принадлежащую суперпользователю, скажем, учетную запись, которая имеет SELECT ANY TABLE, (но не SYS или SYSTEM), который учитывает и рассчитывает разницу.

create function get_diff 
    return pls_integer
    authid definer
as 
    c1 pls_integer;
    c2 pls_integer;
begin
    select count(*) 
    into c1
    from staff.stf_table;
    select count(*)
    into c2
    from employee.emp_table;

    return abs(c1-c2);
end get_diff;
/

Итак, решающим моментом здесь является AUTHID DEFINER.Это означает, что функция запускается с разрешениями пользователя, которому принадлежит функция;потому что у них есть необходимые разрешения для запроса обеих таблиц, которые пользователь может запускать функцию, и любой другой пользователь, которому они предоставляют EXECUTE ON GET_DIFF.

, - это действительно минимальный уровень предоставления, с которым вы можете обойтись..


NB. Я не обращался к вопросу записи в файл, потому что на самом деле не думаю, что это суть вашего вопроса.Главное - это разрешения.


"Нет ли способа, чтобы процесс мог подключиться как пользователь 'staff', сохранить счет в файл. Затем подключиться как пользователь 'employee', сохранить счет в тот же файл и сравнить? "

Нет.Это не так, как работает модель безопасности.

Данные STAFF принадлежат STAFF, а данные EMPLOYEE принадлежат EMPLOYEE.По умолчанию STAFF не может видеть данные РАБОТНИКА и наоборот.Чтобы изменить эту ситуацию, у вас есть два варианта:

  1. Разрешить STAFF предоставлять SELECT на своей таблице для EMPLOYEE, а EMPLOYEE предоставлять SELECT на своей таблице для STAFF.
  2. Использовать учетную запись с привилегиямидля работы с таблицами обеих схем.

Очевидно, что при первом подходе могут возникнуть проблемы с защитой данных.Если вас это интересует, вам доступны некоторые уточнения:

  1. У каждой схемы есть собственное представление, которое просто выбирает количество своих записей и предоставляет привилегии для представлений.
  2. Если у вас есть Enterprise Edition 10gR2 или выше, вы можете использовать VPD на уровне столбцов: предоставление грантов на столе, поставить политику на место, чтобы скрыть все конфиденциальные данные. Узнать больше .
1 голос
/ 13 сентября 2011

APC прав в том, что вы не можете легко решить эту проблему без предоставления дополнительных разрешений.Возможно, есть более простой способ, чем он предлагает.

Я бы предложил создать представление и предоставить доступ к этому представлению другой схеме.

В схеме STAFF вы можете создать представлениеstf_table_count:

create or replace view stf_table_count
as
select count(*) as num_rows
from stf_count;

Затем предоставьте выбор в этом представлении для схемы сотрудника:

grant select on stf_table_count to employee;

Затем из схемы сотрудника вы можете найти результат без получения данных

select num_rows from staff.stf_table_count
union all
select count(*) from emp_table;

Вы также можете повторить этот процесс, чтобы получить количество сотрудников в схеме персонала.

Я не специалист по безопасности баз данных Oracle, поэтому ваш пробег может отличаться от этого ответа, но я думаю, что он должен работать.

1 голос
/ 13 сентября 2011

Предоставление разрешений - правильная вещь, однако, как вы заявляете, это невозможно:

Одним из решений может быть сделать это в командной строке с помощью сценариев. (самый большой недостаток заключается в том, что имя пользователя и пароль будут встроены в скрипт для всеобщего обозрения, поэтому убедитесь, что скрипты надежно защищены)

сначала создайте 2 скрипта:

a.sql:

set timing off
set feedback off
set pages 0
select count(*) from stf_table;
exit

b.sql:

set timing off
set feedback off
set pages 0
select count(*) from emp_table;
exit

Теперь создайте файл сценария extract.bat для получения вывода:

 @echo off
 FOR /F "usebackq delims=!" %%i IN (`sqlplus -s username/password@db_a @a.sql`) DO set resulta=%%i 

 FOR /F "usebackq delims=!" %%i IN (`sqlplus -s username/password@db_b @b.sql`) DO set resultb=%%i 

 set /a diff=%resulta%-%resultb%

 echo stf_table count %resulta% 
 echo emp_table count %resultb%
 echo difference %diff%

 IF %diff%=0 (
 echo Counts match TRUE
 ) ELSE (
 echo Counts match FALSE)

теперь просто выполните extract.bat в командной строке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...