• SFDC_Lance
  • NEWBIE
  • 0 Points
  • Member since 2013

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 3
    Replies

Hi,

Now I know that Bulk API not for the master + detail insert in single shot.

What you guys think if I create a new object (say temp) which holds master + details and use the Bulk API to load data.

Once the Bulk API finish the job then trigger/call a web service which will now move from this temp to respective master + detail.

 

Do you think this is an acceptable solution?

We are loading 10K records in Bulk API. Do see any DML Limitation or Governors Issue with this approach.

 

Please advices - Thanks

 

Lance

How to update master & detail in one shot using Bulk Api.  

Currently we have CSHistory as Header & CSHistory Items as Details. 2 Objects in SFDC.

 

Can we able to create header and details in single shot? using bulk api. if so can you please show me an example

 

Thank you

 

Regards,

Lance

Hi,

Now I know that Bulk API not for the master + detail insert in single shot.

What you guys think if I create a new object (say temp) which holds master + details and use the Bulk API to load data.

Once the Bulk API finish the job then trigger/call a web service which will now move from this temp to respective master + detail.

 

Do you think this is an acceptable solution?

We are loading 10K records in Bulk API. Do see any DML Limitation or Governors Issue with this approach.

 

Please advices - Thanks

 

Lance

How to update master & detail in one shot using Bulk Api.  

Currently we have CSHistory as Header & CSHistory Items as Details. 2 Objects in SFDC.

 

Can we able to create header and details in single shot? using bulk api. if so can you please show me an example

 

Thank you

 

Regards,

Lance

