Delete rows from multiple tables using a single query (SQL Express 2005) with a WHERE condition - sql

This is the query I'm using:
DELETE TB1.*, TB2.*
FROM TB1
INNER JOIN TB2 ON TB1.PersonID = TB2.PersonID
WHERE (TB1.PersonID)='2'
It's working fine in MS Access but getting error (Incorrect syntax near ','.) in SQL Server Express 2005.
How to solve it? Please help.

You cannot DELETE from multiple tables with a single expression in SQL 2005 - or any other standard SQL for that matter. Access is the exception here.
The best method to get this effect is to specify FOREIGN KEYS between the table with an ON DELETE trigger.

Why you don't use a DELETE CASCADE FK ?

This cannot be done in one statement. You will have to use 2 statements
DELETE FROM TB1 WHERE PersonID = '2';
DELETE FROM TB2 WHERE PersonID = '2';

As i know, you can't do it in a sentence.
But you can build an stored procedure that do the deletes you want in whatever table in a transaction, what is almost the same.

I don't think you can delete from multiple tables at once (though I'm not certain).
It sounds to me, however, that you would be best to achieve this effect with a relationship that cascades deletes. If you did this you would be able to delete the record from one table and the records in the other would be automatically deleted.
As an example, say the two tables represent a customer, and the customer's orders. If you setup the relationship to cascade deletes, you could simply delete record in the customer table, and the orders would get deleted automatically.
See the MSDN doc on cascading referential integrity constraints.

Specify foreign key for the details tables which references to the primary key of master and set Delete rule = Cascade .
Now when u delete a record from the master table all other details table record based on the deleting rows primary key value, will be deleted automatically.
So in that case a single delete query of master table can delete master tables data as well as child tables data.

Use this in procedure
declare cu cursor for SELECT [name] FROM sys.Tables where [name] like 'tbl_%'
declare #table varchar(100)
declare #sql nvarchar(1000)
OPEN cu
FETCH NEXT FROM cu INTO #table
WHILE ##FETCH_STATUS = 0
BEGIN
set #sql = N'delete from ' + #table
EXEC sp_executesql #sql
FETCH NEXT FROM cu INTO #table
END
CLOSE cu;
DEALLOCATE cu;

