In apex-code i have wrote 2 triggers. I have 2 objects A and B. I need to create records of B object when A object is created. For eg: When 1 record of Object A is created then then create 4 records of object B. I have wrote 2 trigger 1 is for default some fields in B object when A object is created (this is before insert, before update) trigger and 2 trigger is to create record of object B when record of A is created(this is after insert, after update) trigger.
But when i create i record of Object A then 4 record id created.
But when used Apex Data Loader to create records of object A at that time 2 records are created for A but for B object only 4 records are create. This is created for the second record of the A object.
i changed the code to
for(Object e : Trigger.new){
for(){
create 4 records for B object
}}
I am getting this error when i did it
Insert failed. First exception on row 0 with id abcdef12345; first error: INVALID_FIELD_FOR_INSERT_UPDATE, cannot specify Id in an insert call: [Id]
Can any body help me to solve the problem.
Thanks
Anu
The error message is telling you that you cannot assign a value to the ID field. The ID field is protected and the value for it is auto-generated by Salesforce.com.
Remove ID field from your insert statement.
Id isn't populated yet during a before insert trigger so you may be referencing it too early, maybe trying to point the B records back at the A records. Another problem would be trying to assign a value to B.Id. Both code problems are illustrated below:
trigger trigA on A__c (before insert) {
List<B__c> listB = new List<B__c>();
for (A__c a : trigger.new) {
B__c b = new B__c();
B__c.reference_to_A__c = a.Id; // <-- Wrong! a.Id isn't populated yet in before insert
B__c.Id = '...'; // <-- Wrong! Salesforce generates the Id field for you
listB.add(b);
}
insert listB;
}
It would be helpful to see more of your code.
Related
I have a mapping that gets data from multiple sql server source tables and assigns a sequence generated number as ID for each rows. In the target table, the ID field is set as primary key.
Every time I run this mapping, it creates new rows and assigns a new ID for the records that are pre-existing in the target. Below is an example:
1st run:
ID SourceID Name State
1 123 ABC NY
2 456 DEF PA
2nd run:
ID SourceID Name State
1 123 ABC NY
2 456 DEF PA
3 123 ABC NY
4 456 DEF PA
Desired Output must:
1) create a new row and assign a new ID if a record gets updated in the source.
2) create a new row and assign a new ID if new rows are inserted in the source.
How can this be obtained in Informatica?
Thank you in advance!
I'll take a flyer and assume the ACTUAL question here is 'How can I tell if the incoming record is neither insert nor update so that I can ignore it'. You could
a) have some date field in your source data to identify when the record was updated and then restrict your source qualifier to only pick up records which were last updated after the last time this mapping ran... drawback is if fields you're not interested in were updated then you'll process a lot of redundant records
b) better suggestion!! Configure a dynamic lookup which should store the latest state of a record matching by the SourceID. Then you can use the newlookuprow indicator port to tell if the record is an insert, update or no change and filter out the no change records in a subsequent transformation
Give the ID field an IDENTITY PROPERTY...
Create Table SomeTable (ID int identity(1,1),
SourceID int,
[Name] varchar(64),
[State] varchar(64))
When you insert into it... you don't insert anything for ID. For example...
insert into SomeTable
select
SourceID,
[Name],
[State]
from
someOtherTable
The ID field will be an auto increment starting at 1 and increment by 1 each time a row is inserted. In regards to your question about adding rows each time one is updated or inserted into another table, this is what TRIGGERS are for.
I have a SQL Server table which has the following columns:
Id, HeaderText, ContentText, ProposedContentId, Active
I want to maintain two versions of records that are edited by users using a website. For example, user John could edit the HeaderText and ContentText fields of the following record and click save.
Id, HeaderText, ContentText, ProposedContentId, Active
==> 1, Hello, This is a test, NULL, 1
But instead of updating that same record I want to create another record and point from the old record to new record. Now the table looks like this:
Id, HeaderText, ContentText, ProposedContentId, Active
1, Hello, This is a test, 2, 0
==> 2, Hello World, This is a new post, NULL, 1
As you can see, the old record is marked as not active and now the ProposedContentId points to the newly created row.
I don't know whether this is good solution to this problem. Please suggest better ways if there are any.
Edit: I only need to maintain two copies (old and new) and I cannot create extra tables.
I personally would not use this Active flag as a way of tracking the latest record. This type of identifier gets tricky to maintain.
I would add a content identifier to your table. Then, when a record gets changed, simply insert the new data with the same content identifier. The Id field will auto increment, or you could add a datetime field, then you can track the active record by looking at record the highest Id (or latest timestamp) for that given ContentId.
Id, ContentId HeaderText ContentText
1 1 Hello This is a test
2 1 Hello World This is a new post
3 1 Hello again! The content was changed again
4 2 New Content This is some new text
5 2 Newer Content This is that other record, updated
You could add in an active flag to this setup if you want, but it doesn't really have to be any more complex than each record having it's own identifier like a ContentId and knowing the active record by whatever has the highest ID, or latest timestamp. However you'd prefer to do it.
If you wanted to get the "active" records, all you'd need to do is run something like this:
SELECT A.*
FROM YourTable A
JOIN (
SELECT ContentId, MAX(Id) MaxId FROM YourTable GROUP BY ContentId) B
ON A.ContentId = B.ContentId AND A.Id = B.MaxId
That should give you the following:
Id, ContentId HeaderText ContentText
3 1 Hello again! The content was changed again
5 2 Newer Content This is that other record, updated
I hope this helps or at least gives you some food for thought.
I have sqlite local database. I want to insert only fresh data from remote server to local database.Since there is no time field,it is difficult to insert only new records.How can i acheive this? I require this for my hybrid mobile app. Any helps apperciated..Thanks in advance.
Two tables:
my local db table is
tbl_orders
id name age
1 yyy 30
2 xxx 20
my remote db table is
tbl_orders
id name age
1 yyy 36
2 xxx 20
3 vvv 40
4 zzz 37
In the above the remote table contains additionally two records and also the value in first record(age column) get changed.now i want to insert and update this(i.e 1st,3rd,4th) to my local sqlite table without deleting and reinserting the whole table.
You should add a UNIQUE constrain in id.
Redefining your local table:
CREATE TABLE tbl_orders(UNIQUE id, name, age);
or without redefining table
CREATE UNIQUE INDEX tbl_orders_id ON tbl_orders(id);
With constrain, your updates become a single statement:
INSERT OR REPLACE INTO local.tbl_orders SELECT * FROM remote.tbl_orders;
Your table is replicated in two DB?
If yes, you can do an INSERT with NOT EXISTS clause in WHERE condition. Alternatively, add datetime field in your source table.
Another way:
Add a boolean field in your source DB (fl_sent), populated by a trigger when create a new row in your DB or update them. Default value is false, and when you want to syncronize your DBs your select is based on this field
SELECT * FROM myTable WHERE fl_sent = 0
For a more complete answer please post your tables.
EDIT AFTER COMMENT:
Solution 1:
Add field date in your remote table (source) (if you want, you write a trigger about toggle this field) and then execute your sendable query based on this date.
Solution 2:
Add field flag (fl_sent) set by zero (if you want, you write a trigger about toggle this field) and then execute your sendable query based on this flag.
I have 3 custom objects, Object1, Object2, Object3.
Object2 is the child of Object1.
Object3 is the child of Object2.
So I want to insert multiple records into Object1, Object2, Object3.???
Well, have you actually tried anything?
Simplest action (without using advanced tricks like upsert, external ids etc) is to do it in correct sequence. On successful insert the Id of the record will be returned to the object and you can use it in the lookups to build the relationship.
Account a = new Account(Name = 'test acc');
insert a;
Contact c = new Contact(LastName = 'Test', AccountId = a.Id);
insert c;
AccountContactRole acr = new AccountContactRole(Role = 'President', AccountId = a.Id, ContactId = c.Id);
insert acr;
Alternative would be to do it in whatever order you want and later update the child records with proper references...
I have a table from which I need to insert some of its data into another table.
I have tables "Provider" and "1_MAIN - Contacts" (I know really bad name, lets just call it "Main" in this discussion). The 2 tables are linked by a column named "Contact_ID". All records in the Provider table have a record in the Main table with a matching "Contact_ID".
The "Providers" table has 4 columns called "geri", "adol", "adult", and "pedi". These fields are datatype bit with a default value of 0.
I have created 4 new columns in "Main" with the same names and want to pull the values from the "Provider" table into the "Main" table.
So basically what I want to accomplish is this:
If a "Main" record has a record in "Provider" then grab the values of the "geri", "adol", "adult", and "pedi" columns from its "Provider" record and copy them into its "Main" record.
You need UPDATE, not INSERT :
UPDATE m
SET geri = p.geri
, adol = p.adol
, adult = p.adult
, pedi = p.pedi
FROM Main m
JOIN Provider p
ON p.Contact_ID = m.Contact_ID
You're looking for "INSERT INTO...SELECT". Something like (you'll need to modify this)
Insert Into Main(geri, adol, adult, pedi)
Select p.geri, p.adol, p.adult, p.pedi
from Provider p
where p.ProviderID = Main.ProviderID
That's rough, because I haven't done it in a while, but it should get you fairly close.