我使用全局应用程序用户帐户访问数据库A.此用户帐户无权修改数据库A的架构(即创建表,修改表等)。此用户还可以访问数据库B,但只能访问视图。我需要运行SQL以将数据从数据库B中的视图提供到数据库A中的表中。
在一个完美的世界中,我将能够使用这个SQL:
create database_a.mytable as (select * from database_b) with no data
但是,用户无法在数据库A中创建表。如果我可以获取select语句的DDL,那么我可以在我的个人帐户下登录(它没有对数据库B的任何访问权限)并运行数据库A中的DDL创建表。
唯一的另一个选择是手动编写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。
答案 0 :(得分:10)
为对象生成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有一个开放的沟通渠道来支持这个系统。我确定你的疯狂有理由在这里无法透露。
可能的解决方案 - VOLATILE TABLE
除非已从全局应用程序帐户撤消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
的Teradata 13.10功能。默认情况下,CREATE TABLE
AS将获取SELECT
语句的第一列,并使其成为表的PRIMARY INDEX
。这可能会导致测试中的倾斜和烫发空间问题,具体取决于数据的人口统计特征。您可以在了解基础数据时自行指定显式PRIMARY INDEX
。 (如果您不确定,请参阅DDL手册以获取有关语法的详细信息。)
使用ON COMMIT PRESERVE ROWS
作为此示例的意图可能是无关紧要的。但实际上,如果您将任何数据弹出到该表中以进行测试,则该子句在Teradata模式下将是有益的,因为在CREATE TABLE
或对易失性表执行任何其他数据操作之后,数据将立即丢失。