SQL Stored Procedure - Customer List Import

WARNING: This is not kids stuff. Use of this feature requires expertise in SQL Server and in the Cyrious database structure. It is very possible to irreversibly damage your Cyrious Control database if you make a mistake. Always develop your tests using a separate database on a separate machine. If you are interested in using sql_bridge but are not a SQL guru, please contact a sales or consulting at Cyrious.

Note: This feature requires Control 5.75 or higher.

Overview

The stored procedure can be used to Import Customers and Contact from a CSV file into Control.

Before executing the Stored Procedure, you must add your customer list as a table. It is recommended to use the SQL Import Wizard to build your table.

  • Log into SQL Management Studio
  • Right-click on your database instance (i.e. StoreData), and navigate to Tasks > Import Data to open the SQL Server Import and Export Wizard.
  • Set the following information on the “Choose a Data Source” screen:
    • Set your data source to Flat File Source.
    • Click Browse to find your CSV.
    • Click Columns to preview your data.
    • Click Advance to set the Data Types and OutputColumnWidth
    • Click Next
  • Set the following information on the “Choose a Destination” screen:
    • Set your destination to SQL Server.
    • Verify your Server Name
    • Enter credentials for your SQL Server Authentication
    • Verify your Database
    • Click Next
  • Set your Table Name. (It will default to your CSV file name) Click Next.
  • Make “Run immediately” is checked. Click Next. Depending on your version of SQL, you may have additional permissions to save before running.
  • Click Finish.

Your table should now be added to the database.

Notes:

  • If the Customer or Contact already exist, they are updated.
  • If the Customer and Contact do not exist, they are imported.
  • If the Customer exists but not the Contact, the Customer is updated, and the contact is imported.

The stored procedure requires sql_bridge in order to obtain IDs for the inserted records. sql_bridge is a collection of SQL Server stored procedures and functions and external modules that can be called to safely insert or update data into the Control database and notify the CHAPI service that data has been updated. The CHAPI service is a controller program that will then notify the SSLIP and all copies of Control about the changes.

Example Usage

This imports and updates all Customers and Contacts.

EXEC csp_ImportCustomerList
;

Stored Procedure

The SQL to create the Customer List Import Function.

  • This must be run to create the stored procedure before it can be used.
  • This function also requires two additional SQL procedures found below. They must be run to create those functions before this method can be used.

csp_CustomerListImport

-- =============================================
-- Author:          Cyrious Sofware
-- Create date:     November-2016
-- Description:     This stored procedure imports a Customer CVS file with the
--                  following information:
--
--                  Customer
--                  Contacts
--
-- Notes:
--          ** If the Customer or Contact already exist, they are updated.
--          ** If the Customer and Contact do not exist, they are imported.
--          ** If the customer exists but not the contact, the customer is updated, and the contact is imported.
--
--          The import assumes you have had the customer/contact list as a table.
--          It is recommended to use the SQL Import Wizard to build your table.
--
-- To Enable the File Copy, you must enable SQL to run a command shell.
-- To do this, run the following commands (in order) in SQL Server Management Console.
--
-- ---- To allow advanced options to be changed.
-- EXEC sp_configure 'show advanced options', 1
-- GO
-- ---- To update the currently configured value for advanced options.
-- RECONFIGURE
-- GO
-- ---- To enable the feature.
-- EXEC sp_configure 'xp_cmdshell',1
-- GO
-- ---- To update the currently configured value for this feature.
-- RECONFIGURE
-- GO
--
-- Returns:     Table of new records
-- =============================================
ALTER PROCEDURE [dbo].[csp_ImportCustomerList]
 
-- Optional inputs - Leave off for the default value or if they don't apply
@DeveloperMode      bit             = 0         -- Show addtional information helpful for development
 
