【问题标题】:Create table whose columns properties are rows of another创建其列属性是另一个行的表
【发布时间】:2013-05-01 02:11:03
【问题描述】:

首先,请不要将其标记为重复,因为我不是要求选择而是创建新表。为了更清楚,我有一张像这样的表格:

CREATE  TABLE Attributes (
   Col_Name VARCHAR(45) NULL,
   Col_type VARCHAR(45) NULL, 
   Col_ID   VARCHAR(45) NULL 
);

Col_Name    |   Col_type|   Col_ID
-----------------------------------------------
C1          T1      1
C2          T2      2

我想最终得到这样的东西:

C1(T1)| C2(T2)
----------------
Val      Val

谢谢

【问题讨论】:

  • 我搜索了一下,但一切都与执行一些特殊的“选择”有关,但我需要在这里有一个新表,如果你能告诉我实现这一目标的可能性是什么,因为我明白这可能并不简单。谢谢
  • SELECT Col_Name, Col_Type, Col_ID FROM Attributes 然后用你的编程语言处理它,然后放到一个HashTable中,例如。
  • 你能给我一个java中的小例子吗?无论如何,非常感谢你:)
  • 我看到你的想法有错误的逻辑。如果你在 Attributes 中放了多于两行,那会有什么快乐呢?像 10 还是 100?那么你应该如何形成你的列名呢?我可以通过你的例子为你写程序,但这是非常糟糕的逻辑。
  • 如果您的列类型数量有限,例如 10 种,最好为每种列类型创建一个单独的表。

标签: mysql sql database oracle11g relational-database


【解决方案1】:

这些程序在 Oracle 中,其中之一应该适合您的问题。这将创建包含与行一样多的列。

属性作为属性和固定列类型:

DECLARE
  lc_string VARCHAR2(2000);
BEGIN
  FOR c1 IN (SELECT Col_Name, Col_type FROM Attributes ORDER BY Col_ID) LOOP
    lc_string := lc_string||c1.Col_Name||'_'||c1.Col_type||'_'||' VARCHAR2(100), ';
  END LOOP;
  lc_string := SUBSTR(lc_string,0,(LENGTH(lc_string)-2));
  lc_string := 'CREATE TABLE some_name ('||lc_string||')';
  EXECUTE IMMEDIATE lc_string; 
END;
/

属性作为列类型:

DECLARE
  lc_string VARCHAR2(2000);
BEGIN
  FOR c1 IN (SELECT Col_Name, Col_type FROM Attributes ORDER BY Col_ID) LOOP
    lc_string := lc_string||c1.Col_Name||' '||c1.Col_type||', ';
  END LOOP;
  lc_string := SUBSTR(lc_string,0,(LENGTH(lc_string)-2));
  lc_string := 'CREATE TABLE some_name ('||lc_string||')';
  EXECUTE IMMEDIATE lc_string; 
END;
/

【讨论】:

  • 非常感谢您的回答,但 Oracle 一直告诉我 'IMMEDIATE' 是未知命令..
  • 尝试把lc_string放到屏幕上,看看它的格式是否正确(所有的',()'都在适当的位置)。 EXECUTE IMMEDIATE 是 Oracle 中的标准 PL/SQL 语句。
  • 也许我的 Oracle 出了点问题。但是我认为你的回答是最好的,所以我会接受这个:)
  • 把 dbms_output.put_line(lc_string);之前或 insted 立即执行。然后你会看到你的字符串是否有问题。你得到什么样的错误?
【解决方案2】:

除非这是针对临时表,否则您会经常创建表以使其值得。

无论如何,以下基本 SQL 将为您创建创建查询:-

SELECT CONCAT('CREATE TABLE IF NOT EXISTS `sometable` (, ', GROUP_CONCAT(CONCAT('`', Col_Name, '` ', Col_type) ORDER BY Col_ID SEPARATOR ','), ");")
FROM Attributes

(假设是 MySQL 而不是 Oracle)

将我的 SQL 与 DARK_As proc 示例结合起来有点儿戏:-

DECLARE
BEGIN
  FOR c1 IN (SELECT 'CREATE TABLE IF NOT EXISTS `sometable` (, ' || (LISTAGG('`' || Col_Name || '` ' || Col_type, ',') WITHIN GROUP ORDER BY Col_ID) || ');') AS CreateCommand FROM Attributes) LOOP
    EXECUTE IMMEDIATE c1.CreateCommand;
  END LOOP;
END;
/

请注意,这未经测试(如果 Attributes 表包含多个表的描述,您可能需要为表添加 GROUP BY 子句)。

【讨论】:

  • 我认为你在 ')' 之前的最后一列中得到一个 ',',这可能会出现错误。
  • 你不应该这样做,因为逗号是由 group_concat 添加的,所以只会用于分隔字段.. 除非我在某处打错字
  • 先生,我一直在尝试,但我得到的只是一个选择结果,并且没有创建表,有什么错误吗?还是谢谢你
  • 选择结果应该是你需要执行的创建语句。
  • 您可以将我的 SQL 语句与 DARK_A 中的基本过程结合起来完成这项工作。似乎 Oracle 现在支持一个名为 LISTAGG 的函数,它几乎等同于 GROUP_CONCAT - oracle-developer.net/display.php?id=515 - 所以这应该相当容易(怕我这些天不使用 Oracle 并且没有开发环境所以我会尝试敲一些东西up 但不确定它是否正确)
猜你喜欢
  • 2013-01-08
  • 1970-01-01
  • 2017-12-04
  • 1970-01-01
  • 1970-01-01
  • 2012-06-14
  • 1970-01-01
  • 2019-08-02
  • 2020-07-19
相关资源
最近更新 更多