简体   繁体   English

DROP TABLE IF EXISTS 相当于来自 SAS 的 TERADATA

[英]DROP TABLE IF EXISTS equivalent for TERADATA from SAS

I'm trying to avoid the error:我试图避免错误:

ERROR: Teradata execute: Object 'MY_TABLE' does not exist.

When executing TERADATA SQL from SAS从 SAS 执行 TERADATA SQL 时

This is the original SAS code I'm using:这是我使用的原始 SAS 代码:

proc sql;
    connect to TERADATA (user='my_user' password=XXXXXXXXXX MODE=TERADATA TDPID='bdpr');
    execute(database MY_DB) by TERADATA;
    execute(Drop table MY_TABLE;) by TERADATA;
    disconnect from TERADATA;
quit;

According to the documentation the .SET ERRORLEVEL 3807 SEVERITY 0 should fix my problem.根据文档, .SET ERRORLEVEL 3807 SEVERITY 0应该可以解决我的问题。

I tried inserting the following before my DROP TABLE statement:我尝试在我的DROP TABLE语句之前插入以下内容:

execute(.SET ERRORLEVEL 3807 SEVERITY 0) by TERADATA;
execute(ECHO '.SET ERRORLEVEL 3807 SEVERITY 0') by TERADATA;

I tried combining both:我尝试将两者结合起来:

execute(ECHO '.SET ERRORLEVEL 3807 SEVERITY 0'; Drop table MY_TABLE;) TERADATA;

With either a syntax error for the calls without ECHO or no effect on the error when trying the ECHO variants.没有ECHO的调用有语法错误,或者在尝试ECHO变体时对错误没有影响。

The problem is that the .SET ERRORLEVEL is not a SQL statement but a BTEQ command.问题在于 .SET .SET ERRORLEVEL不是 SQL 语句而是 BTEQ 命令。 According to the docs it should be possible to execute BTEQ commands from standard TERADATA SQL should be possible using the ECHO construct.根据文档,应该可以使用ECHO构造从标准 TERADATA SQL 执行 BTEQ 命令。 But from SAS this doesn't seem to be working.但是从 SAS 这似乎不起作用。

I only need a solution to avoid the SAS error, both SAS side solutions as well as TERADATA solutions are ok for me.我只需要一个解决方案来避免 SAS 错误,SAS 端解决方案以及 TERADATA 解决方案对我来说都可以。

Maybe this could help you, if you run this as a proc call:如果您将其作为 proc 调用运行,也许这可以帮助您:

replace procedure drop_if_exists( in_object varchar(50)) 
begin
  IF EXISTS(SELECT 1 FROM dbc.tables WHERE tablename = in_object 
    and databasename='<your database name>') THEN
    CALL DBC.SysExecSQL('DROP TABLE ' || in_object);
  END IF;
END;

And call this from sas via:并通过以下方式从 sas 调用它:

execute (call drop_if_exists(MY_TABLE);) by TERADATA;

EDIT: SAS-invoked procedure creation编辑:SAS调用的过程创建

proc sql;
    connect using DBCONN;
    execute(
replace procedure drop_if_exists( in_object varchar(50)) 
begin
  IF EXISTS(SELECT 1 FROM dbc.tables WHERE tablename = in_object 
    and databasename='<my database>') THEN
    CALL DBC.SysExecSQL('DROP TABLE ' || in_object);
  END IF;
END;
    ) by DBCONN;
    disconnect from DBCONN;
quit;

Why not ask Teradata if the table exists and then have SAS conditionally run the drop?为什么不询问 Teradata 该表是否存在,然后让 SAS 有条件地运行删除?

%let tablekind=NONE;
select obj into :tablekind trimmed from connection to teradata
  (select case when (tablekind in ('T','O')) then 'TABLE'
          else 'VIEW' end as obj
    from dbc.tablesv
    where databasename = 'MY_DB' and tablename= 'MY_TABLE'
      and tablekind in ('V','T','O')
  )
;
%if &tablekind ne NONE %then %do;
  execute(drop &tablekind. MY_DB.MY_TABLE;) by teradata;
%end;

I don't know the syntax to create an SP from SAS, but I doubt you will have the right to do so.我不知道从 SAS 创建 SP 的语法,但我怀疑您是否有权这样做。

You might ask your DBA to install following SP, which drops any kind of table (including Volatile).您可能会要求您的 DBA 安装以下 SP,它会删除任何类型的表(包括 Volatile)。

--Drop a table without failing if the table doesn’t exist:
REPLACE PROCEDURE drop_table_if_exists
(
  /* database name, uses default database when NULL.
     Must be calling user for Volatile Tables
  */
  IN db_name VARCHAR(128) CHARACTER SET Unicode, 
  
  /* table name */
  IN tbl_name VARCHAR(128) CHARACTER SET Unicode,
  
  OUT msg VARCHAR(400) CHARACTER SET Unicode
) SQL SECURITY INVOKER – check the rights of the calling user
BEGIN
   DECLARE full_name VARCHAR(361)  CHARACTER SET Unicode;
   DECLARE sql_stmt VARCHAR(500)  CHARACTER SET Unicode;
   
   DECLARE exit HANDLER FOR SqlException
   BEGIN
      -- catch "table doesn't exist" error
      IF SqlCode = 3807 THEN SET msg = full_name || ' doesn''t exist.';
      ELSE
        -- fail on any other error, e.g. missing access rights or wrong object tye
        RESIGNAL;
      END IF;
   END;

   SET full_name = '"' || Coalesce(db_name,DATABASE) || '"."' || Coalesce(tbl_name,'') || '"';

   SET sql_stmt = 'DROP TABLE ' || full_name || ';';

   EXECUTE IMMEDIATE sql_stmt;

   SET msg = full_name || ' dropped.';
END;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM