System Setup

Rebuilding a corrupted Store Table.

Overview

The Guide will take you through the SQL Script process in order repair a Store Table where the StoreID's are not Sequential , ie 1, 2, 3. 

There are instances of Databases where a Venue might have been converted from a multivenue to a single site and the Store numbers are now not sequential or starting from StoreID 1, instead they have StoreID's like 127, 130, 138 etc 

This results in other errors for functions like Handling Fee where the Handling fee Array cannot populate due to the corrupted StoreID's

Prerequisites​​​​​​​

  • SSMS

Full Backup

Make a full backup of the database before proceeding, encase you have to roll back. 

Login to SSMS

The following script was used to identify all the Tables where StoreID is being used. 

This is purely for reference but useful to know where the changes are going to take place.

--All Tables that contain StoreID

SELECT t.name AS table_name,

SCHEMA_NAME(schema_id) AS schema_name,

c.name AS column_name

FROM sys.tables AS t

INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID

WHERE c.name LIKE '%StoreID%'

ORDER BY schema_name, table_name;

Identify the current Store Records

Do a select query and make notes of the current StoreID's

--Verify Stores

Select * from Store

Change the SEED Numbering on Store Table

This will set the Record numbering to start from StoreID 1 

--Reset SEED  

DBCC CHECKIDENT (Store, RESEED, 0)

Set Identity insert for the Store Table to ON

--Change IDENTITY Insert

SET IDENTITY_INSERT Store ON

Correct the Store Records to Start from 1

Edit the Store Table and Copy the Existing Stores as New Stores Records

This has to be done as you cannot change the StoreID's as they are Primary Keys

Please see Video on the Right to show an example of the process.

Set Identity insert for the Store Table to OFF

--Change IDENTITY Insert

SET IDENTITY_INSERT Store OFF

Verify the Current Store List 

This should include the Old Store Records and the New Store Records

Where the NEW Store Records ID's should number 1, 2 and 3 

Delete the OLD Store Records 

Now that the NEW Store Records are in place we need to remove the OLD Store Records

--Delete old Stores

Delete Store where StoreID not in (1,2,3)

Verify the Current Store List 

This should include the New Store Records only.

--Verify Stores

Select * from Store

Correcting the StoreID Records for All Tables per Store

The following script is used to create a TempDB that houses all the SQL Script required to update the StoreID's per Store. 

So for example, if the site has 3 Stores you will have to run the Script 3 times with amendments to the OrgStoreID and NewStoreID Values within the Script.

In our example, the Orginal StoreID for the Bar Store was '120', and the New StoreID is now '1'

So below pointed out in green we have to: SET @OrgStoreID = 120 and  SET @NewStoreID = 1

Run the Script, it will loop through each table and set the StoreID's to the new value.

Repeat the process for any additional stores i.e Bistro Original StoreID was 137 is it now StoreID 2

--Builds a tempDB with SQLSCRIPTS.

IF OBJECT_ID('tempdb..#BaseData') IS NOT NULL DROP TABLE #BaseData

GO

CREATE TABLE #BaseData (Schema_Name sysname, Table_Name sysname, Field_Name sysname, SQLScript varchar(max));

DECLARE @FieldName varchar(20)

SET @FieldName = '%StoreID%'

DECLARE @OrgStoreID int

--Set Orignal StoreID below.... 

SET @OrgStoreID = 120       --<<<CHANGE VALUE HERE

DECLARE @NewStoreID int

--Set New StoreID below.... 

SET @NewStoreID = 1        --<<<CHANGE VALUE HERE

INSERT INTO #BaseData (Schema_Name, Table_Name, Field_Name, SQLScript)

SELECT

s.name

,o.name 

,c.name

,'update ' + s.name + '.' + o.name + ' SET ' + c.name + ' = ' + CONVERT(VARCHAR(20),@NewStoreID) + ' where ' + c.name + ' = ' + CONVERT(VARCHAR(20),@OrgStoreID) 

