oracle 在PL/SQL上编写过程有困难

sulc1iza  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(107)

所以,基本上,我需要创建一个过程,它将两个表的名称作为参数,然后创建一个新表,其中外键与参数中表的主键连接。
我需要什么:我需要这个过程来获取两个已经存在于DB表中的列,找到那些被主键约束的列,创建一个表(这就是为什么我使用execute immediate,cnc),它引用我的两个表的主键上的fks,这些列名作为新创建的列的数据库,因为我们不知道参数表的pk列的数据类型是什么。因此,此过程应该写入创建的表的名称或显示发生的错误(但不是ORA)。
主要的问题是在创建一个表的一部分,我不知道如何把这些列名(我希望它只是一个),我被告知,我可以使用子字符串,但不知道如何在这种情况下,我可以做到这一点,因为我不知道列的名称的长度,我不知道如果我的列的信息是完整的没有绑定,我应该在哪里使用它。
编辑之前写的内容,这是我的程序的全文。

create or replace procedure table_creation (table_a varchar2, table_b varchar2) 
is 
l_cnt_a number;
l_cnt_b number;
l_str_a varchar2 (32767); 
l_str_b varchar2 (32767); 
l_pk_a varchar2 (32767); 
l_pk_b varchar2 (32767); 
err1 exception;
err2 exception; 
sql_text varchar2 (32767); 
begin 
SELECT count(1), 
max(cols.constraint_name), listing(cols.column_name || '_1' ',') 
INTO l_cnt_a, l_str_a, l_pk_a 
FROM all_constraints cons 
INNER JOIN all_cons_columns cols ON cons.constraint_name = cols.constraint_name 
WHERE cons.table_name = table_a 
AND cons.constraint_type = 'P'; 
IF l_cnt = 0 then 
RAISE err; 
END IF;

SELECT count(1), 
max(cols.constraint_name), listing(cols.column_name || '_2' ',') 
INTO l_cnt_b, l_str_b, l_pk_b
FROM all_constraints cons 
INNER JOIN all_cons_columns cols ON cons.constraint_name = cols.constraint_name 
WHERE cons.table_name = table_b
AND cons.constraint_type = 'P'; 
IF l_cnt = 0 then 
RAISE err; 
END IF;

sql_text := 
'create or replace table table_c ('
|| CHR(10) 
|| 'for i in 1..l_cnt_a loop'
|| CHR(10) 
|| 'column_for_a_i a_i_column%TYPE, '
|| CHR(10) 
|| 'end loop'
|| CHR(10) 
|| 'for i in 1..l_cnt_b loop'
|| CHR(10) 
|| 'column_for_b_i b_i_column%TYPE, '
|| CHR(10) 
|| 'end loop'
|| CHR(10) 
|| 'constraint fk_a' 
|| CHR(10) 
|| 'foreign key (column_for_a_i) '
|| CHR(10) 
|| 'references table_a(l_pk_a), '
|| CHR(10) 
|| 'constraint fk_b' 
|| CHR(10) 
|| 'foreign key (column_for_b_i) '
|| CHR(10) 
|| 'references table_b(l_pk_b), '
|| CHR(10) 
|| ') ';

execute immediate sql_text;
dbms_output.put_line('done');
exception
when err1 then 
dbms_output.put_line('first table');
when err2 then 
dbms_output.put_line('second table');
end table_creation;

我很抱歉,如果它有点不可读,我还在学习(希望现在的问题是更容易理解,如果不是-我会再试一次XD

qnyhuwrf

qnyhuwrf1#

问题是,您的代码将sql_text生成为SQL和PL/SQL的组合-这将不起作用。你应该创建动态代码,要么是SQL,要么是PL/SQL。我不是很明白这个问题,但我会试着提出一部分的解决办法。
引用:“主要的麻烦是在创建一个表的一部分,我不知道如何把这些列名在” 结束引用。
您可以使用以下命令生成完整的CREATE TABLE命令。

Select  'CREATE TABLE ' || CHR(10) || CHR(9) || 
    'NEW_TABLE' || CHR(10) || CHR(9) || '(' || 
        SubStr(COL_DESC, 3, Length(COL_DESC) - 4) || CHR(10) || CHR(9) || 
    ')' "CREATE_TABLE_DDL"
From    (   Select   LISTAGG(CHR(10) || CHR(9) || CHR(9) || 
                Case When TABLE_NAME = 'A_TBL_1' Then COLUMN_NAME || '_FROM_T1 ' 
                Else COLUMN_NAME || '_FROM_T2 ' 
                End || 
                Case When DATA_TYPE = 'DATE' Then DATA_TYPE || ', '
                Else DATA_TYPE || '(' || CASE WHEN DATA_TYPE = 'NUMBER' 
                                              THEN To_Char(DATA_PRECISION) || ', ' || To_Char(DATA_SCALE) 
                                         ELSE To_Char(DATA_LENGTH) 
                                         END 
                                       || ')' || Case When NULLABLE = 'N' Then ' NOT NULL' End || ', '
                End
              ) WITHIN GROUP (Order By TABLE_NAME, COLUMN_ID) "COL_DESC"
      From all_tab_columns 
      Where TABLE_NAME IN('A_TBL_1', 'A_TBL_2')
      Order By TABLE_NAME, COLUMN_ID
    )
--  
--  R e s u l t :
--
--  CREATE_TABLE_DDL
--  ---------------------------------------------------
--  CREATE TABLE 
--      NEW_TABLE 
--      (   ID_FROM_T1 NUMBER(3, 0) NOT NULL,   
--          T2_ID_FROM_T1 VARCHAR2(20),   
--          SOME_COLUMN_FROM_T1 DATE,   
--          ID_FROM_T2 VARCHAR2(3, 0) NOT NULL,   
--          T1_ID_FROM_T2 NUMBER(22),   
--          SOME_OTHER_COLUMN_FROM_T2 VARCHAR2(20)  
--      )

注意:我使用了两个虚拟表。您可以使用过程的参数,并将结果存储到sql_text变量中。同样地,你也可以生成其他的声明。
使用的虚拟表:

Desc A_TBL_1;
Name        Null?    Type         
----------- -------- ------------ 
ID          NOT NULL NUMBER(3)    
T2_ID                VARCHAR2(20) 
SOME_COLUMN          DATE        

Desc A_TBL_2;
Name              Null?    Type         
----------------- -------- ------------ 
ID                NOT NULL VARCHAR2(20) 
T1_ID                      NUMBER(3)    
SOME_OTHER_COLUMN          VARCHAR2(20)

相关问题