TERADATA:WHILE LOOP在SELECT中起作用,但在我的SPROC中不起作用

时间:2019-05-09 05:19:25

标签: sql arrays variables teradata teradata-sql-assistant

我在teradata中创建了以下存储过程,从当前运行日开始,并提取该特定星期内的所有发票。然后继续返回52周,然后将记录插入我的holder表中。

但是我可以在没有WHILE循环的情况下运行SELECT。但是当我成功创建一个存储过程并运行时,我收到以下消息:

  

OUTLETLOOPMG:用户引用的所有者没有对CORP_INVOICE_VIEWS.INVOICE_CORP.Ownrshp_ID的SELECT访问权限

我不知道选择是否可以在没有循环的情况下正常工作。

有两个问题:

  1. 该错误怎么了?
  2. 基于我在初始段落中描述的逻辑,我的WHILE循环能否实现这一目标?

代码:

CREATE  PROCEDURE OutletLoopMG()
BEGIN 
    DECLARE iVAR INT DEFAULT 52;
    DECLARE dVAR DATE DEFAULT current_date;

    --SET iVAR = 52;
    --SET dVAR = current_date;

    WHILE  iVAR > 0
    DO
    BEGIN
        INSERT INTO dlccc_cust_cntc_cntr_lab.OutletHolder
            SELECT 
                invcorp.OWNRSHP_ID, invcorp.BTLR_DLVR_PNT_NO,
                snap.btlr_branch_nm, snap.dlvr_pnt_nm,
                invcorp.inv_no, invcorp.inv_dt,
                cal.week_of_year, cal.year_of_calendar
            FROM
                corp_invoice_VIEWS.invoice_corp invcorp
            LEFT JOIN
                CHR_VIEWS.DPT_SNAPSHOT_SELECT snap ON invcorp.BTLR_DLVR_PNT_NO = snap.BTLR_DLVR_PNT_NO 
                                                   AND invcorp.OWNRSHP_ID = snap.OWNRSHP_ID 
            INNER JOIN
                sys_calendar.calendar cal ON invcorp.inv_dt = cal.calendar_date
            WHERE 
                1 = 1 
                AND invcorp.inv_dt = dVAR;
    END;    

    SET dVAR = (CAST(dVAR AS DATE) - 7);
    SET iVAR = (iVAR-1);

END WHILE;  
END;

1 个答案:

答案 0 :(得分:0)

这个问题有点长,但是由于最近的编辑,它弹出回到了队列的顶部:

在过程中,可以分配安全性的三个“角色”(实际上是4个,我会介绍的)

  1. OWNER-这是在其下创建过程的数据库/用户。如果您为过程使用默认的SQL SECURITY设置,则OWNER将需要访问过程WITH GRANT OPTION中使用的对象。因此:GRANT SELECT ON corp_invoice_VIEWS TO <whatever database this proc is in> WITH GRANT OPTION您需要为FROM子句中此处选择的每个数据库/视图/表授予该访问权限。

  2. 创建者-这是您,因为您正在编译过程。使用该过程的默认SQL SECURITY设置,您将需要有权访问该过程中使用的对象。您必须已经具有该访问权限才能单独运行SELECT。所以这一切都很好。

  3. INVOKER-这是将执行/调用该过程的用户。对于过程的默认SQL SECURITY设置,INVOKER仅需要对该过程具有EXECUTE过程。

过程上的默认SQL SECURITY设置(编写过程时可被覆盖)为SQL SECURITY DEFINER。这是我上面提到的“第四”角色。定义程序安全性将在编译过程时检查过程CREATOROWNER是否都可以访问过程中的对象。此外,在执行该过程时,将再次检查OWNER特权。如果您和该过程所在的数据库无权访问,则在编译时会引发错误。如果OWNER(该过程所在的数据库)也没有访问权限,则会在执行时抛出错误。

您可以解决此错误的选项:

  1. 授予过程的所有者SELECT访问具有GRANT OPTION的表,视图或包含这些表/视图的数据库的权限,以便满足SQL SECURITY DEFINER的默认设置。这是更安全,易变的路线。

  2. 将过程上的sql安全性更改为SQL SECURITY CREATOR,以便在编译和执行时仅检查您的凭据(过程的创建者)。这是一个便宜的修补程序,但是如果您没有权限更改正在使用的数据库的安全性,则可以理解。

  3. 将过程的sql安全性更改为SQL SECURITY INVOKER,以便仅将在编译后执行过程的人员用于检查特权。这意味着执行的用户不仅必须具有对该过程的EXECUTE PROCEDURE访问权,而且还需要具有对其中使用的视图/表的SELECT访问权。这可能是比编号2更安全的选项,但不如选项1(检查创建者和所有者)的健壮性强。

您可以阅读有关过程安全性at the documentation site的更多信息。