FROM sys.columns c

JOIN sys.types t

    ON c.user_type_id = t.user_type_id

JOIN sys.objects o

    ON c.object_id = o.object_id

JOIN sys.schemas s ON o.schema_id=s.schema_id

WHERE c.name LIKE @FieldName 

    AND o.type_desc = 'USER_TABLE'

    AND o.name not like 'Store';

    SELECT * FROM #BaseData

-- THIS LOOPS THROUGH THE TEMPDB AND RUNS ALL THE SQLSCRIPTS FOR THE STOREIDS

DECLARE @sql VARCHAR(MAX)

DECLARE @SqlScript VARCHAR(max)

DECLARE c CURSOR LOCAL FAST_FORWARD FOR

    SELECT SQLScript

    FROM #BaseData;

OPEN c;

FETCH NEXT FROM c INTO @SQLScript;

WHILE @@FETCH_STATUS = 0

BEGIN

    SET @sql = @SqlScript

    EXEC(@sql); 

    FETCH NEXT FROM c INTO @SQLScript;

END

CLOSE c;

DEALLOCATE c;

Renumber Stores Sequentially v1.00 (10/03/23) by Jamie Bradshaw 

/*

Renumber Stores Sequentially v1.00 (10/03/23) by Jamie Bradshaw (jamie@bepoz.com.au)

Based on previous script concept by Calvin Schentke

Version agnostic

Renumbers store table sequentially and dynamically updates all storeid fields in Bepoz database

Updates store table to respect redirects

No user input necessary.

*/

--Take a copy to reinsert into store, keep a second copy incase things go wrong.

select * into storebackup from store 

select * into storebackupkeep from store --This will error and stop script being run more than once, it also keeps an original copy of the store table.

-- Delete and Reseed Store table

delete from store 

dbcc checkident('store', reseed, 0)

--Variables to dynamically build store insert query

declare @columnname varchar(max) = ''

declare @storecolumns varchar(max) = ''

declare @insertquery varchar(max) = ''

--Cursor to populate insert query column names

declare cursor_createquery cursor

for 

select c.name as col 

from sys.columns c join sys.tables t on c.object_id = t.object_id 

where t.name = 'Store' and c.name != 'StoreId' --Exclude Identity Column

-- Build list of columns in store table into insert format

open cursor_createquery

fetch next from cursor_createquery into @columnname

while @@FETCH_STATUS = 0

begin

set @storecolumns += @columnname + ','

fetch next from cursor_createquery into @columnname

end

close cursor_createquery

deallocate cursor_createquery

--Trim last comma

set @storecolumns = left(@storecolumns, len(@storecolumns)-1)

-- Build dynamic insert query

set @insertquery = 'insert into store '

set @insertquery += '(' + @storecolumns + ')' -- Field List

set @insertquery += '(select ' + @storecolumns + ' from storebackup)'

-- Insert storebackup back into store allowing identity column to provide sequential ids

exec sp_sqlexec @insertquery

--Link old store numbers to new store numbers

select s.name, sb.storeid as oldstoreid, s.storeid as newstoreid

into #tempstore

from storebackup sb join store s on s.name = sb.name

--Create queries to update storeid in all tables containing storeid (exclude store/storebackup, fixed later)

select t.name as [table], c.name as [column], ts.oldstoreid, ts.newstoreid, 'Update ' + t.name + ' set ' + c.name + ' = ' + cast(ts.newstoreid as varchar) + ' where ' + c.name + ' = ' +  cast(ts.oldstoreid as varchar) as query

into #tempquery

from sys.columns c join sys.tables t on c.object_id = t.object_id

join #tempstore ts on 1=1

where c.name like '%StoreId%'

and t.name not in ('store', 'storebackup', 'storebackupkeep')

declare @storeupdatequery varchar(max)

--Exec dynamic update queries created in previous step

declare cursor_fixstores cursor

for 

select query from #tempquery