Below is the code in C# for Bulk Api.


 

  using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.VisualBasic;
    using System.Collections;
    using System.Data;
    using System.Diagnostics;
    using System.Xml;
    using System.IO;
    using System.Net;
    
    
    namespace ConsoleApplication7
    {
        class Program
        {
    
           
            private static SForceService.SforceService bindingService { get; set; }
    
    
            private static void QueryUsingBulkAPI()
            {
                string jobId = string.Empty;
                string resultId = string.Empty;
                string batchId = string.Empty;
                //new code
                Console.Write("Enter user name: ");
                string userName = Console.ReadLine();
    
    
                Console.Write("Enter password: ");
                string password = Console.ReadLine();
    
    
    
                ////Provide feed back while we create the web service binding    
                Console.WriteLine("Creating the binding to the web service...");
    
                // Create the binding to the sforce servics
                bindingService = new SForceService.SforceService();
    
                // Set the time out value
                bindingService.Timeout = 60000;
    
                ////Attempt the login giving the user feedback
                Console.WriteLine("LOGGING IN NOW....");
    
    
    
                try
                {
                    SForceService.LoginResult loginRes = bindingService.login(userName, password);
                    Console.WriteLine(loginRes);
                    Console.WriteLine( "The session id is: " + loginRes.sessionId);
                    Console.WriteLine("The new server url is: " + loginRes.serverUrl);
    
                    //Change the binding to the new endpoint
                    bindingService.Url = loginRes.serverUrl;
    
                    //Create a new session header object and set the session id to that returned by the login
                    bindingService.SessionHeaderValue = new SForceService.SessionHeader();
                    bindingService.SessionHeaderValue.sessionId = loginRes.sessionId;
                    Debug.WriteLine(loginRes.sessionId);
                   
                    CreateJob(loginRes.sessionId, "query", "Case", ref jobId);
                    //e.g for inserting contact
                    //Dim jobId As String = CreateJob(loginRes.sessionId, "insert", "Contact")
    
                    byte[] inputFileData = null;
    
                    if ((jobId.Length > 0))
                    {
                        //data loading using a sampe file
                        // Open a file that is to be loaded into a byte array
                        System.IO.FileInfo oFile = null;
                        //oFile = New System.IO.FileInfo("data.csv")
                        oFile = new System.IO.FileInfo("request.txt");
    
                        System.IO.FileStream oFileStream = oFile.OpenRead();
                        long lBytes = oFileStream.Length;
                        int a = (int)lBytes; //modified after conversion
                        if ((lBytes > 0))
                        {
                            byte[] fileData = new byte[lBytes];
                            // Read the file into a byte array
                            oFileStream.Read(fileData, 0, a);   //modified after conversion
                            oFileStream.Close();
    
                            //Get the file where the Query is present
                            inputFileData = fileData;
                        }
    
                        //Adds the batch to SalesForce
                        AddBatch(loginRes.sessionId, inputFileData, jobId, batchId, resultId);
    
                        //Check Status and Get BatchId and ResultsId
                        GetStatusAndRetrieveBatchIdAndResultsId(loginRes.sessionId, jobId, ref batchId, ref resultId);
    
                        //Get Results Id
                        RetrieveResults(loginRes.sessionId, jobId, batchId, resultId);
                    }
                }
                catch (System.Web.Services.Protocols.SoapException e)
                {
                    //// This is likley to be caused by bad username or password
                    Console.Write(e.Message + ", please try again." + "Hit return to continue...");
                    Console.ReadLine();
    
                }
                catch (Exception ex)
                {
                    //// This is something else, probably comminication
                    Console.Write(ex.Message + ", please try again." +   "Hit return to continue...");
                    Console.ReadLine();
    
                }
    
    
    
                //new code end
                //Used to create the Job in SalesForce--
                //the Job can be query, insert, delete etc...This is the operation parameter
                //eg for querying Case
    
    
    
    
    
            }
    
            /// <summary>
            /// Creates a job in Salesforce
            /// </summary>
            /// <param name="sfSessionId"></param>
            /// <param name="sfOperation"></param>
            /// <param name="sfObjectName"></param>
            /// <param name="jobId"></param>
            /// <remarks></remarks>
    
            public static void CreateJob(string sfSessionId, string sfOperation, string sfObjectName, ref string jobId)
            {
                string str = "";
                string reqURL = "";
                byte[] bytes = null;
                XmlDocument reqDoc = null;
                XmlDocument responseXmlDocument = new XmlDocument();
    
                str = "" + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<jobInfo xmlns=\"http://www.force.com/2009/06/asyncapi/dataload\">" + "    <operation></operation>" + "    <object></object>" + "    <contentType>CSV</contentType>" + "</jobInfo>";
                //Eg for XML content type
                //"    <contentType>XML</contentType>" &
    
                reqURL = "https://na1.salesforce.com/services/async/28.0/job";
                reqDoc = new XmlDocument();
                reqDoc.LoadXml(str);
                // added XML modifications
                reqDoc.GetElementsByTagName("operation")[0].InnerText = sfOperation;
                reqDoc.GetElementsByTagName("object")[0].InnerText = sfObjectName;
                bytes = System.Text.Encoding.ASCII.GetBytes(reqDoc.InnerXml);
                //bytes = System.Text.Encoding.UTF8.GetBytes(reqDoc.InnerXml)
               
                using (Stream responseStream = Post(bytes, reqURL, sfSessionId, "POST", "text/csv; charset=UTF-8"))
                {
                    responseXmlDocument.Load(responseStream);
                    //Get jobId
                    jobId = ((((responseXmlDocument) != null)) ? responseXmlDocument.GetElementsByTagName("id").Item(0).InnerText : "");
                }
    
            }
    
            /// <summary>
            /// Adds the Batch to SalesForce
            /// </summary>
            /// <param name="sfSessionId"></param>
            /// <param name="fileBytes"></param>
            /// <param name="sfJobId"></param>
            /// <param name="sfBatchId"></param>
            /// <param name="sfResultId"></param>
            /// <remarks></remarks>
    
            public static void AddBatch(string sfSessionId, byte[] fileBytes, string sfJobId, string sfBatchId = null, string sfResultId = null)
            {
                string requestURI = ("https://login.salesforce.com/services/async/23.0/job/" + (sfJobId + "/batch"));
                Post(fileBytes, requestURI, sfSessionId, "POST", "text/csv; charset=UTF-8");
    
            }
    
            /// <summary>
            /// Once the batch is added get the BatchId and then
            /// once the processing is done , get the Results ID
            /// </summary>
            /// <param name="sfSessionId"></param>
            /// <param name="sfJobId"></param>
            /// <param name="batchId"></param>
            /// <param name="resultId"></param>
            /// <remarks></remarks>
    
            public static void GetStatusAndRetrieveBatchIdAndResultsId(string sfSessionId, string sfJobId, ref string batchId, ref string resultId)
            {
    
                XmlDocument responseXmlDocument = new XmlDocument();
                string reqURL = ("https://na1.salesforce.com/services/async/23.0/job/" + sfJobId + "/batch");
                //Get BatchId
                using (System.IO.Stream responseStream = Post(null, reqURL, sfSessionId, "GET", "text/csv; charset=UTF-8"))
                {
                    responseXmlDocument.Load(responseStream);
                    batchId = ((((responseStream) != null)) ? responseXmlDocument.GetElementsByTagName("id").Item(0).InnerText : "");
                }
    
                //Get ResultId
                reqURL = ("https://na1.salesforce.com/services/async/23.0/job/" + (sfJobId + "/batch/" + batchId + "/result"));   
                using (System.IO.Stream responseStream = Post(null, reqURL, sfSessionId, "GET", "text/csv; charset=UTF-8"))
                {
                    responseXmlDocument.Load(responseStream);
                    resultId = ((((responseStream) != null)) ? responseXmlDocument.GetElementsByTagName("result").Item(0).InnerText : "");
                }
    
            }
    
            /// <summary>
            /// Post the rest call with batch id and results id to get the output
            /// </summary>
            /// <param name="sfSessionId"></param>
            /// <param name="sfJobId"></param>
            /// <param name="sfBatchId"></param>
            /// <param name="sfResultId"></param>
            /// <remarks></remarks>
    
            public static void RetrieveResults(string sfSessionId, string sfJobId, string sfBatchId, string sfResultId)
            {
                string reqURL = ("https://na1.salesforce.com/services/async/23.0/job/" + (sfJobId + "/batch/" + sfBatchId + "/result/" + sfResultId));  
                string localFile = "output.csv";
                //Create the output file
                using (System.IO.Stream responseStream = Post(null, reqURL, sfSessionId, "GET", "text/csv; charset=UTF-8"))
                {
                    using (System.IO.FileStream fsOutputFile = new System.IO.FileStream(localFile, FileMode.Create, FileAccess.Write))
                    {
                        byte[] buffer = new byte[2048];
                        int read = 0;
                        do
                        {
                            read = responseStream.Read(buffer, 0, buffer.Length);
                            fsOutputFile.Write(buffer, 0, read);
                        } while (!(read == 0));
                        responseStream.Close();
                        fsOutputFile.Flush();
                        fsOutputFile.Close();
                    }
                    responseStream.Close();
                }
    
            }
    
            /// <summary>
            /// Function to POST the HTTP rest request
            /// </summary>
            /// <param name="bytes"></param>
            /// <param name="reqURL"></param>
            /// <param name="sfSessionId"></param>
            /// <param name="method"></param>
            /// <param name="contentType"></param>
            /// <returns></returns>
            /// <remarks></remarks>
            public static Stream Post(byte[] bytes, string reqURL, string sfSessionId, string method, string contentType)
            {
    
                //Create the request object
                WebRequest requestHttp = WebRequest.Create(reqURL);
                //Assign the type of request POST,GET..
                requestHttp.Method = method;
                //Assign Content Type
                requestHttp.ContentType = contentType;
                //"text/csv; charset=UTF-8" or "application/xml; charset=UTF-8"
                //Assign the session id to the header
                requestHttp.Headers.Add(("X-SFDC-Session: " + sfSessionId));
    
                //Assign byte length
                if ((bytes != null))
                {
                    requestHttp.ContentLength = bytes.Length;
    
                    System.IO.Stream strmHttpContent = requestHttp.GetRequestStream();
                    strmHttpContent.Write(bytes, 0, bytes.Length);
                    strmHttpContent.Close();
    
                }
    
                //Get the response object
              
               String responseFromServer;
              try
                {
                    //Call the service and get the response
                    HttpWebResponse response = (HttpWebResponse)requestHttp.GetResponse();
    
                    if (HttpStatusCode.OK == response.StatusCode)
                    {
                        Stream dataStream = response.GetResponseStream();
                        StreamReader reader = new StreamReader(dataStream);
                       responseFromServer = reader.ReadToEnd();
                        response.Close();
                    }
                }
                catch (WebException e)
                {
                    using (WebResponse response = e.Response)
                    {
                        HttpWebResponse httpResponse = (HttpWebResponse)response;
                        responseFromServer = string.Format("Error code: {0}  ", httpResponse.StatusCode);
                        using (Stream data = response.GetResponseStream())
                        {
                            responseFromServer += new StreamReader(data).ReadToEnd();
                         //   return responseFromServer;
                            Console.WriteLine("reponse from server" + responseFromServer);
                        }
                    }
                }
                //Return response Stream
                WebResponse responseHttpRequest = requestHttp.GetResponse();
                return responseHttpRequest.GetResponseStream();
    
    
            }
            static void Main(string[] args)
            {
                QueryUsingBulkAPI();
            }
        }
    }

 


 

Its returning the following output with Error:

Enter user name: sfuserid
Enter password: paswd+token
Creating the binding to the web service...
LOGGING IN NOW....
ConsoleApplication7.SForceService.LoginResult
The session id is: 00D90000000k6uO!ARoAQH02gPYFrZmt2RDkBNSXKZrEZLQv9jmAh2lXPaqAp
AsEu0zUbpTUC5mDn0FIHk2cCeYMuDjEIJeXnVfn.ccD1jW31IM3
The new server url is: https://ap1.salesforce.com/services/Soap/u/28.0/00D900000
00k6uO
reponse from serverError code: BadRequest  <?xml version="1.0" encoding="UTF-8"?
><error
   xmlns="http://www.force.com/2009/06/asyncapi/dataload">
 <exceptionCode>InvalidSessionId</exceptionCode>
 <exceptionMessage>Invalid session id</exceptionMessage>
</error>
The remote server returned an error: (400) Bad Request., please try again.Hit
return to continue...

Please help me resolve the Error.The bad request is due to invalid session id,but when i am printing the session id it has a valid value.Please tell me where the prblm is in the above code.

Thanks in advance.