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 2005 Forums
 Transact-SQL (2005)
 No primary key defined

Author  Topic 

carumuga
Posting Yak Master

174 Posts

Posted - 2010-11-17 : 22:08:37
Hi,

There were few tables in the SQL Server db where these tables dont have primary key defined.

We are supposed insert the data from temp tables to the target and load only when the data in the target is not available.

Is there any way where we can identify the key columns in the target tables.

Note: temp and target has the same structure.

Thanks,

Chandra

chadmat
The Chadinator

1974 Posts

Posted - 2010-11-18 : 00:37:38
Only if there is a column that uniquely identifies a row.

-Chad
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2010-11-18 : 05:41:43
You need to use not exists

insert into target(co_list)
select col_list from temp as t
where not exists(select * from target where keycol=t.keycol)

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2010-11-18 : 07:21:09
quote:
Originally posted by madhivanan

You need to use not exists

insert into target(co_list)
select col_list from temp as t
where not exists(select * from target where keycol=t.keycol)

Madhivanan

Failing to plan is Planning to fail


I think question itself was to find key columns

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

carumuga
Posting Yak Master

174 Posts

Posted - 2010-11-18 : 08:37:34
I have too many columns in the temp table. I'm trying to find out the keys by identifying unique rows meaning the composite keys will not return duplicate records in the temp.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2010-11-18 : 08:46:18
that requires analysing data of table to determine which combination will give you unique records.

------------------------------------------------------------------------------------------------------
SQL Server MVP
http://visakhm.blogspot.com/

Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2010-11-18 : 10:17:28
See if this helps
http://beyondrelational.com/blogs/madhivanan/archive/2009/03/06/which-columns-uniquely-identify-a-row.aspx

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2010-11-18 : 12:13:12
I don't think that sp_special_columns works very well (or at all). I have never ever seen it return anything.
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2010-11-18 : 12:23:58
wow..it works with a table that has a PK..well duh

But when I do

SELECT * INTO myTable99_BKP FROM myTable99

It returns nothing


Well it's not looking at data



create procedure sys.sp_special_columns
(
@table_name sysname, -- Wildcard pattern matching IS NOT supported.
@table_owner sysname = null, -- Wildcard pattern matching IS NOT supported.
@table_qualifier sysname = null,
@col_type char(1) = 'R',
@scope char(1) = 'T', -- Not used in the search criteria.
@nullable char(1) = 'U',
@ODBCVer int = 2
)
as
declare @index_id int
declare @table_id int
-- quotename() returns up to 258 chars
declare @full_table_name nvarchar(517) -- 258 + 1 + 258
declare @scopeout smallint

if @col_type not in ('R','V') or @col_type is null
begin
raiserror (15251,-1,-1,'col_type','''R'' or ''V''')
return
end

if @scope = 'C'
select @scopeout = 0
else if @scope = 'T'
select @scopeout = 1
else
begin
raiserror (15251,-1,-1,'scope','''C'' or ''T''')
return
end

if @nullable not in ('U','O') or @nullable is null
begin
raiserror (15251,-1,-1,'nullable','''U'' or ''O''')
return
end

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)

if (@table_id is null) -- Return empty resultset if table doesn't exist
begin
select
SCOPE = convert(smallint,0),
COLUMN_NAME = convert(sysname,NULL),
DATA_TYPE = convert(smallint,0),
TYPE_NAME = convert(sysname,NULL),
"PRECISION" = convert(int,0),
"LENGTH" = convert(int,0),
SCALE = convert(smallint,0),
PSEUDO_COLUMN = convert(smallint,0)
where
1=0
return
end

if @col_type = 'V'
begin -- if ROWVER, just run that query
select
SCOPE = convert(smallint,NULL),
COLUMN_NAME = convert(sysname,c.name),
DATA_TYPE = convert(smallint, -2),
TYPE_NAME = t.name,
"PRECISION" = convert(int,8),
"LENGTH" = convert(int,8),
SCALE = convert(smallint, NULL),
PSEUDO_COLUMN = convert(smallint,1)
from
sys.types t,
sys.all_columns c
where
c.object_id = @table_id and
t.name = 'timestamp' and
t.user_type_id = c.system_type_id and
t.user_type_id = c.user_type_id
return
end

