Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 SQL Server Development (2000)
 Identify Primary key column(s) from system tables

Author  Topic 

cas_o
Posting Yak Master

154 Posts

Posted - 2005-03-10 : 07:03:51
Hi all,

I want to create a small TSQL code generator, as I find myself creating the same old stored procs every project. I want to pass a tablename to a stored proc that will then generate TSQL for a whole new stored proc based on the schema for that table. Heres what I have so far


declare @tablename varchar(128)
set @tablename = '<sometable>'

create table #proc_lines (line_no int identity(1,1),line varchar(256))

insert into #proc_lines(line)
select 'Create Procedure sp_'+@tablename+'_store'

/*generate input parameter list
@colname datatype
! need OUTPUT for Primary Key column*/
insert into #proc_lines(line)
select
'@'+
c.[name]+
' '+
d.[name]+
--need (length) for character datatypes
case when d.[name] in ('nvarchar','varchar','nchar','char')
then '('+
cast(c.length as varchar)+
')'
else
''
end+',' line
from
sysobjects t
join syscolumns c on t.id = c.id
join systypes d on c.xusertype = d.xusertype
where
t.[name] = @tablename
and t.xtype = 'U'
Order by c.colorder

/*! don't need coma for last param*/
update #proc_lines
set line = left(line,(len(line)-1))
where line_no = (select max(line_no) from #proc_lines)

insert into #proc_lines(line)
select 'AS '
--Etc...

/*ultimatley will BCP this out to .sql text file somewhere*/
select * from #proc_lines

drop table #proc_lines


The bit I'm stuck on is I need to concatenate the string 'OUTPUT' next to the primary key column variable in the parameter list, because the stored proc i'm generating is going to be a genric insert/update for that table and if it inserts I want to output the new id.

I'm struggeling to work out the relationships between syscolumns and sysindexkeys and sysindexes, so that I can determine which column is the primary key column for the table dynamically.

Can anyoone help?

;-]... Quack Waddle

robvolk
Most Valuable Yak

15732 Posts

Posted - 2005-03-10 : 07:37:57
Your original post said "identity column" and not "primary key" column. This is a significant change, because if you are NOT using an identity column as a primary key, then you don't need to specify that parameter as an output.

Instead of querying the system tables directly for structural data, use the INFORMATION_SCHEMA views:

declare @tbl varchar(128)
set @tbl='Customers'

select 'CREATE PROCEDURE sp' + TABLE_NAME + ' (' as text FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=@tbl
UNION ALL
SELECT CASE WHEN ORDINAL_POSITION=1 THEN '' ELSE ', ' END +
'@' + COLUMN_NAME + ' ' + DATA_TYPE +
CASE WHEN DATA_TYPE LIKE '%char' OR DATA_TYPE LIKE '%binary' THEN
'(' + cast(CHARACTER_OCTET_LENGTH as varchar) + ')' ELSE '' END +
CASE COLUMNPROPERTY(OBJECT_ID(quotename(TABLE_SCHEMA) + '.' + quotename(TABLE_NAME)), COLUMN_NAME, 'IsIdentity')
WHEN 1 THEN ' OUTPUT ' ELSE '' END
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=@tbl
UNION ALL
SELECT ') AS '
UNION ALL
SELECT 'SET NOCOUNT ON'


They do all the heavy lifting between sysobjects, syscolumns, etc.

You can find primary key and key column information in INFORMATION_SCHEMA.TABLE_CONSTRAINTS and INFORMATION_SCHEMA.KEY_COLUMN_USAGE. Keep in mind that you do not have to use identity as a primary key, and that you can also have multiple columns in your primary key. Knowing the primary key (unless an identity column) would not affect this code generator.

Also, DO NOT use "sp_" for non-system procedures in non-system databases. They incur extra overhead for name resolution which can cause a performance decrease. The example I posted uses "sp" without the underscore and would not have this behavior.
Go to Top of Page

cas_o
Posting Yak Master

154 Posts

Posted - 2005-03-10 : 11:43:16
Thankyou, nail squarly on head cheers.

Added bonus too, I had no idea about sp_ meaning overhead, Luckily I haven't named stored procs in this way before now, and you have stopped me before I did phew!

I do know about natural and composite primary keys and have read your articles, they were good reading. This is only a generic generator and you are right I only need 'OUTPUT' where IDentity is involved.

;-]... Quack Waddle
Go to Top of Page
   

- Advertisement -