[BUG][4.0EA3] Invalid surrogate key is created after engineering to relation model

Repro steps:
Go to Tools -> Domain Administration. Add new domain named MyIdentifier with logical type UNIQUEIDENTIFIER. Apply and save changes.
Go to Tools -> Preferences, then Data Modeler -> Model -> Relational. Get to Surrogate Column Data Type group box and set Domain = MyIdentifier. Apply changes.
Create new Entity and enable option "Create Surrogate Key". Apply changes.
Engineer to Relational Model with default settings.
Expected result:
Entity_1_ID column's data type is UNIQUEIDENTIFIER
Actual result:
Entity_1_ID column's data type is CHAR

I've forgot to mention, that my default RDBMS Site is set to SQL Server 2008. In Types Administration UNIQUEIDENTIFIER is mapped to CHAR for Oracle, but it mapped to UNIQUEIDENTIFIER for SQL Server 2008.

Similar Messages

  • How to create surrogate key in dimension without unique value

    Hi, I have a dimension where there is no column with unique value. I want to add a surrogate key to replace the existing primary key which is derived from concatenating 3 columns(e.g. 'A'||'B'||'C'). I'm thinking of using sequence. But this won't allow me to link the dimension to fact table. How do I come up with surrogate key under this situation? Thanks. ~Tracy

    I'm actually trying to accomplish something similar myself.
    In my sources I've got two sorts of customers, ones that are directly reported, and ones whose information is provided with sales records (this is stored in module ODS).
    Of course identification is different, but in the datamart (module DWH) I'm sort of forced to use an equivalent way of loading (due to the way it first used to work). To accelerate lookups on dimensions, I copy the ODS surrogate key to DWH dimensions, but this does not work for the 'inbuilt' customers because they do not have a surrogate key in the ODS.
    They DO have means of unique identification, and at first I thought I could concatenate these (also 3) columns to use as identification code. Unfortunately this is VARCHAR2, where the surrogate key is (naturally) NUMBER.
    So now it looks like I'm forced to first build a table in ODS especially for these 'inbuilt' customers and assign a surrogate key (by sequence) to it, this way it conforms to how 'normal' customers are loaded into DWH.
    I guess you'll have to pull of the same trick, i.e. create a table with either only the 'translation' of D-code to a surrogate key or all information that is fed into the dimension, which then can be used as a lookup or as complete source when loading data into your datamart.
    Good luck, Patrick

  • How to create surrogate keys

    dear all,
    please give me some steps to creating and implementation of Surrogate keys in ODI .
    thanks in advance
    sri

    Hi Yellanki,
    Both ways are for calling the sequence in back end.
    <%=odiRef.getObjectName("<your sequence name>")%>.NEXTVAL is syntax for calling back end objects from ODI.
    your sequence name.NEXTVAL is generic syntax for calling sequence in Oracle.
    Both will work in ODI but its "recommended" to call backend objects in ODI syntax.
    Makes sense?
    Thanks,
    Guru

  • Surrogate Key and Map for Cube

    Hi
    I am new to Data Warehousing and am trying to use OWB 11g.
    I am trying to create dimensions with multiple levels. When I create more than one level it need to have surrogate as well business key for each dimension level. But I can create only one surrogate in the dimension, there is no option to create multiple surrogate keys in the same dimension. so what am I missing?
    My second question is regarding cube. Do I need to create a Mapping for a cube? if yes, should I move the data to the cube from the dimensions? and where will the measures come from? do i need to load the measures or they will be calculated automatically?
    please reply...
    regards
    Arif

    hi
    Got it, Yes that was the reason,
    The table was not properly deployed after the dimension was modified.
    Anyway, the describe of the table is as follows
    describe arif.QUESTION_DIM
    Name Null Type
    DIMENSION_KEY NOT NULL NUMBER
    IGV_ID NUMBER
    PER_ID NUMBER
    DIM_ID NUMBER
    IGO_ID NUMBER
    INQ_ID NUMBER
    ID NUMBER
    DIM_ORDEM NUMBER
    DIM_AMBITO VARCHAR2(3)
    DIM_NOME VARCHAR2(150)
    10 rows selected
    Now, I am having another problem,
    when, I deploy the Map to load the data from three different tables, it gives the following problem
    Name               Action               Status          Log
    QUESTION_MAP          Create               Warning          ORA-06550: line 297, column 25:
                                            PLS-00302: component 'ID' must be declared
    QUESTION_MAP          Create               Warning          ORA-06550: line 1153, column 11:
                                            PL/SQL: SQL Statement ignored
    QUESTION_MAP          Create               Warning          ORA-06550: line 1155, column 15:
                                            PL/SQL: ORA-00904: "QUESTION_DIM"."ID": invalid identifier
    QUESTION_MAP          Create               Warning          ORA-06550: line 1155, column 31:
                                            PLS-00302: component 'ID' must be declared
    QUESTION_MAP          Create               Warning          ORA-06550: line 233, column 1:
                                            PL/SQL: SQL Statement ignored
    QUESTION_MAP          Create               Warning          ORA-06550: line 2539, column 11:
                                            PL/SQL: SQL Statement ignored
    QUESTION_MAP          Create               Warning          ORA-06550: line 2541, column 15:
                                            PL/SQL: ORA-00904: "QUESTION_DIM"."ID": invalid identifier
    QUESTION_MAP          Create               Warning          ORA-06550: line 2541, column 31:
                                            PLS-00302: component 'ID' must be declared
    QUESTION_MAP          Create               Warning          ORA-06550: line 297, column 9:
                                            PL/SQL: ORA-00904: "QUESTION_DIM"."ID": invalid identifier
    Edited by: user643560 on Oct 22, 2008 9:38 AM

  • Bug? - Getting "ORA-20001: Unable to create updateable report"

    We have created hundreds of simple tabular reports, but have come across 3 tables that we cannot get past the following error for when finishing the last step of the create wizard:
    ORA-20001: Unable to create updateable report. ORA-06502: PL/SQL: numeric or value error: character string buffer too small
    Error creating tabular form.
    Return to application.
    Here is the DDL for this table:
    CREATE TABLE ancfx_test
    (ANCFX_ID NUMBER(31,0) NOT NULL ENABLE,
    APP_DTL_LVL_CD VARCHAR2(160),
    NOTE_CALL_FR_TYP_CD VARCHAR2(15),
    ANCFX_VOID_IND CHAR(1) DEFAULT 'n' NOT NULL ENABLE,
    PCT_AUDT_USER_CREA VARCHAR2(30) DEFAULT 'PCT',
    PCT_AUDT_DTM TIMESTAMP (6) DEFAULT SYSDATE
    I have tried an alternate surrogate key, renaming the table, excluding the 160 character column etc., but not able to create this form.
    Based on this and the many hundreds of unique tabular forms we have created, seems we may have run across a bug?
    Any help would be greatly appreciated.
    Thanks!

    Hi Scott,
    Turns out we did reach some sort of limit in APEX regarding how many pages can be assigned to a tab as the current tab for assigned pages. We had around 750 or more pages listed under a given tab as the current tab for those pages, which apparently created a list of page numbers in a string presumably that exceeded the maximum size for a field somewhere in APEX apparently, thus the error about the character buffer being too small. Not only could we not create new pages, but we could not even view the tab page in the shared components area for this tab without getting the error, but could get into the tab page to view the page numbers assigned to the tab.
    To get around this we had to remove all the page numbers that were listed for the tab as the current tab for those pages. Once that was done, everything was back to normal, although the tab in question is no longer shown as the current tab for any of those pages, which is not really a problem for us.
    Anyway, seems Oracle may want to review any field limits that are related to page numbers assigned to a tab to be the current tab for those pages and consider doubling that limit. In our case, 785 pages were too many for this limit, and there were no messages that helped us deduce where this was coming from - just brute force trial and error to figure this one out. Since we have more pages to go, we might run into some limits elsewhere which I'll post here if so.
    Monte Malenke

  • How to Maintain Surrogate Key Mapping (cross-reference) for Dimension Tables

    Hi,
    What would be the best approach on ODI to implement the Surrogate Key Mapping Table on the STG layer according to Kimball's technique:
    "Surrogate key mapping tables are designed to map natural keys from the disparate source systems to their master data warehouse surrogate key. Mapping tables are an efficient way to maintain surrogate keys in your data warehouse. These compact tables are designed for high-speed processing. Mapping tables contain only the most current value of a surrogate key— used to populate a dimension—and the natural key from the source system. Since the same dimension can have many sources, a mapping table contains a natural key column for each of its sources.
    Mapping tables can be equally effective if they are stored in a database or on the file system. The advantage of using a database for mapping tables is that you can utilize the database sequence generator to create new surrogate keys. And also, when indexed properly, mapping tables in a database are very efficient during key value lookups."
    We have a requirement to implement cross-reference mapping tables with Natural and Surrogate Keys for each dimension table. These mappings tables will be populated automatically (only inserts) during the E-LT execution, right after inserting into the dimension table.
    Someone have any idea on how to implement this on ODI?
    Thanks,
    Danilo

    Hi,
    first of all please avoid bolding something. After this according Kimball (if i remember well) is a 1:1 mapping, so no-surrogate key.
    After that personally you could use Lookup Table
    http://www.odigurus.com/2012/02/lookup-transformation-using-odi.html
    or make a simple outer join filtering by your "Active_Flag" column (remember that this filter need to be inside your outer join).
    Let us know
    Francesco

  • Recieving ORA-01722 invalid number error while creating a materialized view

    Hi,
    I am receiving a ORA-01722 invalid number error while creating a materialized view. when run the select statement of the view i don't get any error, but when i use the same select statement to create a materialized view i receive this error. Could any please help in resolving this error. Here is the code i am using to create a materialized view.
    CREATE MATERIALIZED VIEW MV_EBS_CH_CLOSED
    REFRESH FORCE ON DEMAND
    AS
    SELECT DISTINCT kr.request_id, org.org_unit_name,
    ebs_ch_ticket_type (kr.request_id) ticket_type,
    DECODE
    (kr.status_code,
    'CLOSED_SUCCESS', kr.last_update_date,
    'IN_PROGRESS', (SELECT MAX (start_time)
    FROM ebs_ch_datastore ecd1
    WHERE kr.request_id = ecd1.request_id
    AND workflow_step_name =
    'Final BA Review and Deployment Exit Criteria')
    ) closed_date,
    substr(krhd.visible_parameter12,1,10) siebel_start_date,
    kr.creation_date itg_start_date
    FROM kcrt_requests kr,
    kcrt_request_types krt,
    kcrt_req_header_details krhd, kcrt_request_details krd1,
    (SELECT koum.user_id user_id,
    DECODE (koup.org_unit_name,
    'IT Implementations', 'CHS - Service Management BA',
    koup.org_unit_name
    ) org_unit_name
    FROM krsc_org_unit_members koum, krsc_org_units koup
    WHERE 1 = 1
    AND 'Y' = koup.enabled_flag
    AND koum.org_unit_id = koup.org_unit_id
    AND EXISTS (
    SELECT 'X'
    FROM krsc_org_units kouc
    WHERE koup.org_unit_id = kouc.org_unit_id
    START WITH kouc.parent_org_unit_id =
    ANY (SELECT org_unit_id
    FROM krsc_org_units krsc_org_units1
    WHERE 'Clearinghouse' =
    org_unit_name)
    CONNECT BY kouc.parent_org_unit_id =
    PRIOR kouc.org_unit_id)
    UNION
    SELECT kou.manager_id user_id,
    DECODE
    (kou.org_unit_name,
    'IT Implementations', 'CHS - Service Management BA',
    kou.org_unit_name
    ) org_unit_name
    FROM krsc_org_units kou
    WHERE 'Y' = kou.enabled_flag
    START WITH kou.parent_org_unit_id =
    (SELECT org_unit_id
    FROM krsc_org_units krsc_org_units2
    WHERE 'Clearinghouse' = org_unit_name)
    CONNECT BY kou.parent_org_unit_id = PRIOR kou.org_unit_id) org
    WHERE krt.request_type_id = kr.request_type_id
    AND krt.request_type_name IN ('Bug Fix', 'IT Enhancement')
    and kr.REQUEST_ID = krd1.request_id
    and krd1.batch_number = 1
    AND kr.request_id = krhd.request_id
    AND org.user_id in (krd1.parameter4, krd1.parameter5, krd1.parameter7)
    AND ( 'CLOSED_SUCCESS' = kr.status_code
    OR 'IN_PROGRESS' = kr.status_code
    AND kr.request_id IN (
    SELECT request_id
    FROM (SELECT DISTINCT request_id,
    MAX
    (start_time)
    closed_date
    FROM ebs_ch_datastore
    WHERE 'Final BA Review and Deployment Exit Criteria' =
    workflow_step_name
    GROUP BY request_id))
    Thanks,
    Shaik Mohiuddin

    This error occurs when you try to create a materialized view , but if you run the sql the results are perfectly fine. Well it happend to me also and to fix this I made sure all the coulmns have the same data type which are used in joins or in where clause.
    use
    where
    to_number(col1)=to_number(col2) and to_number(col3)=to_number(col4)
    hope this helps..

  • Best Practice loading Dimension Table with Surrogate Keys for Levels

    Hi Experts,
    how would you load an Oracle dimension table with a hierarchy of at least 5 levels with surrogate keys in each level and a unique dimension key for the dimension table.
    With OWB it is an integrated feature to use surrogate keys in every level of a hierarchy. You don't have to care about
    the parent child relation. The load process of the mapping generates the right keys and cares about the relation between the parent and child inside the dimension key.
    I tried to use one interface per Level and created a surrogate key with a native Oracle sequence.
    After that I put all the interfaces in to one big Interface with a union data set per level and added look ups for the right parent child relation.
    I think it is a bit too complicated making the interface like that.
    I will be more than happy for any suggestions? Thank you in advance!
    negib
    Edited by: nmarhoul on Jun 14, 2012 2:26 AM

    Hi,
    I do like the level keys feature of OWB - It makes aggregate tables very easy to implement if your sticking with a star schema.
    Sadly there is nothing off the shelf with the built in knowledge modules with ODI , It doesnt support creating dimension objects in the database by default but there is nothing stopping you coding up your own knowledge module (use flex fields maybe on the datastore to tag column attributes as needed)
    Your approach is what I would have done, possibly use a view (if you dont mind having it external to ODI) to make the interface simpler.

  • Invalid API Key Error in Ecosign API

    I'm using the sample soap code(Developer kit) given by echosign api for testping, but it always show invalid api key error while i'm executing from terminal. Please give the solution as soon as possible, and i'm not able to get solution from google also.
    This is my API Key:
    Client Secret:
    6IaJHev8N48JbsZcM4Itggzt0pAHF0iS
    I tried with this comment in terminal:
    php demo.php https://secure.echosign.com/services/EchoSignDocumentService20?wsdl 6IaJHev8N48JbsZcM4Itggzt0pAHF0iS test
    This is demo.php file:
    <?php
    // get input
    array_shift($_SERVER['argv']);
    $Url = array_shift($_SERVER['argv']);
    $ApiKey = array_shift($_SERVER['argv']);
    $cmd = array_shift($_SERVER['argv']);
    $params = $_SERVER['argv'];
    if (!$cmd) print_usage();
    $S = new SOAPClient($Url);
    call_user_func("cmd_$cmd", $params);
    function cmd_test() {
        global $Url, $ApiKey, $S;
        print "Testing basic connectivity...\n";
        $r = $S->testPing(array('apiKey' => $ApiKey));
        print "Message from server: {$r->documentKey->message}\n";
        print "Testing file transfer...\n";
        $text = file_get_contents('../test.pdf');
        $r = $S->testEchoFile(array('apiKey' => $ApiKey, 'file' => base64_encode($text)))->outFile;
        if (base64_decode($r) === $text) {
            print "Woohoo! Everything seems to work.\n";
        else {
            die("ERROR: Some kind of problem with file transfer, it seems.\n");
    function cmd_send() {
        global $Url, $ApiKey, $S;
        list($filename, $recipient) = reset(func_get_args());
        $r = $S->sendDocument(array(
            'apiKey' => $ApiKey,
            'documentCreationInfo' => array(
                    'fileInfos' => array(
                        'FileInfo' => array(
                            'file'     => file_get_contents($filename),
                            'fileName' => $filename,
                    'message' => "This is neat.",
                    'name'    => "Test from SOAP-Lite: $filename",
                    'signatureFlow' => "SENDER_SIGNATURE_NOT_REQUIRED",
                    'signatureType' => "ESIGN",
                    'tos' => array( $recipient ),
        print "Document key is: {$r->documentKeys->DocumentKey->documentKey}\n";
    function cmd_info() {
        global $Url, $ApiKey, $S;
        list($doc_key) = reset(func_get_args());
        $r = $S->getDocumentInfo(array('apiKey' => $ApiKey, 'documentKey' => $doc_key))->documentInfo;
        print "Document is in status: {$r->status}\n";
        print "Document History: ";
        foreach($r->events->DocumentHistoryEvent as $_) {
            $keytext =
              $_->documentVersionKey
              ? " (versionKey: {$_->documentVersionKey})"
            print "{$_->description} on {$_->date}$keytext\n";
        print "Latest versionKey: {$r->latestDocumentKey}\n";
    function cmd_latest() {
        global $Url, $ApiKey, $S;
        list ($doc_key, $filename) = reset(func_get_args());
        $r = $S->getLatestDocument(array('apiKey' => $ApiKey, 'documentKey' => $doc_key))->pdf;
        //$r = base64_decode($r);
        file_put_contents($filename, $r);
    function print_usage() {
        die(<<<__USAGE__
    Usage:
      demo.php <URL> <API key> <function> [parameters]
    where the function is one of:
      test
      send <filename> <recipient_email>
      info <documentKey>
      latest <documentKey> <filename>
    test will run basic tests to make sure you can communicate with the web service
    send will create a new agreement in the EchoSign system, and returns a documentKey
    info returns the current status and all the history events for a given documentKey
    latest saves the latest version of the document as a PDF with the given filename
    __USAGE__
    --------------------------  End of file ---------------------------------------------------------------

    This is my API Key:
    Client Secret:
    6IaJHev8N48JbsZcM4Itggzt0pAHF0iS
    Client secret is not the same as an api key!
    in addition to the above, integration key or access codes can be had by going to personal preferences>access code and clicking the plus sign.

  • Invalid query key/Mapping View

    Hi,
    I am mapping a view without any primary key to a ValueObject. I am selecting three fields as primary keys such that the values are unique. I am getting an exception like
    EXCEPTION DESCRIPTION: Invalid query key [lookupType] in expression.
    The expression I am having is
    Expression contactTypeExpr = builder.get("lookupType").equal("COUNTRIES");
    constantsCol = tcaServerSession.readAllObjects(ConstantsLookupVO.class, contactTypeExpr);
    Pls help me regarding this problem.
    I have created a new Class mapping in which also I am facing the same problem.
    Is there any other parameters that I have to consider while mapping objects to DB View.
    Regards
    Solomon

    This error generally occurs when the mapping for this attribute does not exists. Please ensure that the attribute you are attempting to use in the expression has a valid mapping.
    --Gordon

  • DataModeler v3.3.0 - Naming standards template for surrogate keys creation

    I'm using DM 3.3.0.734 and in the logical model we now can define in the entity properties to "Create Surrogate Key".
    When we use Engineer to relational model, for each entity is automatically created a new column using the naming template {entity}_ID as NUMERIC (without precision) and is defined as primary key.
    My questions are:
    Is possible to define a different naming standard for surrogate key creation?. We define id_{entiry}
    Is possible to set the precision of NUMERIC surrogate key?
    If we define entity's column as Primary UID, these columns are included in an unique constraint, but are using the naming standards for PK.
    As consequence are created the following:
    Unique constraint name: entity_PK
    Primary key(surrogate)name: entity_PKv1
    There is any way to define naming standards like "{entity}_UID" for unique constraints, or even, "{entity}_SK" for surrogate primary key name?
    Can anyone help with some of these topics?
    Regards,
    Ariel.

    Hi Ariel,
    Naming standards template for surrogate keys creation I logged enhancement request for that.
    How to change those bad names (going to change them one by one is not an option):
    1) If those "transformed" unique keys are the only ones you have in relational model then simply can apply naming standards
    2) You can write transformation script to do that for you
    3) you can use new functionality - search, export to excel file, change the names there (using find/replace will be faster) and return changed data back to relational model
    you can find description for that here:
    https://apex.oracle.com/pls/apex/f?p=44785:24:13179871410726::NO:24:P24_CONTENT_ID,P24_PREV_PAGE:6621,16
    http://www.thatjeffsmith.com/archive/2012/11/sql-developer-data-modeler-v3-3-early-adopter-search/
    http://www.thatjeffsmith.com/archive/2012/11/sql-developer-data-modeler-v3-3-early-adopter-collaborative-design-via-excel/
    You should search for _PK, then filter result on Index and you can export result using report functionality (to XLS or XLSX output format). You can create template and include only table and name (of index) as properties to be included into report.
    Regards,
    Philip

  • Invalid query key

    I have the following class hierarchy
    A has a one-to-many relationship with B, B has a one-to-one relationship with C, C has a one-to-one relationship with D and D has a one-to-one relationship with E. B, C, D, and E each have a derived class B1, C1, D1 and E1 respectively.
    I am getting Invalid Query Key exception while trying to access a query key defined in E1 using the following toplink code
    ExpressionBuilder.get("A").anyOf("B").get("C").get("D").get("E").get("aFieldInE1");
    Any help on this will be greatly appreciated.
    Thanks,
    Milan Dattawade.

    I assume by "derived class" you mean subclass. If so, then this query breaks polymorphism. Although you may know that you only want A's that have an E that is specifically E1, the language doesn't know that.
    Luckily there is an easy way to handle this. You can create a Query Key in the class E that has the information about the subclass attribute in E1 that you want to be able to query through. In other words, hint to TopLink that you'd like to occasionally query and break polymorphism by assuming you're querying on specific subclass attributes.
    See:
    http://download-west.oracle.com/docs/cd/B10464_01/web.904/b10313/queries.htm#1108755
    (or search your PDF for Foundation Library for "DirectQueryKey") See Javadoc for DirectQueryKey too.
    - Don

  • Invalid Query Key when using ReadAllQuery.addOrdering()

    Hi,
    I have an object called Request mapped to the Request table and a field within it called creator which is mapped to the User object with a 1-1 mapping. the User object is mapped to the user table.
    Now when I do addOrdering() with an expression as below and execute the ReadAllQuery, I get an exception which says "Invalid Query Key[lastName]".
    raq.addOrdering(raq.getExpressionBuilder().get("creator").get("lastName").ascending());
    where raq is an instance of ReadAllQuery.
    Have anyone experienced this? Any help would be much appreciated.
    Thank you,
    Sanjay Mathew.

    I double checked and the attribute names look ok.
    Please see the code below:
    SearchCriteria p_searchCriteria = new SearchCriteria();
    sc.setSortAttribute (
    "m_creatorUser.m_lastName,m_creatorUser.m_firstName");
    sc.setSortOrder(SearchCriteria.ASCENDING);
    ReadAllQuery raq = new ReadAllQuery(Request.class, queryExpression);
    if (p_searchCriteria.getSortAttribute() != null &&
    p_searchCriteria.getSortAttribute().trim().length() > 0) {
    StringTokenizer st1 =
    new StringTokenizer(p_searchCriteria.getSortAttribute(), ",");
    while (st1.hasMoreTokens()) {
    ExpressionBuilder eb = raq.getExpressionBuilder();
    String sortattr = st1.nextToken();
    StringTokenizer st2 = new StringTokenizer(sortattr, ".");
    Expression orderexpr = null;
    while (st2.hasMoreTokens()) {
    String st2Str = st2.nextToken();
    if (orderexpr == null)
    orderexpr = eb.get(st2Str);
    else
    orderexpr = orderexpr.get(st2Str);
    if (p_searchCriteria.getSortOrder() == null ||
    (p_searchCriteria.getSortOrder() != null &&
    p_searchCriteria.getSortOrder().equals(SearchCriteria.
    ASCENDING))) {
    orderexpr = orderexpr.ascending();
    } else {
    orderexpr = orderexpr.descending();
    raq.addOrdering(orderexpr);
    I tried creating the expression with hard coded attribute names as well like this:
    raq.getExpressionbuilder().get("m_creatorUser").get("m_lastName").ascending()
    In both cases I get "Invalid query key" exception.
    Sanjay.

  • Apex and Natural Vs Surrogate keys

    Hi
    We've been using Apex for a few months now and there's a debate raging in our department over whether we should design our database tables using natural or surrogate (based on Oracle sequences / triggers) keys. Our experience as Apex developers shows that Apex itself looks to lean towards surrogate keys, a few examples are below:
    - When creating forms on reports / tables Apex only allows 2 primary key columns without adding 'extras' in the background (see a previous post of mine).
    - If we have a form on a table and our natural primary keys can be updated, the Apex-created DML statements break, as they look to do the update using the changed key values in the WHERE clause rather than the old ones. The only way around this seems to be to delete the inbuilt DML statements created by Apex and code your own, which is extra work.
    - The Apex sample applications themselves seem to use sequences / surrogate keys.
    What are people's opinions on this? In particular is there any guidance from the Apex development team on which is best to use with Apex?
    Regards
    Antilles

    Hi Andrew,
    As with abots_d, I only use "natural" keys for lookups.
    >
    1. the department names were here for 20 years and they never changed
    >
    But, can you guarantee that they never will? My firm has changed departmental names so many times, it's getting ridiculous! But other things also change over time - consider what happens if a person gets married and changes their name and you've used their previous names as the keys (and consider how much data in other tables may use those keys).
    >
    2. Server names are uniquely generated by special formula in excel to preciously avoid the duplication problem and guarantee the uniqueness within our glamorous bank.
    >
    SQL could probably recreate that formula and Unique Key constraints would handle the rest
    >
    3. no, we are not going to extend this app to cover any other banks
    >
    Given what's happening with the banking industry right now, who can say ;)
    >
    4. PK that means smth ( aka "server name" ) has a meaning, whereas meaningless - has no (business) value
    >
    Why does a bit of data have to have explicit "business value"? I would suggest that a surrogate key is a pointer to a record and allows you to easily create relationships. Once created, the key would never be changed regardless of what happens to the data on its record. Thus, the relationship is maintained. Using personnel (which our firm renamed as "Human Resources" a while back) as an example, it's likely that every employee would have an employee number. Does this number actually mean anything in itself, does it have "business value"? Most likely, it's just a convenient way to identify a person and relate records to them.
    I would suggest that any non-numeric/date keys are relatively slow. As strings, the only way to check for their sort order would be to (A) convert to upper or lower case and (B) perform a string comparison left-to-right across the entire string. There's also the possibility of certain characters appearing in the strings that can cause issues - for example, quotes, apostrophes, colons, commas, question marks and percentage signs.
    Also, consider the length of a VARCHAR2 that you would have to use - how big would it need to be to cover all possibilities? You may say 20 now but tomorrow you get data with 21 characters in it - do you want to update the table plus all related tables for that?
    There are further issues with parent, child, grand-child etc relationships where the keys would have to be passed down in full through the relationships. Depending on how many levels you may have, a fair number of the fields on the bottom-most table would be there just for the keys.
    It has been a standard industry practice for many years now to "normalise databases" to avoid lots of issues with keys and "repeating data". Apart from very simple lookup tables, I have stuck with those guidelines for years now without any problems at all.
    Andy

  • Loading data into Fact/Cube with surrogate keys from SCD2

    We have created 2 dimensions, CUSTOMER & PRODUCT with surrogate keys to reflect SCD Type 2.
    We now have the transactional data that we need to load.
    The data has a customer id that relates to the natural key of the customer dimension and a product id that relates to the natural key of the product dimension.
    Can anyone point us in the direction of some documentation that explains the steps necessary to populate our fact table with the appropriate surrgoate key?
    We assume that we need to have an lookup table between the current version of the customer and the incoming transaction data - but not sure how to go about this.
    Thanks in advance for your help.
    Laura

    Hi Laura
    There is another way to handling SCD and changing Facts. This is to use a different table for the history. Let me explain.
    The standard approach has these three steps:
    1. Determine if a change has occurred
    2. End Date the existing record
    3. Insert a new record into the same table with a new Start Date and dummy End Date, using a new surrogate key
    The modified approach also has three steps:
    1. Determine if a change has occurred
    2. Copy the existing record to a history table, setting the appropriate End Date en route
    3. Update the existing record with the changed information giving the record a new Start Date, but retaining the original surrogate key
    What else do you need to do?
    The current table can use the surrogate key as the primary key with the natural key being being a unique key. The history table has the surrogate key and the end date in the primary key, with a unique key on the natural key and the end date. For end user queries which in more than 90% of the time go against current data this method is much faster because only current records are in the main table and no filters are needed on dates. If a user wants to query history and current combined then a view which uses a union of the main and historical data can be used. One more thing to note is that if you adopt this approach for your dimension tables then they always keep the same surrogate key for the index. This means that if you follow a strict Kimball approach to make the primary key of the fact table be a composite key made up of the foreign keys from each dimension, you NEVER have to rework this primary key. It always points to the correct dimension, thereby eliminating the need for a surrogate key on the fact table!
    I am using this technique to great effect in my current contract and performance is excellent. The splitter at the end of the map splits the data into three sets. Set one is for an insert into the main table when there is no match on the natural key. Set two is when there is a match on the natural key and the delta comparison has determined that a change occurred. In this case the current row needs to be copied into history, setting the End Date to the system date en route. Set three is also when there is a match on the natural key and the delta comparison has determined that a change occurred. In this case the main record is simply updated with the Start Date being reset to the system date.
    By the way, I intend to put a white paper together on this approach if anyone is interested.
    Hope this helps
    Regards
    Michael

Maybe you are looking for