-- ROWID, now find the id of the 'best' index for this table

if @nullable = 'O' -- Don't include any indexes that contain nullable columns.
select
@index_id = MIN(x.index_id)
from
sys.indexes x,
sys.all_columns c,
sys.all_columns c2
where
x.is_unique = 1 and -- If Unique Index
x.object_id = @table_id and
x.index_id > 0 and -- Eliminate Table Row
c.object_id = x.object_id and
c2.object_id = c.object_id and
c.name = index_col(@table_name,x.index_id,c2.column_id)
group by
x.index_id HAVING SUM(convert (int, c.is_nullable)) = 0
else -- Include indexes that are partially nullable.
select
@index_id = MIN(x.index_id)
from
sys.indexes x
where
x.is_unique = 1 and -- If Unique Index
x.object_id = @table_id and
x.index_id > 0 -- Eliminate Table Row

select
SCOPE = @scopeout,
COLUMN_NAME = convert(sysname,c.name),
DATA_TYPE = convert(smallint,
case
when (d.ss_dtype = 240) then -- CLR UDT
-4
when (d.ss_dtype = 241) then -- XML
-10
when (c.max_length = -1 and d.ss_dtype = 167) then -- varchar(max)
-1
when (c.max_length = -1 and d.ss_dtype = 231) then -- nvarchar(max)
-10
when (c.max_length = -1 and d.ss_dtype = 165) then -- varbinary(max)
-4
when d.ss_dtype IN (40,41,42,43) then -- DATE/TIME/DATETIME2/DATETIMEOFFSET
-9 -- SQL_WVARCHAR
else
d.DATA_TYPE
end),
TYPE_NAME = convert(sysname,case
when (t.system_type_id = 240 or t.user_type_id > 255) then t.name
else d.TYPE_NAME collate database_default
end),
"PRECISION" = convert(int,case
when d.DATA_TYPE in (6,7) then d.data_precision -- FLOAT/REAL
when (c.max_length = -1 and d.ss_dtype = 240) then -- Large UDT => image for non-SNAC clients
2147483647
else OdbcPrec(c.system_type_id,c.max_length,c.precision)
end),
"LENGTH" = convert(int,case
when type_name(d.ss_dtype) IN ('numeric','decimal') then -- decimal/numeric types
OdbcPrec(c.system_type_id,c.max_length,c.precision)+2
when (c.max_length = -1 and d.ss_dtype = 240) then -- Large UDT => image for non-SNAC clients
2147483647
when d.ss_dtype IN (40,41,42,43) then
OdbcPrec(c.system_type_id,c.max_length,c.precision)*2 -- DATE/TIME/DATETIME2/DATETIMEOFFSET
else
isnull(d.length, c.max_length)
end),
SCALE = convert(smallint,case
when d.ss_dtype IN (40,41,42,43) then null -- DATE/TIME/DATETIME2/DATETIMEOFFSET
else OdbcScale(c.system_type_id,c.scale)
end),
PSEUDO_COLUMN = convert(smallint,1)
from
sys.columns c inner join
sys.indexes x on
(
x.object_id = c.object_id and
x.object_id = @table_id and
x.index_id = @index_id
) inner join
sys.types t on
(
t.user_type_id = c.user_type_id
) inner join
sys.spt_datatype_info d on
(
d.ss_dtype = c.system_type_id and
d.ODBCVer = @ODBCVer and
d.AUTO_INCREMENT = c.is_identity
) inner join
sys.columns c2 on -- Self-join to generate list of index columns and to extract datatype names.
(
INDEX_COL(@full_table_name,@index_id,c2.column_id) = c.name and
c2.object_id = x.object_id
)




Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx


Want to help yourself?

http://msdn.microsoft.com/en-us/library/ms130214.aspx

http://weblogs.sqlteam.com/brettk/

http://brettkaiser.blogspot.com/


Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2010-11-18 : 12:31:49
how would you build a column matrix for every possible combination of columns?

