我已经为此苦苦挣扎了一段时间,并感谢任何帮助。 我有一个不断更新的表,该表的表名列表(同一表可能会出现多次)最近已在数据库1中用新数据更新过。
我想创建一个查询,该查询检查此更新列表,并将数据库1中更新后的表中的数据插入数据库2中的相应表中,并一直循环到列表末尾。 < / p>
列表如下所示:
ID Table TimeStamp
----------------------- -------- -----------------------
0313778E-CB68-E811-910D Customer 2018-07-10 13:27:28.567
0313778E-CB68-E811-910D Customer 2018-07-10 13:28:58.010
194DD17A-CE68-E811-910D Order 2018-07-10 13:27:28.567
0EBB391D-126B-E811-910D Product 2018-07-10 13:28:58.010
4AAE33A5-CE68-E811-910D Customer 2018-07-10 13:27:28.567
DFA2A68C-056B-E811-910D Order 2018-07-10 13:28:58.010
C2CFECB6-CE68-E811-910D Employee 2018-07-10 13:27:28.583
更糟糕的是,数据库2中的表没有与数据库1相同的列数。 我一直在研究MERGE和Cursor以及动态SQL。我对这些是新手,请继续使用。我认为动态SQL + CURSOR是最好的方法。所有这些将导致存储过程。也许有更好的方法吗?无论如何,这就是我所拥有的:
Declare @Source_TableName_Column --this one contains the Database 1 tables as well as the correct columns needed to fill matching table in Database 2.
Declare @InsertInto NVARCHAR(MAX),
@TargetTable NVARCHAR(MAX)='Select name from Database2.sys.all_objects', --list of tables I have in Database 2
@Columns NVARCHAR(MAX) = 'Select name from Database2.sys.all_columns', --list of columns I have in Database 2 (same names as it is in SourceTable in Database 1)
;
DECLARE TableInsert CURSOR FOR
SELECT distinct SourceTableName from Database3.dbo.UpdateTableList
OPEN TableInsert
FETCH NEXT FROM TableInsert
INTO @TableName
--LOOP
WHILE @@FETCH_STATUS=0
BEGIN
SET @InsertInto = 'insert into Database2.dbo.'+@TargetTable+' '+(@Columns)+' values'+(....)+'' --not sure how to do this variable where i get all the results from SourceTable matching columns in TargetTable in database 2
FETCH NEXT FROM TableInsert
INTO @TableName
END
--CLOSE CURSOR
CLOSE TableInsert
DEALLOCATE TableInsert
答案 0 :(得分:0)
这很复杂。我将以比您正在做的事情更简单的方式来处理它。如果方案涉及的目标表具有相同的架构,但是包含许多列,那么我将按照您的方式进行操作,看来情况并非如此。 这就是我要做的。
打开cur1 接下来从cur1抓取到@tablename ....
@@ fetchstatus = 0时 开始
如果@@ tablename ='tbl1' 开始 插入到database2.dbo.tbl2值 从database1.dbo.table1中选择...,其中.. 结束
如果@@ tablename ='tblx' 等等
接下来从cur1抓取到... 结束
答案 1 :(得分:0)
我提出了一个对我有用的解决方案。我在这里更改了一些名称,以更好地适应我上面的描述。我认为它们是正确的,以后会仔细检查,如果有错误,请更正=)
我还是不确定代码中后面的delete语句。 我有一个基于更新列表的TempTable。 Ive插入表后,我想删除更新列表中的行。我有一个带有两个“ where字段IN(TempTable中的对应字段)”子句,另一个带有“从...中删除……where存在(tempTable)”子句。Temptable有两列,但更新列表总共有三列。以最快/最好的列为准?
DECLARE @InsertInto NVARCHAR(MAX);
DECLARE @SourceID NVARCHAR(MAX);
DECLARE @TableAttribute NVARCHAR(MAX);
DECLARE @SourceViewName NVARCHAR(MAX);
DECLARE @TargetTable NVARCHAR(MAX);
DECLARE @SourceTableName NVARCHAR(MAX);
/*-------Create temp table to be used in cursor-------*/
Declare @SQL_TempTable_Insert NVARCHAR(MAX);
IF OBJECT_ID('tempdb..#Cursor_TempTable') IS NOT NULL DROP TABLE #Cursor_TempTable
CREATE TABLE #Cursor_TempTable (
SourceEntity NVARCHAR(MAX) )
/*-------variable to be used in insert step below-------*/
SET @SQL_TempTable_Insert = 'SELECT SourceLogicalName FROM DataBaseC.dbo.REF_ENTITIES_SYNC group by SourceLogicalName'
/*-------Insert into temp table-------*/
INSERT INTO #Cursor_TempTable EXECUTE (@SQL_TempTable_Insert)
/*-------Create temp table from NeworUpdate table-------*/
Declare @SQL_TempTable_NewOrUpdated NVARCHAR(MAX);
IF OBJECT_ID('tempdb.. #TempTable_NewOrUpdated') IS NOT NULL DROP TABLE #TempTable_NewOrUpdated
CREATE TABLE #TempTable_NewOrUpdated (
[ID] NVARCHAR(MAX),
[TimeStamp] DATETIME )
/*-------variable to be used in insert step below in NewOrUpdate temp table-------*/
SET @SQL_TempTable_NewOrUpdated = 'SELECT ID, TimeStamp FROM DataBaseC.dbo.[REF_POSTS_NewOrUpdated] group by ID, TimeStamp'
/*-------Insert into NewOrUpdate temp table-------*/
INSERT INTO #TempTable_NewOrUpdated EXECUTE (@SQL_TempTable_NewOrUpdated)
/*-------Cursor segment-------*/
DECLARE EntitiesInsert CURSOR FOR
SELECT SourceEntity FROM #Cursor_TempTable
OPEN EntitiesInsert
FETCH NEXT FROM EntitiesInsert
INTO @TargetTable
--LOOP
WHILE @@FETCH_STATUS=0
BEGIN
BEGIN TRY
BEGIN TRAN
SET @SourceViewName = (select SourceName from DataBaseC.dbo.REF_ENTITIES_SYNC where Targetname = @TargetTable);
SET @SourceTableName = (select SourceTableName from DataBaseC.dbo.REF_ENTITIES_SYNC where Targetname = @TargetTable);
SET @TableAttribute = stuff(( select ', ' +char(10)+ ac.[name] from DataBaseB.sys.all_columns ac
inner join DataBaseB.sys.all_objects ao on ao.object_id=ac.object_id
where ao.name = @TargetTable and ac.name not in ('ValidFrom','ValidTo')
FOR XML PATH('')
), 1, 1, '')
--Finds DatabaseA table's Primary Key
SET @SourceID = (select c.name
from sys.index_columns ic
inner join sys.columns c on ic.object_id = c.object_id and ic.column_id = c.column_id
inner join sys.indexes i on ic.object_id = i.object_id and ic.index_id = i.index_id
inner join sys.tables t on i.object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
where i.is_primary_key= 1 and t.name = @SourceTableName);
SET @InsertInto = 'INSERT INTO DataBaseB.dbo.'+@TargetTable+' ('+@TableAttribute+')
SELECT '+@TableAttribute+' FROM DataBaseA.dbo.'+@SourceViewName+'
where '+@SourceID+' in (select nu.ID from DataBaseC.Inno.REF_ENTITIES_SYNC sync inner join #TempTable_NewOrUpdated nu on nu.SourceEntity = sync.TargetName where sync.TargetName = '''+@TargetTable+''' group by nu.ID )'
EXEC sp_sqlexec @insertInto
--Delete the records from [DataBaseC].[dbo].[REF_POSTS_NewOrUpdated] that we have inserted.
--DELETE FROM [DataBaseC].[dbo].[REF_POSTS_NewOrUpdated]
-- WHERE ID = (select [ID] from #TempTable_NewOrUpdated)
-- AND TimeStamp = (select [Timestamp] from #TempTable_NewOrUpdated)
----alt2
--DELETE FROM [DataBaseC].[dbo].[REF_POSTS_NewOrUpdated]
-- where exists (select * from #TempTable_NewOrUpdated)
--End TRAN
COMMIT
--End TRY
END TRY
--Catch possible errors
BEGIN CATCH
--IF there is an open transaction then roll back and print error messages.
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION
DECLARE @ErrorNumber INT = ERROR_NUMBER();
DECLARE @ErrorLine INT = ERROR_LINE();
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE();
DECLARE @ErrorSeverity INT = ERROR_SEVERITY();
DECLARE @ErrorState INT = ERROR_STATE();
PRINT 'Actual error number: ' + CAST(@ErrorNumber AS VARCHAR(10));
PRINT 'Actual line number: ' + CAST(@ErrorLine AS VARCHAR(10));
PRINT 'Actual error message: ' + CAST(@ErrorMessage AS VARCHAR(MAX));
PRINT 'Actual error Severity: ' + CAST(@ErrorSeverity AS VARCHAR(MAX));
PRINT 'Actual error State: ' + CAST(@ErrorState AS VARCHAR(MAX));
END CATCH
FETCH NEXT FROM EntitiesInsert
INTO @TargetTable
END
CLOSE EntitiesInsert
DEALLOCATE EntitiesInsert
GO