AS
BEGIN
-- Define some variables used in the import
DECLARE @Logs                               TABLE( ID INT, ClassTypeID INT, ParentID INT, IsError BIT,
Summary VARCHAR(255),
Detail VARCHAR(2000)
);
DECLARE @NewCompanies                       SMALLINT = 0;
DECLARE @NewContacts                        SMALLINT = 0;
 
DECLARE @AccountID                          INT;
DECLARE @ContactID                          INT;
DECLARE @CreateCompany                      BIT;
DECLARE @CreateContact                      BIT;
 
DECLARE @RowID                              SMALLINT;
DECLARE @CompanyName                        VARCHAR(128);
 
DECLARE @WorkPhoneAC                        VARCHAR(25);
DECLARE @WorkPhoneNumber                    VARCHAR(25);
DECLARE @WorkExtension                      VARCHAR(25);
 
DECLARE @BillingAddress1                    VARCHAR(256);
DECLARE @BillingAddress2                    VARCHAR(256);
DECLARE @BillingCity                        VARCHAR(256);
DECLARE @BillingState                       VARCHAR(256);
DECLARE @BillingPostalCode                  VARCHAR(256);
 
DECLARE @FirstName                          VARCHAR(25);
DECLARE @LastName                           VARCHAR(25);
DECLARE @POSITION                              VARCHAR(10);
DECLARE @IsPrimary                          BIT;
DECLARE @EmailAddress                       VARCHAR(50);
 
DECLARE @CellPhoneAC                        VARCHAR(10);
DECLARE @CellPhoneNumber                    VARCHAR(25);
 
DECLARE @SalespersonID                      INT;
DECLARE @SalespersonName                    VARCHAR(255);
 
SET NOCOUNT ON;
 
-- Define some error variables in case we need them
DECLARE @DT              SMALLDATETIME = GetDate();
DECLARE @ComputerName    VARCHAR(25) = @@ServerName;
DECLARE @NewLine         CHAR(2) =  CHAR(10)+CHAR(13);
DECLARE @Pos             INT = 0;
 
 
-------------------------------------------------------------------
-- Import the Customers
-------------------------------------------------------------------
--
-- Loop through the customer data in the inmport file and create them
--
DECLARE CustomerList CURSOR FOR
SELECT
CONVERT(INT, AccountID)         ,   -- AccountID
CompanyName                     ,   -- CompanyName
FirstName                       ,   -- Contact First Name
LastName                        ,   -- Contact Last Name
Title                           ,   -- Contact Title
CONVERT(Bit, IsPrimary)         ,   -- Is Primary Contact
Address1                        ,   -- Billing StreetAddress1
Address2                        ,   -- Billing StreetAddress2
City                            ,   -- Billing City
State                           ,   -- Billing State
PostalCode                      ,   -- Billing Postal Code
MainAreaCode                    ,   -- WorkPhoneAC
MainPhoneNumber                 ,   -- WorkPhoneNumber
MainExtension                   ,   -- WorkExtension
MobileAreaCode                  ,   -- Contact CellPhoneAC
MobilePhoneNumber               ,   -- Contact CellPhoneNumber
Email                           ,   -- Contact Email
Salesperson                     ,   -- Company Salesperson1 Name
CONVERT(INT, SalespersonID)         -- Employee ID
FROM ContactListImport;  -- Replace with the name of your SQL Table holding your data.
 
OPEN CustomerList;
FETCH NEXT FROM CustomerList INTO
@AccountID        ,
@CompanyName      ,
@FirstName        ,
@LastName         ,
@POSITION         ,
@IsPrimary        ,
@BillingAddress1  ,
@BillingAddress2  ,
@BillingCity      ,
@BillingState     ,
@BillingPostalCode        ,
@WorkPhoneAC      ,
@WorkPhoneNumber  ,
@WorkExtension    ,
@CellPhoneAC      ,
@CellPhoneNumber  ,
@EmailAddress     ,
@SalespersonName  ,
@SalespersonID    ;
 
