To assign a variable safely, you need to use the SET-SELECT statement:
SET @PrimaryContactKey = (SELECT c.PrimaryCntctKey FROM tarcustomer c, tarinvoice i WHERE i.custkey = c.custkey AND i.invckey = @tmp_key)
Make sure you have both start and end brackets!
The reason why the SET-SELECT version is the safest way to set a variable is twofold.
1. SELECT returns multiple messages
What happens if the following selection results in multiple messages?
SELECT @PrimaryContactKey = c.PrimaryCntctKey FROM tarcustomer c, tarinvoice i WHERE i.custkey = c.custkey AND i.invckey = @tmp_key
@PrimaryContactKey will be assigned the value from the last post as a result.
In fact, @PrimaryContactKey will be assigned one value per message as a result, so it will contain the value of the last message that the SELECT command processed.
Which message is the "last" is determined by any clustered indexes, or if the cluster index is not used or the primary key is not clustered, the last message will be the last message added. In the worst case, this behavior can be changed each time the table is indexed.
With the SET-SELECT statement, your variable will be set to null .
2. SELECT does not return messages
What happens if you use the second version of the code, if your choice does not return a result at all?
In contrast to what you can believe, the value of the variable will not be null - it will retain the same value!
This is due to the fact that, as indicated above, SQL will assign a value to a variable once per message - this means that nothing will happen to the variable if the result does not contain messages. Thus, the variable will still have the value that it had before the statement was run.
Using the SET-SELECT statement, the value will be null .
See also: SET or SELECT when assigning variables.