views:

310

answers:

4

I'm collecting metadata using the sys.* views, and according to the documentation, the sys.identity_columns view will return the seed and increment values like so.

CREATE TABLE ident_test (
  test_id int IDENTITY(1000,10),
  other int
)

SELECT name, seed_value, increment_value
  FROM sys.identity_columns
 WHERE object_id = OBJECT_ID( 'ident_test' )

However, the above query just returns one column. Is it just me?

(Note: I've had to change this question somewhat from its earlier version.)

A: 

Are you sure you are running this in a database with tables with IDENTITY columns?

SELECT c.name, i.seed_value, i.increment_value
FROM sys.columns c
INNER JOIN sys.identity_columns i
    ON i.object_id = c.object_id
    AND i.column_id = c.column_id

Returns rows for me in a regular production database with a few identities.

Using a LEFT JOIN returns these rows as well as many which are not IDENTITY

I ran this on another database, and I noticed some NULLs are returned (even in the INNER JOIN case). This is because some of the columns are in VIEWs.

Try adding:

INNER JOIN sys.tables t
ON t.object_id = c.object_id

To filter only to actual IDENTITY columns in tables.

Cade Roux
A: 

Shouldn't you reverse the from and join, like this:

SELECT c.name, i.seed_value, i.increment_value
from sys.identity_columns i
join sys.columns c
    ON i.object_id = c.object_id
   AND i.column_id = c.column_id
BoltBait
No, because this will only return identity columns. I want all the columns, and only those extended properties when available.
harpo
Well, when I run your original query, it works fine. I thought you wanted to eliminate all the non-identity columns from the output.
BoltBait
I said "works fine" because when I run your query on my small database it returns 400+ rows including my identity fields. The data was returned as expected, null when not an identity column, and filled in when it was. What are you looking for? Example, please.
BoltBait
I guess that's what I wanted to find out. It should work as you described. (I originally left out a table filter to simplify the example.) So I'm thinking something's wrong with my copy of SQL Server.
harpo
Sounds like it to me. If you have "select col1, col2, col3 from..." you better have 3 columns being returned!
BoltBait
Okay, sorry about all the fuss. It turned out to be a problem in my console. I've used a simple web console linked to a datagrid for this kind of thing for many years, and I've never had this problem before. I fired up SQL Management Studio and got the correct result.
harpo
A: 

You are missing the Where clause. Your query is effectively saying 'Give me all of sys.columns and any matching rows from sys.identity_columns you have (but give me null if there are no matching rows)'.

By adding the Where clause below you'll change it to only return where an exact match is returned, which is the same as an inner join in this instance really.

SELECT c.name, i.seed_value, i.increment_value FROM sys.columns c LEFT OUTER JOIN sys.identity_columns i ON i.object_id = c.object_id AND i.column_id = c.column_id Where I.seed_value is not null

So I think your data is correct, there are no results to view though.

Ryan ONeill
A: 

your query returns what I'd expect [see below]; it returns the single meta-data row about the single identity column (test_ID) in table (ident_test), the oter column (other) has no meta-data in the sys.identity_column as is is not an identity.

SELECT name, seed_value, increment_value
  FROM sys.identity_columns
 WHERE object_id = OBJECT_ID( 'ident_test' )

select name, is_identity, is_nullable
from sys.columns
WHERE object_id = OBJECT_ID( 'ident_test' )

Which gives

name        seed_value    increment_value
-----------------------------------------
test_id     1000          10
(1 row(s) affected)

name        is_identity   is_nullable
-------------------------------------
test_id     1           0
other       0           1

(2 row(s) affected)
adam straughan