Stored procedure for selecting table rows from a date range used to populate two other tables
I'm not sure why you need a recursive CTE. If you just need to split the data into two tables based on a date range you can do the following:

CREATE PROCEDURE FillTables
(
    @dateFrom DATETIME,
    @dateTo DATETIME
)
AS
BEGIN
SET NOCOUNT ON;

BEGIN TRANSACTION;
BEGIN TRY

    -- GET ONLY THE DATA WE NEED AND CACHE IT
    SELECT doc_num, doc_date, shop_name, shop_address
      INTO #results
      FROM dbo.shipment_data
     WHERE doc_date BETWEEN @dateFrom AND @dateTo;

    -- ADD THE SHOPS TO GENERATE THE ID's 
    -- (COULD USE OUTPUT HERE AS AN ALTERNATIVE)
    INSERT dict_shops (shop_name, shop_address)
    SELECT DISTINCT shop_name, shop_address
      FROM #results
    EXCEPT
    SELECT DISTINCT shop_name, shop_address
      FROM dict_shops;

    -- JOIN ON THE NEWLY CREATED SHOPS TO POPULATE SHIPMENT DOCS
    INSERT shipment_docs (doc_num, doc_date, shop_id)
    SELECT DISTINCT r.doc_num, r.doc_date, s.shop_id
      FROM #results AS r 
      JOIN dict_shops AS s
        ON s.shop_name = r.shop_name
       AND s.shop_address = r.shop_address;

COMMIT;
END TRY
BEGIN CATCH

     IF @@TRANCOUNT &gt; 0
        ROLLBACK;
     THROW;

END CATCH

END