WHILE @@FETCH_STATUS = 0
BEGIN
-- For each customer, create a separate transaction
BEGIN TRANSACTION
BEGIN TRY
PRINT @CompanyName;
 
 
SELECT TOP(1)
@AccountID = A.ID
FROM Account A
WHERE A.CompanyName = @CompanyName;
 
SELECT TOP(1)
@ContactID = AC.ID
FROM AccountContact AC
WHERE AC.AccountID = @AccountID;
 
SET @FirstName            = (CASE WHEN COALESCE(@FirstName, '') = '' THEN '.' ELSE @FirstName END);
SET @LastName             = (CASE WHEN COALESCE(@LastName , '') = '' THEN '.' ELSE @LastName  END);
 
 
IF (@AccountID IS NULL) -- then insert the company with the contact
BEGIN
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
EXEC csp_ImportCompany
 
-- OUTPUT Variables to Capture the Key
@AccountID            = @AccountID    OUTPUT,
@ContactID            = @ContactID    OUTPUT,
 
-- Input Variables
@CompanyName        = @CompanyName,
@SalespersonID      = @SalespersonID,
 
@WorkPhoneAC        = @WorkPhoneAC,
@WorkPhoneNumber    = @WorkPhoneNumber,
@WorkExtension      = @WorkExtension,
 
-- Company Billing Address Info
@BillingAddress1    = @BillingAddress1,
@BillingAddress2    = @BillingAddress2,
@BillingCity        = @BillingCity,
@BillingState       = @BillingState,
@BillingPostalCode  = @BillingPostalCode,
 
-- Contact #1 Information
@AddContact         = 1,
@FirstName          = @FirstName,
@LastName           = @LastName,
@EmailAddress       = @EmailAddress,
 
@CellPhoneAC        = @CellPhoneAC,
@CellPhoneNumber    = @CellPhoneNumber
;
SET @NewCompanies = @NewCompanies + 1;
SET @NewContacts  = @NewContacts  + 1;
 
UPDATE ContactListImport  -- Replace with the name of your SQL Table holding your data.
SET   AccountID = @AccountID
WHERE CompanyName = @CompanyName
;
 
PRINT '    Company and Contact Created';
END
 
ELSE IF (@ContactID IS NULL) -- then just add the contact
BEGIN
 
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
EXEC csp_ImportContact
 
-- OUTPUT Variables to Capture the Key
@ContactID            = @ContactID    OUTPUT,
 
-- INPUT Variables
@AccountID            = @AccountID,
@SalespersonID        = @SalespersonID,
 
@FirstName            = @FirstName,
@LastName             = @LastName,
@EmailAddress         = @EmailAddress,
@POSITION             = @POSITION,
 
@CellPhoneAC        = @CellPhoneAC,
@CellPhoneNumber    = @CellPhoneNumber,
 
@UseDefaultPhone    = 0,
@WorkPhoneAC        = @WorkPhoneAC,
@WorkPhoneNumber    = @WorkPhoneNumber,
@WorkExtension      = @WorkExtension
 
;
SET @NewContacts  = @NewContacts  + 1;
 
PRINT '    Company Exists; Contact Created';
END
 
ELSE
BEGIN
IF (@AccountID IS NOT NULL)
--update the company and contact with the new info from the table
 
--INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
 
-- Now update the Account
-- ----------------------------------
UPDATE PhoneNumber
SET SeqID               = SeqID + 1,
AreaCode            = @WorkPhoneAC,
PhoneNumber         = @WorkPhoneNumber,
Extension           = @WorkExtension,
FormattedText       = '('+@WorkPhoneAC+') '+ @WorkPhoneNumber + ' x' + @WorkExtension
WHERE PhoneNumber.ID = (SELECT A.MainPhoneNumberID FROM Account A WHERE A.ID = @AccountID)
;
 
