Q:

How can I optimize below SQL code? 

I have created a stored procedure in SQL Server which uses two tables tbPOValidation and tbPOValidationTemp.  
If a row of tbPOValidationTemp is present in tbPOValidation, then update tbPOValidation with the value from tbPOValidationTemp.  
If it is not present, then insert the row of tbPOValidationTemp to tbPOValidation.  
This SQL does that job, but I think what I am doing is not safe.  In what ways can I optimise the code and make it safer so that it does the job correctly? 
CREATE PROCEDURE spPOValidation
AS
BEGIN
    SET NOCOUNT ON;

    IF NOT EXISTS(SELECT * 
                  FROM tbPOValidation 
                  WHERE ShoppingCartNo IN (SELECT ShoppingCartNo 
                                           FROM tbPOValidationTemp)
                    AND LineItemNo IN (SELECT LineItemNo 
                                       FROM tbPOValidationTemp) 
                    AND PONo IN (SELECT PONo FROM tbPOValidationTemp))
    BEGIN
        INSERT INTO tbPOValidation (SupplierName, DUNS, PONo, LineItemNo, PurchDocItemDesc, POIssueDate, DeliveryDate, PurchDocType, MtrNo,
        Location, PayTerms, BlanketNo, BlanketLineItemNo, ShoppingCartNo, SHCItmNo, ItemPricing, ItmPrcCurrency, Per, POValue, POValueCurrency,
        Qty, UOM, MFGName, MFGPartNO, Description, Remarks, Accept, AcceptedBy, AcceptedOn, RejectionReason)
            SELECT 
                SupplierName, DUNS, PONo, LineItemNo, PurchDocItemDesc, 
                POIssueDate, DeliveryDate, PurchDocType, MtrNo,
                Location, PayTerms, BlanketNo, BlanketLineItemNo, 
                ShoppingCartNo, SHCItmNo, ItemPricing, ItmPrcCurrency, Per, 
                POValue, POValueCurrency, Qty, UOM, MFGName, MFGPartNO, 
                Description, Remarks, Accept, AcceptedBy, AcceptedOn, RejectionReason 
            FROM 
                tbPOValidationTemp
    END
    ELSE
    BEGIN
        UPDATE t
        SET t.SupplierName = v.SupplierName, t.DUNS = v.DUNS, 
            t.PONo = v.PONo, t.LineItemNo = v.LineItemNo, 
            t.PurchDocItemDesc = v.PurchDocItemDesc,
            t.POIssueDate = v.POIssueDate, t.DeliveryDate = v.DeliveryDate, 
            t.PurchDocType = v.PurchDocType, t.MtrNo = v.MtrNo, 
            t.Location = v.Location, t.PayTerms = v.PayTerms, 
            t.BlanketNo = v.BlanketNo, 
            t.BlanketLineItemNo = v.BlanketLineItemNo, 
            t.ShoppingCartNo = v.ShoppingCartNo, 
            t.SHCItmNo = v.SHCItmNo, t.ItemPricing = v.ItemPricing, 
            t.ItmPrcCurrency = v.ItmPrcCurrency, t.Per = v.Per, 
            t.POValue = v.POValue, t.POValueCurrency = v.POValueCurrency, 
            t.Qty = v.Qty, t.UOM = v.UOM, t.MFGName = v.MFGName, 
            t.MFGPartNO = v.MFGPartNO, t.Description = v.Description, 
            t.Remarks = v.Remarks, t.Accept = v.Accept, 
            t.AcceptedBy = v.AcceptedBy, t.AcceptedOn = v.AcceptedOn, 
            t.RejectionReason = v.RejectionReason
        FROM
            tbPOValidation t
        JOIN 
            tbpovalidationtemp v ON t.ShoppingCartNo = v.ShoppingCartNo 
                                 AND t.LineItemNo = v.LineItemNo 
                                 AND t.PONo = v.PONo
    END

    TRUNCATE TABLE tbPOValidationTemp
END

A:

Your update portion will naturally limit results to those that exist, thanks to your INNER JOIN predicate.   You can use this same logic to re-write your insert portion with a LEFT JOIN for records that don't exist:
INSERT INTO tbPOValidation (SupplierName, DUNS, PONo, LineItemNo, PurchDocItemDesc, POIssueDate, DeliveryDate, PurchDocType, MtrNo,
                Location, PayTerms, BlanketNo, BlanketLineItemNo, ShoppingCartNo, SHCItmNo, ItemPricing, ItmPrcCurrency, Per, POValue, POValueCurrency,
                Qty, UOM, MFGName, MFGPartNO, Description, Remarks, Accept, AcceptedBy, AcceptedOn, RejectionReason)
SELECT SupplierName, DUNS, PONo, LineItemNo, PurchDocItemDesc, POIssueDate, DeliveryDate, PurchDocType, MtrNo,
           Location, PayTerms, BlanketNo, BlanketLineItemNo, ShoppingCartNo, SHCItmNo, ItemPricing, ItmPrcCurrency, Per, POValue, POValueCurrency,
           Qty, UOM, MFGName, MFGPartNO, Description, Remarks, Accept, AcceptedBy, AcceptedOn, RejectionReason 
FROM tbPOValidationTemp T
LEFT JOIN tbPOValidation T2 on T.ShoppingCartNo = T2.ShoppingCartNo
                               and T.LineItemNo = T2.LineItemNo
                               and T.PONo = T2.PONo
WHERE T2.ShoppingCartNo IS NULL --NULL filter to complete anti-join and only 
                                --insert records that do not exist

Then simply do your update after.   This removes all the confusing if logic and in() subqueries, and to me, is much easier to read.   Note that I am assuming you want to check for a match of ShoppingCartNo, LineItemNo, and PONo across a complete record, and not just check for their existence in the main table.