Solved

Identifying which column makes up the primary key

Posted on 2004-10-18
11
307 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
Microsoft Certification Exam 74-409

Veeam® is happy to provide the Microsoft community with a study guide prepared by MVP and MCT, Orin Thomas. This guide will take you through each of the exam objectives, helping you to prepare for and pass the examination.

 
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
 
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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Let's review the features of new SQL Server 2012 (Denali CTP3). It listed as below: PERCENT_RANK(): PERCENT_RANK() function will returns the percentage value of rank of the values among its group. PERCENT_RANK() function value always in be…
I have a large data set and a SSIS package. How can I load this file in multi threading?
Using examples as well as descriptions, and references to Books Online, show the different Recovery Models available in SQL Server and explain, as well as show how full, differential and transaction log backups are performed
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.

825 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