open cursor_fixstores

fetch next from cursor_fixstores into @storeupdatequery

while @@FETCH_STATUS = 0

begin

exec sp_sqlexec @storeupdatequery

fetch next from cursor_fixstores into @storeupdatequery

end

close cursor_fixstores

deallocate cursor_fixstores

--Update Store Table to respect redirects

--Restock

update s set s.restockedfrom = ts.newstoreid

from store s join #tempstore ts on s.restockedfrom = ts.oldstoreid

where s.restockedfrom = ts.oldstoreid

--AltStores

update s set s.altstoretype0 = ts.newstoreid

from store s join #tempstore ts on s.altstoretype0 = ts.oldstoreid

where s.altstoretype0 = ts.oldstoreid

update s set s.altstoretype1 = ts.newstoreid

from store s join #tempstore ts on s.altstoretype1 = ts.oldstoreid

where s.altstoretype1 = ts.oldstoreid

update s set s.altstoretype2 = ts.newstoreid

from store s join #tempstore ts on s.altstoretype2 = ts.oldstoreid

where s.altstoretype2 = ts.oldstoreid

update s set s.altstoretype3 = ts.newstoreid

from store s join #tempstore ts on s.altstoretype3 = ts.oldstoreid

where s.altstoretype3 = ts.oldstoreid

--ReqStores

update s set s.reqstoretype0 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype0 = ts.oldstoreid

where s.reqstoretype0 = ts.oldstoreid

update s set s.reqstoretype1  = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype1  = ts.oldstoreid

where s.reqstoretype1  = ts.oldstoreid

update s set s.reqstoretype2 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype2 = ts.oldstoreid

where s.reqstoretype2 = ts.oldstoreid

update s set s.reqstoretype3 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype3 = ts.oldstoreid

where s.reqstoretype3 = ts.oldstoreid

update s set s.reqstoretype4 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype4 = ts.oldstoreid

where s.reqstoretype4 = ts.oldstoreid

update s set s.reqstoretype5 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype5 = ts.oldstoreid

where s.reqstoretype5 = ts.oldstoreid

update s set s.reqstoretype6 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype6 = ts.oldstoreid

where s.reqstoretype6 = ts.oldstoreid

update s set s.reqstoretype7 = ts.newstoreid

from store s join #tempstore ts on s.reqstoretype7 = ts.oldstoreid

where s.reqstoretype7 = ts.oldstoreid

--BaseStorePrice

update s set s.basestoreprice_1 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_1 = ts.oldstoreid

where s.basestoreprice_1 = ts.oldstoreid

update s set s.basestoreprice_2 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_2 = ts.oldstoreid

where s.basestoreprice_2 = ts.oldstoreid

update s set s.basestoreprice_3 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_3 = ts.oldstoreid

where s.basestoreprice_3 = ts.oldstoreid

update s set s.basestoreprice_4 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_4 = ts.oldstoreid

where s.basestoreprice_4 = ts.oldstoreid

update s set s.basestoreprice_5 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_5 = ts.oldstoreid

where s.basestoreprice_5 = ts.oldstoreid

update s set s.basestoreprice_6 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_6 = ts.oldstoreid

where s.basestoreprice_6 = ts.oldstoreid

update s set s.basestoreprice_7 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_7 = ts.oldstoreid

where s.basestoreprice_7 = ts.oldstoreid

update s set s.basestoreprice_8 = ts.newstoreid

from store s join #tempstore ts on s.basestoreprice_8 = ts.oldstoreid

where s.basestoreprice_8 = ts.oldstoreid

--Cleanup

drop table #tempstore

drop table #tempquery

drop table storebackup

Database Update Tables and Rebuild Indexes

Once the Script has completed and changed all the StoreID's for each Store, I would recommend running Update Tables and Rebuild Indexes from Database.exe 

Backoffice 

Login to Backoffice and navigate to Venue Stores and Till and verify that the correct Store Structure is now in place.