I use this for cleaning up data in test/development databases. You can filter by table name and record count.
DECLARE #sqlCommand VARCHAR(3000);
DECLARE #tableList TABLE(Value NVARCHAR(128));
DECLARE #TableName VARCHAR(128);
DECLARE #RecordCount INT;
-- get a cursor with a list of table names and their record counts
DECLARE MyCursor CURSOR FAST_FORWARD
FOR SELECT t.name TableName,
i.rows Records
FROM sysobjects t,
sysindexes i
WHERE
t.xtype = 'U' -- only User tables
AND i.id = t.id
AND i.indid IN(0, 1) -- 0=Heap, 1=Clustered Index
AND i.rows < 10 -- Filter by number of records in the table
AND t.name LIKE 'Test_%'; -- Filter tables by name. You could also provide a list:
-- AND t.name IN ('MyTable1', 'MyTable2', 'MyTable3');
-- or a list of tables to exclude:
-- AND t.name NOT IN ('MySpecialTable', ... );
OPEN MyCursor;
FETCH NEXT FROM MyCursor INTO #TableName, #RecordCount;
-- for each table name in the cursor, delete all records from that table:
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sqlCommand = 'DELETE FROM ' + #TableName;
EXEC (#sqlCommand);
FETCH NEXT FROM MyCursor INTO #TableName, #RecordCount;
END;
CLOSE MyCursor;
DEALLOCATE MyCursor;
Reference info:
sysobjects
sysindexes
SQL Server Cursors

Generally I do deletions from multiple tables with one query.
It works correct with PostgreSQL, but doesn't work for MSSQL, and that's why I got here.
With Postgres (I don't know about other DBs) you can do:
WITH obsolete_ids AS (
SELECT pr_r."ID" AS ids
FROM "PULL_REQUEST" pr_r
WHERE 1=1
AND pr_r."STATUS" IN (1)
) , del_commit_junc AS (
DELETE
FROM "PR_TO_COMMIT"
WHERE "REQUEST_ID" IN (SELECT ids FROM obsolete_ids)
)
DELETE
FROM "PULL_REQUEST" pr_out
WHERE pr_out ."ID" IN (SELECT ids FROM obsolete_ids)
Actually In my original Query I delete foreign keys from 2 more tables, but here I just paste an example.
That way I solved problem with Foreign Keys in "PR_TO_COMMIT" table.

The way I am using to Delete rows from multiple tables in SQL Server?
The most important is to use on delete cascade when creating a foreign key in the table
#Table 1 Create:#
create table Customer_tbl
(
C_id int primary key,
C_Name varchar(50),
C_Address varchar(max),
City varchar(50)
);
#Table 2: Create with Foreign Key Constraints#
create table [order]
(
Ord_Id int primary key,
Item varchar(50),
Quantity int,
Price_Of_1 int,
C_id int foreign key references Customer_tbl(C_id)
on delete cascade
);
delete from Customer_tbl where C_id = 2;

You can use something like the following:
DECLARE db_cursor CURSOR FOR
SELECT name
FROM master.dbo.sysdatabases
WHERE name IN ("TB2","TB1") -- use these databases
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #name
WHILE ##FETCH_STATUS = 0
BEGIN
DELETE FROM #name WHERE PersonID ='2'
FETCH NEXT FROM db_cursor INTO #name
END

CREATE PROCEDURE sp_deleteUserDetails
#Email varchar(255)
AS
declare #tempRegId as int
Delete UserRegistration where Email=#Email
set #tempRegId = (select Id from UserRegistration where Email = #Email)
Delete UserProfile where RegID=#tempRegId
RETURN 0

Try this query
DELETE TB1, TB2 FROM TB1 INNER JOIN TB2
WHERE TB1.PersonID = TB2.PersonID and TB1.PersonID = '2'

$qry = "DELETE lg., l. FROM lessons_game lg RIGHT JOIN lessons l ON lg.lesson_id = l.id WHERE l.id = ?";
lessons is Main table and
lessons_game is subtable so Right Join

DELETE TB1, TB2
FROM customer_details
LEFT JOIN customer_booking on TB1.cust_id = TB2.fk_cust_id
WHERE TB1.cust_id = $id

Related

Multiple tables in the where clause that start with the same string

I'm using sql-server 2014 and am trying to select ID values from a table where the ID values do not exist in hundreds of other tables which all start with the same string (e.g. MyTable1, MyTable2, MyTable3, etc.)
My current query is something like this...
select ID from want w
where not exists (select 'x' from MyTable1 m1 where m1.ID = w.id)
and not exists (select 'x' from MyTable2 m2 where m2.ID = w.id)
I'm looking for something like
select ID from want w
where not exists (select 'x' from 'MyTable%' m where m.ID = w.id)
Or
select ID from want w
where ID not in
(select ID from 'MyTable%')
Thank you!
You do mention that there are hundreds of other tables, is the number of tables increasing? Using INFORMATION_SCHEMA.TABLES as already mentioned in the comments in your question along with dynamic SQL would be a start but also look up cursors for looping through the table names with the result-set returned from INFORMATION_SCHEMA.TABLES. The code fragment below will loop through the table listing from information_schema on the default database. You'll have to add your own code depending on what you want to do where the 'if' statement is. The variable #Table_Name has the name of the table, so you would need to include this in a dynamic SQL string and execute this to get your unused ids.
declare #table_name varchar(256);
DECLARE db_cursor CURSOR FOR
SELECT TABLE_NAME
FROM [Datasets].INFORMATION_SCHEMA.TABLES
;
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #TABLE_NAME
WHILE ##FETCH_STATUS = 0
BEGIN
if(#Table_Name like 'Airline%')
print('Have table name to work with: ' + #Table_Name);
else
print('Ignoring table: ' + #Table_name);
FETCH NEXT FROM db_cursor INTO #TABLE_NAME
END
CLOSE db_cursor
DEALLOCATE db_cursor

SQL Server avoiding Cursors

I am just reading about SQL Server cursors, that I should avoid them as much as I can :)
Is there ALWAYS a way to write a query/function/procedure without cursors?
I have found some examples on the Net, but they are usually rather simple.
My example - can I avoid cursors?:
Let's have an update procedure X taking an account id and a transaction id - this is the unique key of the row I want to update
But there are more transactions for an account
SELECT accID, transID from table
Now I use a cursor to loop on the table, always taking the accID and transID to get the row and update it
Can I do it a non-cursor way?
Thanks
I was asked for more info about what I want to do, it is a bit too long, so I will add it here as a new comment.. I can not copy the code here, so I am trying to capture at least the base.
My code looked like:
DECLARE #headAcc varchar(20)
set #headAcc='ACC111'
declare #id varchar(20), #clId varchar(20)
declare cur CURSOR for
select addID, transID from Table1
where accID like #headAcc+'%' and...
order by 1 desc
OPEN cur
FETCH NEXT from cur into #accID, #transID
WHILE ##FETCH_STATUS = 0
BEGIN
-- 1
update Table2
set colX = ...
where accID=#accID and transID=#transID and...
-- 2
update Table3
set colY = ...
where accID=#accID and transID=#transID and...
FETCH NEXT from cur into #accID, #transID
END
CLOSE cur
DEALLOCATE cur
Thanks for the help in answers and link in comments, I was not very familiar with UPDATE JOINs, and that should be the answer.
After reading the articles I came up with 2 updates in form like:
DECLARE #headACC varchar(20)
set #headACC='ACC111'
update t2
set t2.colX = ...
from Table2 t2
join Table1 t1
on t1.accID=t2.accID
and t1.transID=t2.transID
where t1.accID like #headAcc+'%'
and...
It seems to work. Any other comments appreciated eg. if there is a more effective way.
See this example from MSDN on how to update one table based on data in other tables:
USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
ON sp.BusinessEntityID = so.SalesPersonID
AND so.OrderDate = (SELECT MAX(OrderDate)
FROM Sales.SalesOrderHeader
WHERE SalesPersonID = sp.BusinessEntityID);
GO

SQL DELETE hits constraints

Let's look at the famous Nortwind database. Say I run DELETE FROM Clients.
In MSAccess, when one runs a DELETE statement against a table with referential integrity constraints, Jet will delete the records it can delete, and leave the other ones. In this case, it would delete only the Clients for which there are no Orders.
In SQL Server, doing this seems to just fail, with a message stating that The DELETE statement conflicted with the REFERENCE constraint .....
My question therefore is: is there a simple way to let SQL Server delete just those records that can be deleted ? or do I have to add a WHERE ClientId NOT IN (SELECT Id FROM Clients) ?
In other words, can I make SQL Server DELETE work like Jet's DELETE ?
For info: I am not THAT lazy, but there are MANY constraints there and I'd like to keep my code simple...
Another approach is to delete in loop (row by row) using CURSOR and TRY .. CATCH block to ignore problems with deleting referenced rows.
In this approach you don't have to model your existing and future constraints.
Example:
SET NOCOUNT ON; -- use not to have "(N row(s) affected)" for each deleted row
DECLARE del_cursor CURSOR
FOR SELECT ClientID FROM Clients
DECLARE #CurrentClientID INT -- use your proper type
DECLARE #message VARCHAR(200) -- just for building messages
OPEN del_cursor
FETCH NEXT FROM del_cursor
INTO #CurrentClientID
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRY
DELETE FROM Clients WHERE CURRENT OF del_cursor
END TRY
BEGIN CATCH
SET #message = 'Row ' + CAST(#CurrentClientID AS VARCHAR) + ' cannot be deleted - skipping.'
PRINT #message
END CATCH
FETCH NEXT FROM del_cursor
INTO #CurrentClientID
END
CLOSE del_cursor
DEALLOCATE del_cursor
You may wrap above example with CREATE PROCEDURE DeleteClients and use EXEC DeleteClients instead of DELETE FROM Clients
Your options are:
Cascading Delete - Will delete all records that are dependent on
those clients.
Drop constraint (I don't recommend this :))
Check ahead of time that it can be delete and will not have a conflict
If you want to leave rows that have FK references, then there are only a couple of options, and none of them are pretty:
Check constraints before you do the delete
Modify the query to have the where clauses for the FK as you mentioned in your question
Change your logic to delete rows one at a time, commit each row and rollback the delete if it fails.
The 'least lousy' option really depends on how many FKs are there, how many rows you'll be deleting and the likelihood that a row has FK dependencies. If that is a relatively rare event, then option #3 may be best, although I would tend to lean towards the first two options.
I know it is a little bit complicated solution but you need to do it only once.
How about a trigger to prevent the deletions?
create table parent(
id int not null primary key
)
create table son(
id int not null primary key,
idparent int)
alter table son add foreign key(idparent) references parent(id)
insert into parent values(1)
insert into parent values(2)
insert into parent values(3)
insert into son values(1,1)
--select * from parent
--select * from son
create trigger preventDelete
on parent
instead of delete
as
begin
delete from parent where id not in (select idparent from son) and id in (select id from deleted)
end
delete from parent
records 2 and 3 will be deleted
Try this, it will generate your statements. Excuse the format I wrote it very quickly:
DECLARE #i INT, #SQL NVARCHAR(2000), #TABLENAME NVARCHAR(100)
SET #i = 1
SET #TABLENAME = 'informer_alert'
SET #SQL = ''
DECLARE #col VARCHAR(50), #basecol VARCHAR(50), #tname VARCHAR(50)
DECLARE #TABLE TABLE ([table] VARCHAR(50), col VARCHAR(50), basecol VARCHAR(50))
INSERT INTO #TABLE
SELECT t.name, sc.name, sc2.name
FROM sys.foreign_key_columns fk
INNER JOIN sys.tables t ON fk.parent_object_id = t.OBJECT_ID
INNER JOIN syscolumns sc ON fk.parent_column_id = sc.colorder
AND sc.id = fk.parent_object_id
INNER JOIN syscolumns sc2 ON fk.referenced_object_id = sc2.id
AND fk.constraint_column_id = sc2.colorder
WHERE fk.referenced_object_id = (SELECT OBJECT_ID
FROM sys.tables
WHERE name = #TABLENAME)
WHILE (#i <= (SELECT COUNT(*) FROM #TABLE))
BEGIN
SELECT #tname = [table], #col = col, #basecol = basecol
FROM (SELECT ROW_NUMBER() OVER(ORDER BY col) [N],
[table], col, basecol
FROM #TABLE) A
WHERE A.N = #i
SET #SQL = #SQL + ' DELETE FROM ' + #TABLENAME + ' WHERE ' + #basecol + ' NOT IN (SELECT ' + #col+ ' FROM ' + #tname + ')'
SET #i = #i + 1
END
SELECT #SQL
If you want to keep code simple (you said that) let you CREATE VIEW over your table.
Define WHERE clause to get only deletable rows.
Then you may just DELETE FROM ClientsDeletable.
Remember about DELETE permission for your new view.
Script example:
CREATE VIEW ClientsDeletable
AS
SELECT *
FROM Clients
WHERE
ClientID NOT IN (SELECT CliID FROM ForeignTab1)
AND
ClientID NOT IN (SELECT CliID FROM ForeignTab2)
Notice, that FROM cannot contains JOINs - other way you'll get error:
Msg 4405, Level 16, State 1, Line 1
View or function 'ClientsDeletable' is not updatable because the modification affects multiple base tables.

SQL while loop with Temp Table

I need to create a temporary table and then update the original table. Creating the temporary table is not a problem.
create table #mod_contact
(
id INT IDENTITY NOT NULL PRIMARY KEY,
SiteID INT,
Contact1 varchar(25)
)
INSERT INTO #mod_contact (SiteID, Contact1)
select r.id, r.Contact from dbo.table1 r where CID = 142
GO
Now I need to loop through the table and update r.contact = SiteID + r.contact
I have never used a while loop before and can't seem to make any examples I have seen work.
You can do this in multiple ways, but I think you're looking for a way using a cursor.
A cursor is sort of a pointer in a table, which when incremented points to the next record. ( it's more or less analogeous to a for-next loop )
to use a cursor you can do the following:
-- DECLARE the cursor
DECLARE CUR CURSOR FAST_FORWARD READ_ONLY FOR SELECT id, siteId, contract FROM #mod_contract
-- DECLARE some variables to store the values in
DECLARE #varId int
DECLARE #varSiteId int
DECLARE #varContract varchar(25)
-- Use the cursor
OPEN CUR
FETCH NEXT FROM CUR INTO #varId, #varSiteId, #varContract
WHILE ##FETCH_STATUS = 0
BEGIN
UPDATE dbo.table1
SET contract = #varSiteId + #varContract -- It might not work due to the different types
WHERE id = #varId
FETCH NEXT FROM CUR INTO #varId, #varSiteId, #varContract
END
CLOSE CUR
DEALLOCATE CUR
It's not the most efficient way to get this done, but I think this is what you where looking for.
Hope it helps.
Use a set based approach - no need to loop (from the little details):
UPDATE
r
SET
r.Contact = m.SiteID + r.Contact
FROM
table1 r
INNER JOIN
#mod_contact m
ON m.id=r.id
Your brain wants to do this:
while records
update(i); //update record i
records = records + 1
end while
SQL is set based and allows you to take a whole bunch of records and update them in a single command. The beauty of this is you can use the WHERE clause to filter certain rows that are not needed.
As others have mentioned, learning how to do loops in SQL is generally a bad idea; however, since you're trying to understand how to do something, here's an example:
DECLARE #id int
SELECT #ID =1
WHILE #ID <= (SELECT MAX(ID) FROM table_1)
-- while some condition is true, then do the following
--actions between the BEGIN and END
BEGIN
UPDATE table_1
SET contact = CAST(siteID as varchar(100)) + contact
WHERE table_1.CID = #ID
--increment the step variable so that the condition will eventually be false
SET #ID = #ID + 1
END
--do something else once the condition is satisfied
PRINT 'DONE!! Don't try this in production code...'
Try this one:
-- DECLARE the cursor
DECLARE CUR CURSOR FAST_FORWARD READ_ONLY FOR SELECT column1,column2 FROM table
-- DECLARE some variables to store the values in
DECLARE #varId int
DECLARE #varSiteId int
--DECLARE #varContract varchar(25)
-- Use the cursor
OPEN CUR
FETCH NEXT FROM CUR INTO #varId, #varSiteId
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT *
FROM Table2
WHERE column1 = #varId
AND column2 = #varSiteId
FETCH NEXT FROM CUR INTO #varId, #varSiteId
END
CLOSE CUR
DEALLOCATE CUR
need to create a temporary table and then up date the original table.
Why use a temporary table at all? Your CID column doesn't appear in the temporary table, so I don't see how you can successfully update the original table using SiteID, unless there is only one row where CID = 142 in which using a temp table is definitely overkill.
You can just do this:
UPDATE dbo.table1
SET contact = SiteID + contact
WHERE CID = 142;
Here's a related example which may help getting you to 'think in SQL':
UPDATE T
SET A = B, B = A;
Assuming A and B are of the same type, this would successfully swap their values.

T-SQL Stored Procedure with While Loop causing Errors in Primary Key Constraints

So I have this MS SQL Stored Procedure:
ALTER PROCEDURE [dbo].[Import_Agent_Client_Bucket_2010]
AS
BEGIN
-- Loop Through Each Agent, Create a Bucket, Add their Clients to the Bucket
DECLARE Agent_Cursor CURSOR FOR
SELECT Agent_GUID, Agent_ID
FROM realforms_2011.dbo.Agent
DECLARE #Agent_GUID uniqueidentifier
DECLARE #Agent_ID int
OPEN Agent_Cursor;
FETCH NEXT FROM Agent_Cursor
INTO #Agent_GUID, #Agent_ID;
WHILE ##FETCH_STATUS = 0
BEGIN
-- Create a bucket for each agent
DECLARE #cbPKTable TABLE (cbPK UNIQUEIDENTIFIER, cbID int)
INSERT INTO realforms_2011.dbo.Client_Bucket ([Description] ) OUTPUT inserted.Client_Bucket_GUID, inserted.Client_Bucket_ID INTO #cbPKTable
SELECT ISNULL(a.First_Name, ' ') + ' ' + ISNULL(a.Last_Name, ' ') + '''s Clients'
FROM realforms_2011.dbo.Agent a
WHERE Agent_GUID = #Agent_GUID
DECLARE #Client_Bucket_GUID uniqueidentifier
SELECT #Client_Bucket_GUID = cbPK FROM #cbPKTable
DECLARE #Client_Bucket_ID int
SELECT #Client_Bucket_ID = cbID FROM #cbPKTable
INSERT INTO realforms_2011.dbo.Agent_Client_Bucket (Agent_GUID, Agent_ID, Client_Bucket_GUID, Client_Bucket_ID)
VALUES (#Agent_GUID, #Agent_ID, #Client_Bucket_GUID, #Client_Bucket_ID)
DECLARE #Client_GUID uniqueidentifier
DECLARE #Client_ID int
-- Get clients from the server (2010)
DECLARE Client_Cursor CURSOR FOR
SELECT C.Client_ID
FROM realforms.dbo.Client C
INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
WHERE AC.Agent_ID = #Agent_ID
ORDER BY C.Client_ID ASC
OPEN Client_Cursor;
FETCH NEXT FROM Client_Cursor
INTO #Client_ID
-- loop through each 2010 client
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #myNewPKTable TABLE (myNewPK UNIQUEIDENTIFIER)
INSERT INTO realforms_2011.dbo.Client (Client_ID,Name,Secondary_Name,[Address],Address_2,City_State_Zip,Phone,Email_Address,Secondary_Email_Address,Create_Date,Last_Change_Date,[Status],File_Under,[Year]) OUTPUT inserted.Client_GUID INTO #myNewPKTable
SELECT c.Client_ID,Name,Secondary_Name,[Address],Address_2,City_State_Zip,Phone,Email_Address,Secondary_Email_Address,Create_Date,Last_Change_Date,[Status],File_Under,2010
FROM realforms.dbo.Client C
INNER JOIN realforms.dbo.Agent_Client AC ON AC.Client_ID = C.Client_ID
WHERE AC.Agent_ID = #Agent_ID AND C.Client_ID = #Client_ID
SELECT #Client_GUID = myNewPK FROM #myNewPKTable
INSERT INTO realforms_2011.dbo.Client_Bucket_Client (Client_Bucket_GUID, Client_GUID, Client_ID, Client_Bucket_ID, [Year])
VALUES (#Client_Bucket_GUID, #Client_GUID, #Client_ID, #Client_Bucket_ID, 2010)
PRINT 'Client Bucket GUID: '
PRINT #Client_Bucket_GUID
PRINT 'Client GUID: '
PRINT #Client_GUID
FETCH NEXT FROM Client_Cursor
INTO #Client_ID;
END;
CLOSE Client_Cursor;
DEALLOCATE Client_Cursor;
FETCH NEXT FROM Agent_Cursor
INTO #Agent_GUID, #Agent_ID;
END;
CLOSE Agent_Cursor;
DEALLOCATE Agent_Cursor;
END
But I get an error message on just a very few of the items, it says
Msg 2627, Level 14, State 1, Procedure
Import_Agent_Client_Bucket_2010, Line
71 Violation of PRIMARY KEY constraint
'Client_Bucket_Client_PK'. Cannot
insert duplicate key in object
'dbo.Client_Bucket_Client'. The
statement has been terminated.
EDIT:
OK, I see what you're doing there, I apologize for missing the OUTPUT statement. Based on that information, it seems like the code could break if a record is not inserted into the Client table in the line right before SELECT #Client_GUID = myNewPK FROM #myNewPKTable. If no record is inserted, you would wind up grabbing the GUID from the previous record and when you go to insert that it would cause the PK violation. You might have to check to make sure that records are being inserted into the Client table.
ORIGINAL ANSWER:
It looks like you're declaring a table:
DECLARE #myNewPKTable TABLE (myNewPK UNIQUEIDENTIFIER)
But then you never put anything into it, so this statement must return null:
SELECT #Client_GUID = myNewPK FROM #myNewPKTable
EDIT:
Why not just do this? I don't see why the table #myNewPKTable is even being created.
SET #Client_GUID = NEWID()
EDIT:
I think the reason you are getting the primary key violation is because #Client_Bucket_GUID is null. At the beginning of the procedure, there is this code:
-- Create a bucket for each agent
DECLARE #cbPKTable TABLE (cbPK UNIQUEIDENTIFIER, cbID int)
...
DECLARE #Client_Bucket_GUID uniqueidentifier
SELECT #Client_Bucket_GUID = cbPK FROM #cbPKTable
After this code is run #Client_Bucket_GUID will always be null. Again, you would have to insert records into #cbPKTable if you wanted to get anything out of it. If you're trying to create a new UNIQUEIDENTIFIER and store it in #Client_Bucket_GUID, just use the NEWID() function.