tags:

views:

5022

answers:

4

Question: How do I store a selected field value into a variable from a query and use it in an update statement?

Here is my procedure:

I'm writing a sql server 2005 tsql stored procedure which does the following: 
1.  gets list of invoices id's from invoice table and stores to Cursor 
2.  Fetch invoice id from cursor -> tmp_key variable 
3.  foreach tmp_key finds invoice client primary contact id from customer table
4.  updates the client contact key with primary contact id 
5.  close cursor

Here is my code:

DECLARE @tmp_key int
DECLARE @get_invckey cursor 

set @get_invckey = CURSOR FOR 
    select invckey from tarinvoice where confirmtocntctkey is null and tranno like '%115876'

OPEN @get_invckey 

FETCH NEXT FROM @get_invckey into @tmp_key

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SELECT c.PrimaryCntctKey as PrimaryContactKey
    from tarcustomer c, tarinvoice i
    where i.custkey = c.custkey and i.invckey = @tmp_key

    UPDATE tarinvoice set confirmtocntctkey = PrimaryContactKey where invckey = @tmp_key
    FETCH NEXT FROM @get_invckey INTO @tmp_key
END 

CLOSE @get_invckey
DEALLOCATE @get_invckey

how do I store the PrimaryContactKey and use again in the set clause of the following update statement? Do I create a cursor variable or just another local variable with an int type?

thanks in advance

+8  A: 

Try This

SELECT @PrimaryContactKey = c.PrimaryCntctKey
FROM tarcustomer c, tarinvoice i
WHERE i.custkey = c.custkey 
    AND i.invckey = @tmp_key

UPDATE tarinvoice SET confirmtocntctkey = @PrimaryContactKey 
WHERE invckey = @tmp_key
FETCH NEXT FROM @get_invckey INTO @tmp_key

You would declare this variable outside of your loop as just a standard TSQL variable.

I should also note that this is how you would do it for any type of select into a variable, not just when dealing with cursors.

TheTXI
+2  A: 
DECLARE @tmp_key int
DECLARE @get_invckey cursor 

set @get_invckey = CURSOR FOR 
    select invckey from tarinvoice where confirmtocntctkey is null and tranno like '%115876'

OPEN @get_invckey 

FETCH NEXT FROM @get_invckey into @tmp_key

DECLARE @PrimaryContactKey int --or whatever datatype it is

WHILE (@@FETCH_STATUS = 0) 
BEGIN 
    SELECT @PrimaryContactKey=c.PrimaryCntctKey
    from tarcustomer c, tarinvoice i
    where i.custkey = c.custkey and i.invckey = @tmp_key

    UPDATE tarinvoice set confirmtocntctkey = @PrimaryContactKey where invckey = @tmp_key
    FETCH NEXT FROM @get_invckey INTO @tmp_key
END 

CLOSE @get_invckey
DEALLOCATE @get_invckey
squillman
A: 

Cursors are great and all, but once the data gets bigger that cursor is going to slow down tremendiously.

DForck42
His question really doesn't have anything to do with cursors despite what he says. The same problem (putting the value of a select into a variable) is something that is used in numerous other instances.
TheTXI
+2  A: 

Why do you need a cursor at all? Your entire segment of code can be replaced by this, which will run a lot faster on large numbers of rows.

UPDATE tarinvoice set confirmtocntctkey = PrimaryCntctKey 
FROM tarinvoice INNER JOIN tarcustomer ON tarinvoice.custkey = tarcustomer.custkey
WHERE confirmtocntctkey is null and tranno like '%115876'
GilaMonster
Are cursors really frowned upon?
phill
They're slow.SQL Server is optimised for set-based queries. It's faster for it to operate on a million rows in one query than to operate on one row a million times. Add to that the overhead that cursors have, and you're asking for major performance problems by using cursors rather than set-based operationsTest your cursor solution and my query, see what the execution times of the two are.
GilaMonster