How to load data into target tables when column value equal to either Insert, Update, Delete or None - informatica-powercenter

I have two target tables one is target table and the other one is error table. We have Firm and Indiv source tables to be loaded into target table and error table. I am using union to pass Indiv and Firm data into the target table and error table separately which is straight move.
Now, I need to check if Firm.Action= Insert and if record already exists in target table then we are passing record to error table, if firm.action=update and present in target table we are updating else passing to error table. We also have firm.action=delete and firm.action=None then records can be ignored.

You can check presence of record int table using lookup transformation, after that in expression transformation you can evaluate your conditions.
For example,
IIF(Firm.Action= 'Insert' and is_record_in_lookup = 1, 'Error', ... )

Related

Update query in LINQ contains all columns in WHERE clause instead of just the primary key column

I am updating a single column in a table using Linq, take fictitious table below.
MyTable (PKID, ColumnToUpdate, SomeRandomColumn)
var row = (from x in DataContext.MyTable
where b.PKID == 5
select x).FirstOrDefault();
row.ColumnToUpdate = 20;
DataContext.SubmitChanges();
This updates the column to as expected, no surprises here. However when I inspect the SQL commands which are generated, it does this:
UPDATE [dbo].[MyTable ]
SET [ColumnToUpdate ] = #p2
WHERE ([PKID] = #p0) AND ([SomeRandomColumn] = #p1)
This is performing the update, but only if all columns have matched the values of what Entity expects them to be, rather than referencing the Primary Key column on it's own.
If a database column is changed by another process, which is very feasible in this particular project; eg. There is a window between getting the row you want to manipulate, calculating the changes you would like to set the value to, and issuing the update command as a batch of rows. In this situation the query will cause an exception, causing a partial update, unless I trap, reload the data and resend individual queries. It also has a downside that the row information can be quite large (ie, containing HTML mark up for instance), and the whole thing gets passed to SQL and slows the system down when larger batches are processed.
Is there a way of making Linq / Entity to issue update commands based only on the PK column in the Where clause?
I never used LINQ-to-SQL for production projects and I never were aware of it applying optimistic concurrency1 by default.
This is the default behavior:
If a table doesn't have a Timestamp/Rowversion column2, all columns have "Update Check" set to "Always" in the DBML (except primary key columns and computed columns, i.e. all updateable columns).
If a table does have a Timestamp/Rowversion column, this column has "Time Stamp" set to "True" in the DBML and all columns have "Update Check" = "Never".
Either "Update Check" or "Time Stamp" mark a column as concurrency token. That's why in update statements you see these additional predicates on (not so) "random" columns. Apparently, the tables in your model didn't have Timestamp/Rowversion columns, hence an update checks the values of all updateable columns in the table.
1 Optimistic concurrency: no exclusive locks are set when updating records, but existing values of all or selected columns are checked while updating. If one of those column value was changed by another user between getting the data and saving them, an update exception occurs.
2 A column of data type Timestamp or Rowversion is automatically incremented when a record is updated and therefore detects all concurrent changes to this record.

Oracle SQL / PLSQL : I need to copy data from one database to another

I have two instances of the same database, but data is only committed to the "original" one. I need to copy inserted data from certain tables and commit them to the same tables in the second DB automatically. How can I do it?
I've already created synonyms for the tables in the second DB on original and within a specially prepared trigger I tried to use INSERT INTO ... statement with :new. but it is causing the data to not be committed anywhere and I receive Oracle Errors like:
ORA-02291: integrity constraint (PRDBSHADOW.FK_ED_PHY_ENT) violated.
Here is my trigger code
create or replace TRIGGER INS_COPY_DATA
AFTER INSERT ON ORIGDB.TABLE_A
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
insert into COPY_TABLE_A(val1,val2,val3,val4) values (:new.val1, :new.val2, :new.val3, :new.val4);
END;
I think the entry in parent table is missing here. At least the FK ending of constraint is telling me so.
It means you need to insert first all the data into a "parent" table in order to be able to insert records in a "child".
For example the table auto_maker is having 3 rows only: Audi, Peugeot, and Honda.
Another table named "model" has 2 columns "maker" and "model". "maker" is a foreign key referencing to the "auto_maker" table.
It means in the models table are only the records allowed whose "maker" column value exists in "auto_maker" table.
In other words only these are available:
maker model
Audi A4
Peugeot 308
Honda Accord
Of course you can enter every model you wish, but "maker" value has to exist in the auto_maker table.
This is what probably happen - the trigger tries to insert a data in a column which is referencing to a "parent" table and the :new value just doesn't exist.
The following script will let you know what table you need to fill first.
select aic.index_owner, aic.table_name, aic.column_name
from all_constraints uc,
all_ind_columns aic
where aic.INDEX_NAME = uc.r_constraint_name
and uc.table_name = 'TABLE_A'
and uc.constraint_type = 'R';
If the query returns something just create similar triggers on those tables with similar logic you already have

Greenplum - Update statement failing on timestamp column

We have source and target table in greenplum database. we are comparing both the table using sql script.
But Update is not working here. and it is not updating the timestamp column of target table with respect to source table.
Input - Source/target table structure
CREATE TABLE sysprocompanyb.target_customer_table
(
time timestamp without time zone,
"Customer" character(20),
)
DISTRIBUTED BY ("ID");
Noted this
However found this, on Execution of below update statement it is not throwing any error. it is saying Updated all rows successfully. But when i am checking after process completion target timestamp column field is not equal to source timestamp column field.
We tried :
BEGIN;
insert into schemaname.target_customer_table select s.* from schemaname.source_customer_table s LEFT JOIN schemaname.target_customer_table d ON s."Customer"=d."Customer" where d."Customer" is null;
UPDATE schemaname.target_customer_table d
SET "time" = d."time"
FROM schemaname.source_customer_table s
WHERE s."Customer" = d."Customer";
Output
We want to match source and target column after completion of above SQL Transaction.
Any help on it would be much appreciated?

In Hive, how can I add a column only if that column does not exist?

I would like to add a new column to a table, but only if that column does not already exist.
This works if the column does not exist:
ALTER TABLE MyTable ADD COLUMNS (mycolumn string);
But when I execute it a second time, I get an error.
Column 'mycolumn' exists
When I try to use the "IF NOT EXISTS" syntax that is supported for CREATE TABLE and ADD PARTITION, I get a syntax error:
ALTER TABLE MyTable ADD IF NOT EXISTS COLUMNS (mycolumn string);
FAILED: ParseException line 3:42 required (...)+ loop did not match anything at input 'COLUMNS' in add partition statement
What I need is something that can execute itempotently so I can run my query whether this column exists or not.
You can partially work it around, by setting the hive.cli.errors.ignore flag. In this case hive CLI will force the execution of further queries even when queries on the way fail.
In this example:
SET hive.cli.errors.ignore=true;
ALTER TABLE MyTable ADD COLUMNS (mycolumn string);
ALTER TABLE MyTable ADD COLUMNS (mycolumn string);
ALTER TABLE MyTable ADD COLUMNS (mycolumn2 string);
hive will execute all queries, even though there'll be an error in the second query.
Well there is no direct way to do that. I mean through a single query.
There are two other ways:
1.) Using JDBC:
1.1) Do describe on the table name.
1.2) You will get a list of columns in result set.
1.3) Check if your columns exists or not by iterating through the result set.
2.) Using hive Metastore client:
2.1) Create a object of HiveMetastoreClient
2.2) HiveMetastoreClient.getFields(<>db_name, <table_name>).get(index).getName() will give you the column name.
2.3) Check if your column exists of not by comparing the list.
Hope it helps...!!!

Not able to update data in target table in ETL

i have taken target table as my lookup table using static cache.in source i have duplicate values.
in mapping i ahve used update strategy transformation but not i m not able update data in target table
Example:Initially(i mean after session Load)
source table Lookup table Target table
ID Name ID Name ID Name
1 A 1 A 1 A
2 B 2 B
Now im inserting two more records
3 C
1 E
but its not updating below record
1 E
i am getting below error
One or more values in the INSERT statement, UPDATE statement, or foreign key update caused by a DELETE statement are not valid because the primary key, unique constraint or unique index identified by "1" constrains table "TABLE_NAME" from having duplicate values for the index key.
I know if i use dynamic lookup it will work correctly but in static.
please give the reason ASAP.

Resources