Solved

Identifying which column makes up the primary key

Posted on 2004-10-18
11
288 Views
Last Modified: 2012-05-05
I want to be able to query the sys tables to find out where the information is stored about a primary key, and which columns make up that primary key ????
0
Comment
Question by:basile
  • 5
  • 5
11 Comments
 
LVL 8

Expert Comment

by:SashP
ID: 12342357
Have a look at the stored proc sp_pkey

The data is stored in sysindexes you will need to reference syscolumns and sysobjects to get the info you need

If this does not give you what you are looking for have a look into the code of sp_pkeys and have a look at how the stored proc works

CREATE PROCEDURE sp_pkeys(
                     @table_name            sysname,
                     @table_owner       sysname = null,
                     @table_qualifier sysname = null )
as
      DECLARE @table_id            int
      DECLARE @full_table_name      nvarchar(255)

      if @table_qualifier is not null
    begin
            if db_name() <> @table_qualifier
            begin      /* If qualifier doesn't match current database */
                  raiserror (15250, -1,-1)
                  return
            end
    end
      if @table_owner is null
      begin      /* If unqualified table name */
            SELECT @full_table_name = quotename(@table_name)
    end
    else
      begin      /* Qualified table name */
            if @table_owner = ''
            begin      /* If empty owner name */
                  SELECT @full_table_name = quotename(@table_owner)
            end
            else
            begin
                  SELECT @full_table_name = quotename(@table_owner) +
                        '.' + quotename(@table_name)
            end
    end
      /*      Get Object ID */
      SELECT @table_id = object_id(@full_table_name)

    select
            TABLE_QUALIFIER = convert(sysname,db_name()),
            TABLE_OWNER = convert(sysname,user_name(o.uid)),
            TABLE_NAME = convert(sysname,o.name),
            COLUMN_NAME = convert(sysname,c.name),
            --KEY_SEQ = convert(smallint,c.colid),
            KEY_SEQ =
                  case
                        when c.name = index_col(@full_table_name, i.indid,  1) then convert (smallint,1)
                        when c.name = index_col(@full_table_name, i.indid,  2) then convert (smallint,2)
                        when c.name = index_col(@full_table_name, i.indid,  3) then convert (smallint,3)
                        when c.name = index_col(@full_table_name, i.indid,  4) then convert (smallint,4)
                        when c.name = index_col(@full_table_name, i.indid,  5) then convert (smallint,5)
                        when c.name = index_col(@full_table_name, i.indid,  6) then convert (smallint,6)
                        when c.name = index_col(@full_table_name, i.indid,  7) then convert (smallint,7)
                        when c.name = index_col(@full_table_name, i.indid,  8) then convert (smallint,8)
                        when c.name = index_col(@full_table_name, i.indid,  9) then convert (smallint,9)
                        when c.name = index_col(@full_table_name, i.indid, 10) then convert (smallint,10)
                        when c.name = index_col(@full_table_name, i.indid, 11) then convert (smallint,11)
                        when c.name = index_col(@full_table_name, i.indid, 12) then convert (smallint,12)
                        when c.name = index_col(@full_table_name, i.indid, 13) then convert (smallint,13)
                        when c.name = index_col(@full_table_name, i.indid, 14) then convert (smallint,14)
                        when c.name = index_col(@full_table_name, i.indid, 15) then convert (smallint,15)
                        when c.name = index_col(@full_table_name, i.indid, 16) then convert (smallint,16)
                  end,
            PK_NAME = convert(sysname,i.name)
      from
            sysindexes i, syscolumns c, sysobjects o --, syscolumns c1
      where
            o.id = @table_id
            and o.id = c.id
            and o.id = i.id
            and (i.status & 0x800) = 0x800
            --and c.name = index_col (@full_table_name, i.indid, c1.colid)
            and (c.name = index_col (@full_table_name, i.indid,  1) or
                 c.name = index_col (@full_table_name, i.indid,  2) or
                 c.name = index_col (@full_table_name, i.indid,  3) or
                 c.name = index_col (@full_table_name, i.indid,  4) or
                 c.name = index_col (@full_table_name, i.indid,  5) or
                 c.name = index_col (@full_table_name, i.indid,  6) or
                 c.name = index_col (@full_table_name, i.indid,  7) or
                 c.name = index_col (@full_table_name, i.indid,  8) or
                 c.name = index_col (@full_table_name, i.indid,  9) or
                 c.name = index_col (@full_table_name, i.indid, 10) or
                 c.name = index_col (@full_table_name, i.indid, 11) or
                 c.name = index_col (@full_table_name, i.indid, 12) or
                 c.name = index_col (@full_table_name, i.indid, 13) or
                 c.name = index_col (@full_table_name, i.indid, 14) or
                 c.name = index_col (@full_table_name, i.indid, 15) or
                 c.name = index_col (@full_table_name, i.indid, 16)
                )
            --and c1.colid <= i.keycnt      /* create rows from 1 to keycnt */
            --and c1.id = @table_id
      order by 1, 2, 3, 5

