views:

118

answers:

2

This is a follow up to my previous question, in t-sql

SELECT SCOPE_IDENTITY()

returns a BIGINT, I did the following to get it to return an INT:

DECLARE @X INT

INSERT ...

SELECT @X = SCOPE_IDENTITY()

-- if i don't include the line below, it will return a BIGINT

SELECT @X

Why does it return a BIGINT unless I do SELECT @X at the end?

p.s. turns out

SELECT @X = SCOPE_IDENTITY()

doesn't return anything, it just sets @x

+1  A: 
SELECT SCOPE_IDENTITY()

returns a BIGINT as you have seen

SELECT @X = SCOPE_IDENTITY()

returns BIGINT and casts it into INT variable @X

So you are returning BIGINT SCOPE_IDENTITY and also concurrently casting it to INT and setting that result to @X.

Returning @X returns the INT result.

Just some interesting reading on the subject.

SQL Server 7.0 Books Online also stated: "It is recommended that SET @local_variable be used for variable assignment rather than SELECT @local_variable."

Matthew Vines
i have a problem with "returns BIGINT and casts it into INT variable @X" ... it doesn't seem to do this, it returns a bigint unless i explicitly do select @x
roman m
I read it again, and it what I said is a little ambiguous, hopefully I clarified it.
Matthew Vines
ok, your edit makes sense now, thanx
roman m
so, basically select @x = scope_identity() is the same as select scope_identity() set @x = scope_identity() ?
roman m
I've been testing to verify my answer. On sql server 2005 the line SELECT @X = SCOPE_IDENTITY() actually returns nothing in a query. I have not tried it in a stored procedure yet, but I would expect the same results there.
Matthew Vines
In spite of what SQL Server 7.0 Books Online says, SELECT @x = has two advantages: (1) you can assign multiple variables in one statement, and (2) when you do so, it is marginally faster than multiple independent SETs. (See Alexander's article here: http://is.gd/4o8Iw)
Aaron Bertrand
+2  A: 

The statement

  SELECT @X = SCOPE_IDENTITY()

is an assignment statement. As in most programming languages, an assignment statement is executed by first evaluating the right hand side. In this case the right hand side evaluates to a bigint. When the value of @X gets the resulting bigint, there is an implicit type conversion, because @X is a different type (int) than the value it's receiving.

SQL is a typed language, and the type of an expression (such as SCOPE_IDENTITY() here) depends on the expression, not on what happens to the expression's value after evaluation.

Analogy:

DECLARE @i INT;
SET @i = 3.2 + 0.2;

You wouldn't suggest that 3.2 + 0.2 is an integer, would you? It's 3.4, a decimal. Only because of the assignment is there an implicit conversion to INT.

There's no magic in most programming languages.

Steve Kass
+1 for detailed explanation
roman m