UPDATE Address
SET SeqID             = SeqID + 1,
StreetAddress1    = @BillingAddress1,
StreetAddress2    = @BillingAddress2,
City              = @BillingCity,
State             = @BillingState,
PostalCode        = @BillingPostalCode,
FormattedText     = @BillingAddress1  + @NewLine + (CASE WHEN len(COALESCE(@BillingAddress2, '')) > 1 THEN @BillingAddress2 + @NewLine ELSE '' END)
+ @BillingCity + ', ' + @BillingState + '  ' + @BillingPostalCode
WHERE Address.ID = (SELECT A.BillingAddressID FROM Account A WHERE A.ID = @AccountID)
;
 
UPDATE Account
SET SeqID               = SeqID + 1,
CompanyName         = @CompanyName,
SalesPersonID1      = @SalespersonID,
PrimaryNumber       = '('+@WorkPhoneAC+') '+ @WorkPhoneNumber + ' x' + @WorkExtension
WHERE Account.ID = @AccountID
;
 
UPDATE ContactListImport  -- Replace with the name of your SQL Table holding your data.
SET   AccountID = @AccountID
WHERE CompanyName = @CompanyName
;
 
-- Now update the AccountContact
-- ----------------------------------
UPDATE AccountContact
SET
FirstName            = @FirstName,
LastName             = @LastName,
POSITION             = @POSITION,
EmailAddress         = @EmailAddress,
IsPrimaryContact     = @IsPrimary,
SalesPersonID1       = @SalespersonID,
PrimaryNumber        = '('+@WorkPhoneAC+') '+ @WorkPhoneNumber + ' x' + @WorkExtension,
SecondaryNumber      = '('+@CellPhoneAC+') '+ @CellPhoneNumber
WHERE AccountContact.ID = @ContactID
;
 
 
 
END;
 
-- and reset the variables for the next time
SET @AccountID = NULL;
SET @ContactID = NULL;
 
PRINT '    Company and Contact Updated';
 
-- Make it so, #1
COMMIT TRANSACTION;
 
END TRY
 
BEGIN CATCH
ROLLBACK TRANSACTION;
 
INSERT INTO @Logs (ID, ClassTypeID, ParentID, IsError, Summary, Detail)
VALUES(
@AccountID, 2000, NULL, 1,
'Company '+@CompanyName+'  Import FAILED due to Unhandled Exception.',
'Exception: '+ERROR_MESSAGE()
);
 
END CATCH;
 
-- Now continue to the next customer
FETCH NEXT FROM CustomerList INTO
@AccountID        ,
@CompanyName      ,
@FirstName        ,
@LastName         ,
@POSITION         ,
@IsPrimary        ,
@BillingAddress1  ,
@BillingAddress2  ,
@BillingCity      ,
@BillingState     ,
@BillingPostalCode        ,
@WorkPhoneAC      ,
@WorkPhoneNumber  ,
@WorkExtension    ,
@CellPhoneAC      ,
@CellPhoneNumber  ,
@EmailAddress     ,
@SalespersonName  ,
@SalespersonID    ;
END;
 
CLOSE CustomerList;
DEALLOCATE CustomerList;
 
 
-------------------------------------------------------------------
---- Output an Informational Summary of Results
-------------------------------------------------------------------
--
IF (@DeveloperMode = 1)
BEGIN
SELECT (CASE WHEN IsError = 1 THEN 'ERROR' ELSE 'Information' END) AS [Message TYPE], *
FROM @Logs
ORDER BY IsError DESC, ClassTypeID, COALESCE(ParentID, ID);
 
SELECT * FROM ContactListImport;  -- Replace with the name of your SQL Table holding your data.
 
END
ELSE
BEGIN
SELECT (CASE WHEN IsError = 1 THEN 'ERROR' ELSE 'Information' END) AS [Message TYPE],
Summary, ParentID, ID, ClassTypeID, Detail
FROM @Logs
ORDER BY IsError DESC, ClassTypeID, COALESCE(ParentID, ID);
END;
 
END;

Source

Contributor: Cyrious Software
Date: 11/2016
Version: Control 5.7+

You could leave a comment if you were logged in.