5

我正在使用全局应用程序用户帐户访问数据库 A。此用户帐户无权修改数据库 A 的架构(即创建表、修改表等)。该用户还可以访问数据库 B,但只能查看。我需要运行 SQL 将数据库 B 中的视图中的数据馈送到数据库 A 中的表中。

在一个完美的世界里,我可以使用这个 SQL:

create database_a.mytable as (select * from database_b) with no data

但是,用户不能在数据库 A 中创建表。如果我可以获得 select 语句的 DDL,那么我可以在我的个人帐户下登录(它没有任何访问数据库 B 的权限)并在数据库中运行 DDL A 创建表。

唯一的其他选择是手动编写 SQL,但我不想这样做,特别是因为我要复制的这个视图有许多不同数据类型和大小的列。

编辑:我可能越来越近了。我刚刚对此进行了实验:

show (select * from database_b.myview)

但是,它生成了视图本身中使用的每个表的 DLL,以及视图的定义。这并没有真正帮助我,因为我只想要 select 语句本身的模式。换句话说,如果我要使用create table as上面提到的语句,我需要生成什么。

为 Rob 编辑:也许“DDL”是一个错误的术语。使用show view db.myview只显示视图的定义,而不是它所代表的模式。在我上面的示例中create table as,我展示了如何创建一个模仿 select 中返回的结果集模式的表。它在后端生成一个用于创建表的 DDL,然后执行该 DDL 以实际创建表。然后您可以说出show table db.newtable并查看新表的 DDL。我想直接从 select 语句中获取DDL,以便我可以复制它,退出应用程序帐户,进入我的个人帐户,然后执行 DDL 以创建表。

这只是为了让我不必手动输入 DDL 以节省时间并减少输入错误,特别是因为源视图有这么多列。也就是说,我认为找 DBA 或编写一些时髦的存储过程来做动态的东西对于我的需求来说有点过头了。我认为必须有一种方法可以直接从 select 语句中获取用于创建表模式的 DDL。

4

1 回答 1

11

为对象生成 DDL 语句:

SHOW TABLE {DatabaseB}.{Table1};
SHOW VIEW {DatabaseB}.{View1};

视图中的列细分:

HELP VIEW {DatabaseB}.{View1};

但是,如果没有在目标数据库中创建对象的能力,DatabaseA您就没有太多的影响力。显然,如果该对象已经存在INSERT INTO SELECT ... FROM DatabaseB.Table1或者MERGE INTO是您已经探索过的选项。

替代解决方案

是否可以创建一个基于提供的视图名称动态创建表的存储过程?全局应用程序帐户只需要特权即可执行该过程。通常,创建存储过程的用户需要权限才能执行存储过程中包含的操作。(在 Teradata 13.10 中,您有一些额外的灵活性。)

这种方法有一些注意事项。您正在尝试物化可以引用从数百到数十亿条记录的任何地方的视图。这些不是放在目标表之上的简单的 1:1 视图。试图确定目标数据库中实现视图所需的空间将很困难。性能可以并且将根据视图的复杂性和数据量而有所不同。这将不是快速路径或数据块优化操作。

作为一名 DBA,我会担心这种方法被一个全球应用程序帐户采用,而没有完全理解其意图。我相信您与支持该系统所涉及的 DBA 有一个开放的沟通渠道。我敢肯定,你的疯狂是有原因的,这里不能透露。

可能的解决方案 - 易失性表

除非已从全局应用程序帐户撤销 CREATE TABLE 的隐式特权,否则此解决方案应该可以工作。

易失性表不需要永久空间。表定义在会话期间持续存在,插入其中的任何数据都依赖于实例化它的用户的假脱机空间。

CREATE VOLATILE TABLE {Global Application UserID}.{TableA_Copy} AS 
(
   SELECT *
     FROM {DatabaseB}.{TableA}
)
 WITH NO DATA
   NO PRIMARY INDEX
   ON COMMIT PRESERVE ROWS;

SHOW TABLE {Global Application UserID}.{TableA_Copy};

我选择使用名为NO PRIMARY INDEX. 默认情况下,CREATE TABLEAS 将获取SELECT语句的第一列并使其成为PRIMARY INDEX表的列。根据数据人口统计数据,这可能会导致测试中出现倾斜和烫发空间问题。PRIMARY INDEX当您了解基础数据时,您可以自行指定显式。(如果您不确定,请参阅 DDL 手册以获取有关语法的详细信息。)

用于ON COMMIT PRESERVE ROWS本示例的意图可能是无关紧要的。但实际上,如果您将任何数据弹出到该表中以测试此子句,则在 Teradata 模式下将是有益的,否则在CREATE TABLE对易失性表执行或任何其他数据操作后,数据将立即丢失。

于 2012-10-16T22:55:02.113 回答