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.
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 |
 |
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2010-11-18 : 05:41:43
|
You need to use not existsinsert into target(co_list)select col_list from temp as twhere not exists(select * from target where keycol=t.keycol)MadhivananFailing to plan is Planning to fail |
 |
|
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 existsinsert into target(co_list)select col_list from temp as twhere not exists(select * from target where keycol=t.keycol)MadhivananFailing to plan is Planning to fail
I think question itself was to find key columns------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
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. |
 |
|
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 MVPhttp://visakhm.blogspot.com/ |
 |
|
madhivanan
Premature Yak Congratulator
22864 Posts |
|
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. |
 |
|
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 duhBut when I doSELECT * INTO myTable99_BKP FROM myTable99It returns nothingWell it's not looking at datacreate 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 ) Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspxhttp://weblogs.sqlteam.com/brettk/http://brettkaiser.blogspot.com/ |
 |
|
X002548
Not Just a Number
15586 Posts |
|
X002548
Not Just a Number
15586 Posts |
|
X002548
Not Just a Number
15586 Posts |
Posted - 2010-11-18 : 15:49:05
|
I am so bad at thisok..got that part...now I need to eliminate the concatenated parts that are the sameCREATE TABLE myTable99(Col1 int, Col2 char, col3 datetime)GODECLARE @TABLE_NAME varchar(256); SET @TABLE_NAME = 'myTable99'DECLARE @COLUMN_NAME varchar(256), @Cols varchar(MAX), @n intDECLARE @SQL varchar(MAX), @DATA_TYPE varchar(255), @ORDINAL_POSITION intDECLARE @Offset intDECLARE @t table (TABLE_NAME varchar(256), COLUMN_NAME varchar(256), UNIQUE_VALS CHAR(1))DECLARE @MAX_ORDINAL_POSITION intSELECT @MAX_ORDINAL_POSITION = MAX(ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TABLE_NAME DECLARE myCursor99 CURSORFOR 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_POSITIONSELECT @Cols = @COLUMN_NAME, @n = 1WHILE @@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 ENDCLOSE myCursor99DEALLOCATE myCursor99GODROP TABLE myTable99GO Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspxhttp://weblogs.sqlteam.com/brettk/http://brettkaiser.blogspot.com/ |
 |
|
X002548
Not Just a Number
15586 Posts |
Posted - 2010-11-18 : 17:25:25
|
....and here it isSET NOCOUNT ONGOCREATE TABLE myTable99(Col1 int, Col2 char, col3 datetime)GOINSERT INTO myTable99(Col1, Col2, Col3)SELECT 1, 'A', '1960-10-24' UNION ALLSELECT 2, 'B', '1960-10-24' UNION ALLSELECT 2, 'C', '2010-10-24'GOCREATE TABLE ##t (TABLE_NAME varchar(256), Cols varchar(MAX), UNIQUE_VALS CHAR(1), Cols_Hash int)GODECLARE @TABLE_NAME varchar(256); SET @TABLE_NAME = 'myTable99'DECLARE @COLUMN_NAME varchar(256), @Cols varchar(MAX), @Cols_D varchar(MAX), @n intDECLARE @SQL varchar(MAX), @DATA_TYPE varchar(255), @ORDINAL_POSITION intDECLARE @Offset int, @Col_Hash intDECLARE @MAX_ORDINAL_POSITION intSELECT @MAX_ORDINAL_POSITION = MAX(ORDINAL_POSITION) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @TABLE_NAME DECLARE myCursor99 CURSORFOR 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_POSITIONSELECT @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) ENDCLOSE myCursor99DEALLOCATE myCursor99GOUPDATE ##t SET UNIQUE_VALS = 'Y' WHERE UNIQUE_VALS IS NULLGOSELECT * FROM ##tGO 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) GODROP TABLE myTable99, ##t Brett8-)Hint: Want your questions answered fast? Follow the direction in this linkhttp://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxWant to help yourself?http://msdn.microsoft.com/en-us/library/ms130214.aspxhttp://weblogs.sqlteam.com/brettk/http://brettkaiser.blogspot.com/ |
 |
|
|
|
|
|
|