Col1 + Col2
Col1 + Col3
etc
Col1 + Col2 + Col3
Col1 + Col2 + Col4
etc
Col1 + Col2 + Col3 + Col4
Col1 + Col2 + Col3 + Col5
ect
Col2 + Col1 + Col3
Col2 + Col1 + Col4



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx


Want to help yourself?

http://msdn.microsoft.com/en-us/library/ms130214.aspx

http://weblogs.sqlteam.com/brettk/

http://brettkaiser.blogspot.com/


Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2010-11-18 : 12:37:43
take for example a table with 3 columns

How to build this, and not reuse a combination that has already been tested


1. Col1
2. Col1 + Col2
3. Col1 + Col2 + Col3
4. Col2
5. Col2 + Col1 -- This is accomodated already by line 2
6. Col2 + Col3
7. Col2 + Col3 + Col1 -- This is accomodated already by line 3
8. Col3
9. Col3 + Col1
A. Col3 + Col1 + Col2 -- This is accomodated already by line 3





Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx


Want to help yourself?

http://msdn.microsoft.com/en-us/library/ms130214.aspx

http://weblogs.sqlteam.com/brettk/

http://brettkaiser.blogspot.com/


Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2010-11-18 : 15:49:05
I am so bad at this


ok..got that part...now I need to eliminate the concatenated parts that are the same


CREATE TABLE myTable99(Col1 int, Col2 char, col3 datetime)
GO

DECLARE @TABLE_NAME varchar(256); SET @TABLE_NAME = 'myTable99'
DECLARE @COLUMN_NAME varchar(256), @Cols varchar(MAX), @n int
DECLARE @SQL varchar(MAX), @DATA_TYPE varchar(255), @ORDINAL_POSITION int
DECLARE @Offset int
DECLARE @t table (TABLE_NAME varchar(256), COLUMN_NAME varchar(256), UNIQUE_VALS CHAR(1))
DECLARE @MAX_ORDINAL_POSITION int
SELECT @MAX_ORDINAL_POSITION = MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TABLE_NAME

DECLARE myCursor99 CURSOR
FOR
SELECT COLUMN_NAME, DATA_TYPE, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TABLE_NAME

OPEN myCursor99

FETCH NEXT FROM myCursor99 INTO @COLUMN_NAME, @DATA_TYPE, @ORDINAL_POSITION
SELECT @Cols = @COLUMN_NAME, @n = 1

WHILE @@FETCH_STATUS = 0
BEGIN
-- PRINT @Cols
WHILE @n < @MAX_ORDINAL_POSITION + 2
BEGIN
IF @n <> @ORDINAL_POSITION
BEGIN
PRINT @Cols
SELECT @COLUMN_NAME = COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE ORDINAL_POSITION = @n
SET @Cols = @Cols + '+' + @COLUMN_NAME
END
SELECT @n = @n + 1
END
FETCH NEXT FROM myCursor99 INTO @COLUMN_NAME, @DATA_TYPE, @ORDINAL_POSITION
SELECT @Cols = @COLUMN_NAME, @n = 1
END

CLOSE myCursor99
DEALLOCATE myCursor99
GO

DROP TABLE myTable99
GO



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx


Want to help yourself?

http://msdn.microsoft.com/en-us/library/ms130214.aspx

http://weblogs.sqlteam.com/brettk/

http://brettkaiser.blogspot.com/
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2010-11-18 : 17:25:25
....and here it is


SET NOCOUNT ON
GO

CREATE TABLE myTable99(Col1 int, Col2 char, col3 datetime)
GO

INSERT INTO myTable99(Col1, Col2, Col3)
SELECT 1, 'A', '1960-10-24' UNION ALL
SELECT 2, 'B', '1960-10-24' UNION ALL
SELECT 2, 'C', '2010-10-24'
GO

CREATE TABLE ##t (TABLE_NAME varchar(256), Cols varchar(MAX), UNIQUE_VALS CHAR(1), Cols_Hash int)
GO