Cheers Sash
0
 
LVL 39

Expert Comment

by:appari
ID: 12343819
select B.* from INFORMATION_SCHEMA.TABLE_CONSTRAINTS A, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B
where A.CONSTRAINT_TYPE ='PRIMARY KEY'
and A.CONSTRAINT_NAME = B.CONSTRAINT_NAME  order by 7
0
 
LVL 39

Expert Comment

by:appari
ID: 12343839

its better to use INFORMATION_SCHEMA views instead of using system tables directly.

use this query to get details of all the primary keys,

select B.* from INFORMATION_SCHEMA.TABLE_CONSTRAINTS A, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B
where A.CONSTRAINT_TYPE ='PRIMARY KEY'
and A.CONSTRAINT_NAME = B.CONSTRAINT_NAME  order by B.CONSTRAINT_NAME
0
 
LVL 1

Author Comment

by:basile
ID: 12344573
This returns the primary key name, but i'm really trying to find out is, if ther's more than one key that makes up the primary key..... and what those keys are.
0
 
LVL 1

Author Comment

by:basile
ID: 12344574
when i say keys, i mean columns. sorry
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 1

Author Comment

by:basile
ID: 12344578
also what argumetns should i use wit sp_pkey to find what i'm looking for ?
0
 
LVL 39

Expert Comment

by:appari
ID: 12344749

have you tried the sql from my post? it returns multiple rows, each row related to one column in the pkey.
in your pkey if you have 3 columns then it returns three rows, you can check column_name field to find out the each columns name.

0
 
LVL 39

Expert Comment

by:appari
ID: 12344753

you can try

select B.CONSTRAINT_NAME, B.COLUMN_NAME from INFORMATION_SCHEMA.TABLE_CONSTRAINTS A, INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE B
where A.CONSTRAINT_TYPE ='PRIMARY KEY'
and A.CONSTRAINT_NAME = B.CONSTRAINT_NAME  order by B.CONSTRAINT_NAME
0
 
LVL 1

Author Comment

by:basile
ID: 12349220
appari,

I have tried yours. i guess i'm just to unknowledgable to figure out what the results mean!!


I'll try again.... thanks

baz
0
 
LVL 1

Author Comment

by:basile
ID: 12349266
appari,

how can i use this for a particular table ? becuase this only returns two rows and i knkow there are alot more pk's in the database. i want to get all pk's in a database and their associated columns.


this is the result set:

CONSTRAINT_NAME                                            COLUMN_NAME            

pk_dtproperties                                                   id
pk_dtproperties                                                   property


Should i be in the master database ?


0
 
LVL 39

Accepted Solution

by:
appari earned 500 total points
ID: 12352595
no execute it in the DB from which you want to get the info.
if i execute the above query in the sample pubs DB i am getting following data

CONSTRAINT_NAME      COLUMN_NAME
PK__jobs__22AA2996      job_id
pk_dtproperties      id
pk_dtproperties      property
PK_emp_id      emp_id
UPK_storeid      stor_id
UPKCL_auidind      au_id
UPKCL_pubind      pub_id
UPKCL_pubinfo      pub_id
UPKCL_sales      ord_num
UPKCL_sales      stor_id
UPKCL_sales      title_id
UPKCL_taind      au_id
UPKCL_taind      title_id
UPKCL_titleidind      title_id

if you are not getting anything else means yo dont have pkeys.
0

Featured Post

Zoho SalesIQ

Hassle-free live chat software re-imagined for business growth. 2 users, always free.

Join & Write a Comment

This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
This video shows how to set up a shell script to accept a positional parameter when called, pass that to a SQL script, accept the output from the statement back and then manipulate it in the Shell.
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now