Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
动态SQL从多个表更新一个表?_Sql_Sql Server_Dynamic Sql - Fatal编程技术网

动态SQL从多个表更新一个表?

动态SQL从多个表更新一个表?,sql,sql-server,dynamic-sql,Sql,Sql Server,Dynamic Sql,我有一个表PI_catalog_Update,它将模式名、表名、Count(*)存储为Volume,将max(ETLRunTime)存储为来自多个原始表的LastUpdate。如何构建一个查询,该查询将使用PI_Catalog_中的SchemaName和TableName对原始表进行更新和查询,并在每次运行SP时更新卷和LastUpdate 可能我需要一些动态SQL。我还是不知道该怎么办 该表如下所示: SchemaName TableName Volume LastUpd

我有一个表PI_catalog_Update,它将模式名、表名、Count(*)存储为Volume,将max(ETLRunTime)存储为来自多个原始表的LastUpdate。如何构建一个查询,该查询将使用PI_Catalog_中的SchemaName和TableName对原始表进行更新和查询,并在每次运行SP时更新卷和LastUpdate

可能我需要一些动态SQL。我还是不知道该怎么办

该表如下所示:

SchemaName      TableName   Volume     LastUpdate
ProdInsights_In abc         4680816    2017-06-04 00:00:00.000
ProdInsights_In bcd         52250      2017-06-04 00:00:00.000
ProdInsights_In def         744225     2017-06-04 00:00:00.000
ProdInsights_In gih         668502     2017-06-04 00:00:00.000
MERGE
INTO    [dbo].[PI_Project_Catalogue] t1
USING   [ProdInsights_In].[View_Table_Catalogue] t2
ON      t1.SchemaName = t2.SchemaName
    and t1.TableName = t2.TableName
WHEN MATCHED THEN
UPDATE
SET     t1.Volume = t2.Volume
       ,t1.LastUpdate = t2.LastUpdate
WHEN NOT MATCHED THEN
INSERT  (SchemaName, TableName, Volume, LastUpdate)
VALUES  (t2.SchemaName. t2.TableName, t2.Volume, t2.LastUpdate)
我编写的查询是另一种方式,我从原始表[ProdInsights\u In].[view\u table\u catalog]创建了一个视图。视图如下所示:

CREATE VIEW  [ProdInsights_In].[View_Table_Catalogue] AS
select
  'ProdInsights_In' as SchemaName
  ,'abc' as TableName
  ,Count(*) Volume
  ,MAX(ETLRunTime) as LastUpdate
From [ProdInsights_In].[abc]
Union All
select
  'ProdInsights_In' as SchemaName
  ,'bcd' as TableName
  ,Count(*) Volume
  ,MAX(ETLRunTime) as LastUpdate
From [ProdInsights_In].[bcd]
Union All ....
然后我使用下面的SP从视图中更新PI_catalog_更新表。 程序如下所示:

SchemaName      TableName   Volume     LastUpdate
ProdInsights_In abc         4680816    2017-06-04 00:00:00.000
ProdInsights_In bcd         52250      2017-06-04 00:00:00.000
ProdInsights_In def         744225     2017-06-04 00:00:00.000
ProdInsights_In gih         668502     2017-06-04 00:00:00.000
MERGE
INTO    [dbo].[PI_Project_Catalogue] t1
USING   [ProdInsights_In].[View_Table_Catalogue] t2
ON      t1.SchemaName = t2.SchemaName
    and t1.TableName = t2.TableName
WHEN MATCHED THEN
UPDATE
SET     t1.Volume = t2.Volume
       ,t1.LastUpdate = t2.LastUpdate
WHEN NOT MATCHED THEN
INSERT  (SchemaName, TableName, Volume, LastUpdate)
VALUES  (t2.SchemaName. t2.TableName, t2.Volume, t2.LastUpdate)

您可以避免使用动态sql,并使用系统视图来获取行计数,而不是从…为每个表执行
select count(*)

select 
    [SchemaName]= s.name
  , [TableName] = o.name
  , [row_count] = p.rows
from sys.partitions p
  inner join sys.indexes i 
    on p.object_id = i.object_id
      and p.index_id = i.index_id
      and i.index_id < 2
  inner join sys.objects o
    on i.object_id = o.object_id
  inner join sys.schemas s
    on o.schema_id = s.schema_id
where o.is_ms_shipped=0
您可以使用单独的语句进行更新,然后插入,而不是使用
merge
。我使用了
merge
,因为这是您在问题中所使用的,并添加了
和(holdlock)

rextester演示:

返回:

+------------+-----------+--------+---------------------+
| SchemaName | TableName | Volume |     LastUpdate      |
+------------+-----------+--------+---------------------+
| dbo        | a         |      1 | 01.01.2017 00:00:00 |
| dbo        | c         |      2 | 06.06.2017 00:00:00 |
| dbo        | d         |      3 | 06.06.2017 00:00:00 |
+------------+-----------+--------+---------------------+
使用此虚拟数据:

create table pi_Project_Catalogue (SchemaName sysname collate Latin1_General_CI_AS, TableName sysname collate Latin1_General_CI_AS, Volume bigint, LastUpdate date)
create table a (id int not null identity(1,1) primary key clustered, ETLRunTime date)
insert into  a values ('20170101');
create table b (id int not null identity(1,1) ); -- no ETLRunTime  column
insert into  b default values
create table c (id int not null identity(1,1), ETLRunTime date );
insert into  c values (sysutcdatetime()),(sysutcdatetime());
create table d (id int not null identity(1,1), ETLRunTime date );
insert into  d values (sysutcdatetime()),(sysutcdatetime()),(sysutcdatetime());
合并
参考:


我建议您使用触发器而不是动态查询。您可以发布您目前编写的查询吗?我已经用代码编辑了问题部分。谢谢。嗨,这是一种很好的方式。但是sysutcdatetime()总是向我显示当前日期时间,即使我没有更新某些表的任何内容。实际上,我有一个工具,它每天在这些表中插入数据,并在该工具更新的所有表中插入名为ETLRunTime的列。我想把
Max(ETLRunTime)
作为最后一次更新。有可能吗?我已经用我写的查询编辑了这个问题,但是查询看起来不够好和有效。Thanks@DataPoliceInc. 更新了我的答案以包含
ETL运行时
。当我第一次读到这个问题时,不知怎的错过了。嗨,这是一个很好的方式。非常感谢你的努力。我学到了一些新东西。谢谢..@DatapolicyInc。很乐意帮忙!