Possible data model
Tyson, February 03, 2011 - 3:55 pm UTC
I realize that this does not answer the direct problem, but here is a data model that borrows from the apex websheet design (the websheet design is probably better because the apex team rocks). A generic data storage table with a large amount of generic columns. A table that maps the generic columns to a more meaningful name. a procedure that builds a view against the generic data table which maps meaniningful names to the columns.
CREATE TABLE CASE_STUDIES (
CASE_STUDY_ID NUMBER NOT NULL ENABLE,
NAME VARCHAR2(50 BYTE),
CONSTRAINT CASE_STUDIES_PK PRIMARY KEY (CASE_STUDY_ID),
CONSTRAINT CASE_STUDIES_NAME_UK UNIQUE (NAME)
);
CREATE UNIQUE INDEX CASE_STUDIES_NAME_UK ON CASE_STUDIES (NAME);
CREATE UNIQUE INDEX CASE_STUDIES_PK ON CASE_STUDIES (CASE_STUDY_ID);
CREATE TABLE CASE_STUDY_DATA(
ID NUMBER NOT NULL ENABLE,
CASE_STUDY_ID NUMBER NOT NULL ENABLE,
C001 VARCHAR2(4000 BYTE),
C002 VARCHAR2(4000 BYTE),
C003 VARCHAR2(4000 BYTE),
C004 VARCHAR2(4000 BYTE),
C005 VARCHAR2(4000 BYTE),
C006 VARCHAR2(4000 BYTE),
C007 VARCHAR2(4000 BYTE),
C008 VARCHAR2(4000 BYTE),
C009 VARCHAR2(4000 BYTE),
C010 VARCHAR2(4000 BYTE),
CONSTRAINT CASE_STUDY_DATA_PK PRIMARY KEY (ID),
CONSTRAINT CASE_STUDY_DATA_CASE_ID_FK FOREIGN KEY (CASE_STUDY_ID)
REFERENCES CASE_STUDIES (CASE_STUDY_ID) ENABLE
);
CREATE TABLE CASE_STUDY_COLS(
ID NUMBER NOT NULL ENABLE,
CASE_STUDY_ID NUMBER NOT NULL ENABLE,
DISPLAY_COL_NAME VARCHAR2(30 BYTE) NOT NULL ENABLE,
MAP_COL_NAME VARCHAR2(30 BYTE) NOT NULL ENABLE,
CONSTRAINT CASE_STUDY_COLS_PK PRIMARY KEY (ID),
CONSTRAINT CASE_STUDY_COLS_UK1 UNIQUE (CASE_STUDY_ID, MAP_COL_NAME),
CONSTRAINT CASE_STUDY_COLS_CASE_STUD_FK1 FOREIGN KEY (CASE_STUDY_ID)
REFERENCES CASE_STUDIES (CASE_STUDY_ID) ENABLE
);
CREATE UNIQUE INDEX CASE_STUDY_COLS_PK ON CASE_STUDY_COLS (ID);
CREATE UNIQUE INDEX CASE_STUDY_COLS_UK1 ON CASE_STUDY_COLS (CASE_STUDY_ID, MAP_COL_NAME);
insert into case_studies(case_study_id, name)
values(1,'FISH');
insert into case_study_data( id, case_study_id, C001, C002, C003, C004, C005, C006, C007, C008, C009, C010)
values(1, 1 , 'SALMON', '21', '8', 'M', null, null, null, null, null, null);
insert into case_study_data( id, case_study_id, C001, C002, C003, C004, C005, C006, C007, C008, C009, C010)
values(2, 1 , 'SALMON', '24', '8.7', 'F', null, null, null, null, null, null);
insert into case_study_data( id, case_study_id, C001, C002, C003, C004, C005, C006, C007, C008, C009, C010)
values(3, 1 , 'SALMON', '18', '6.4', 'M', null, null, null, null, null, null);
insert into case_study_cols( id, case_study_id, display_col_name, map_col_name)
values(1, 1, 'SPECIES', 'C001');
insert into case_study_cols( id, case_study_id, display_col_name, map_col_name)
values(2, 1, 'LENGTH INCHES', 'C002');
insert into case_study_cols( id, case_study_id, display_col_name, map_col_name)
values(3, 1, 'WEIGHT POUNDS', 'C003');
insert into case_study_cols( id, case_study_id, display_col_name, map_col_name)
values(4, 1, 'GENDER', 'C004');
create or replace
procedure build_study_view(p_study_name case_studies.name%type)
as
l_nl varchar2(10) := chr(10);
l_sql varchar2(32000);
l_study_name case_studies.name%type := upper(p_study_name);
begin
l_sql := 'create or replace view '|| l_study_name || '$current ' || l_nl ||
'as ' || l_nl ||
'select ';
for rec in(select csc.display_col_name
, csc.map_col_name
from case_studies cs
join case_study_cols csc
on cs.case_study_id = csc.case_study_id
where cs.name = l_study_name)
loop
l_sql := l_sql || '"'|| rec.map_col_name || '" as "' || rec.display_col_name || '", ';
end loop;
l_sql := rtrim(l_sql,', ');
l_sql := l_sql || ' from case_studies cs ' ||
' join case_study_data csd ' ||
' on cs.case_study_id = csd.case_study_id ' ||
'where cs.name = ''' || l_study_name || '''';
dbms_output.put_line(l_sql);
execute immediate l_sql;
end build_study_view;
begin
build_study_view('FISH');
end;
February 03, 2011 - 4:16 pm UTC
but they do not even need to do that, all of their tables have the same columns - they just needed to add ONE MORE COLUMN...
the study name
and then keep it all in a single schema.