DECLARE @TABLE_NAME varchar(256); SET @TABLE_NAME = 'myTable99'
DECLARE @COLUMN_NAME varchar(256), @Cols varchar(MAX), @Cols_D varchar(MAX), @n int
DECLARE @SQL varchar(MAX), @DATA_TYPE varchar(255), @ORDINAL_POSITION int
DECLARE @Offset int, @Col_Hash int
DECLARE @MAX_ORDINAL_POSITION int
SELECT @MAX_ORDINAL_POSITION = MAX(ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TABLE_NAME

DECLARE myCursor99 CURSOR
FOR
SELECT COLUMN_NAME, DATA_TYPE, ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @TABLE_NAME

OPEN myCursor99

FETCH NEXT FROM myCursor99 INTO @COLUMN_NAME, @DATA_TYPE, @ORDINAL_POSITION
SELECT @Cols = CASE WHEN @DATA_TYPE NOT IN ('cha','nchar','varchar','nvarchar')
THEN 'CONVERT(varchar(26),' + @COLUMN_NAME + ')'
ELSE @COLUMN_NAME
END
, @Cols_D = @COLUMN_NAME
, @n = 1, @Col_Hash = POWER(2,@ORDINAL_POSITION)

WHILE @@FETCH_STATUS = 0
BEGIN
-- PRINT @Cols
WHILE @n < @MAX_ORDINAL_POSITION + 2
BEGIN
IF @n <> @ORDINAL_POSITION
BEGIN
INSERT INTO ##t(TABLE_NAME,Cols, Cols_Hash)
SELECT @TABLE_NAME, @Cols_D, @Col_Hash
WHERE @Col_Hash NOT IN (SELECT Cols_Hash FROM ##t)
-- PRINT @Cols + ' ' + CONVERT(varchar(26),POWER(2,@n))
SET @SQL = 'IF EXISTS (SELECT COUNT(*) FROM ' + @TABLE_NAME + ' GROUP BY ' + @Cols + ' HAVING COUNT(*) <> 1)'
+ ' UPDATE ##t SET UNIQUE_VALS = ''N'''
+ ' WHERE TABLE_NAME = ' + '''' + @TABLE_NAME + ''''
+ ' AND Cols = ' + '''' + @Cols_D + ''''
-- PRINT 'SELECT COUNT(*) FROM ' + @TABLE_NAME + ' GROUP BY ' + @Cols + ' HAVING COUNT(*) <> 1'
PRINT @SQL
EXEC(@SQL)
SELECT @COLUMN_NAME = COLUMN_NAME, @DATA_TYPE = DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE ORDINAL_POSITION = @n
SET @Cols = @Cols + '+' + CASE WHEN @DATA_TYPE NOT IN ('char','nchar','varchar','nvarchar')
THEN 'CONVERT(varchar(26),' + @COLUMN_NAME + ')'
ELSE @COLUMN_NAME
END
SET @Cols_D = @Cols_D + '+' + @COLUMN_NAME
SET @Col_Hash = @Col_Hash + POWER(2,@n)
END
SELECT @n = @n + 1
END
FETCH NEXT FROM myCursor99 INTO @COLUMN_NAME, @DATA_TYPE, @ORDINAL_POSITION
SELECT @Cols = CASE WHEN @DATA_TYPE NOT IN ('char','nchar','varchar','nvarchar')
THEN 'CONVERT(varchar(26),' + @COLUMN_NAME + ')'
ELSE @COLUMN_NAME
END
, @Cols_D = @COLUMN_NAME
, @n = 1, @Col_Hash = POWER(2,@ORDINAL_POSITION)
END

CLOSE myCursor99
DEALLOCATE myCursor99
GO

UPDATE ##t SET UNIQUE_VALS = 'Y' WHERE UNIQUE_VALS IS NULL
GO

SELECT * FROM ##t
GO

SELECT *
FROM ##t o
WHERE UNIQUE_VALS = 'Y'
AND Cols_Hash = (SELECT MIN(Cols_Hash) FROM ##t i
WHERE UNIQUE_VALS = 'Y'
AND i.TABLE_NAME = o.TABLE_NAME)
GO

DROP TABLE myTable99, ##t



Brett

8-)

Hint: Want your questions answered fast? Follow the direction in this link
http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspx


Want to help yourself?

http://msdn.microsoft.com/en-us/library/ms130214.aspx

http://weblogs.sqlteam.com/brettk/

http://brettkaiser.blogspot.com/


Go to Top of Page
   

- Advertisement -