Tsql 从SSIS中数据流任务中的逗号分隔字段填充数据透视表

Tsql 从SSIS中数据流任务中的逗号分隔字段填充数据透视表,tsql,csv,ssis,pivot-table,Tsql,Csv,Ssis,Pivot Table,这是我的第一篇帖子,所以要温柔:)。我正在构建一个SSIS包,以收集在整个企业中运行的作业的信息。目标是让表中充满关于服务器、实例、数据库、作业及其相互关系的信息。理想情况下,我将使用合并命令在必要时进行更新或插入,但目前它只是插入。以下是我的包裹概览(请不要把你的注意力放在阴沟里:P): (对新用户超链接的限制意味着您需要在我的链接中将+符号替换为“t” 第一个数据流任务从平面文本文件中提取要检查的实例列表,并将它们存储在记录集中。然后foreach循环遍历其中的每一个实例,并相应地更改源连

这是我的第一篇帖子,所以要温柔:)。我正在构建一个SSIS包,以收集在整个企业中运行的作业的信息。目标是让表中充满关于服务器、实例、数据库、作业及其相互关系的信息。理想情况下,我将使用合并命令在必要时进行更新或插入,但目前它只是插入。以下是我的包裹概览(请不要把你的注意力放在阴沟里:P):

(对新用户超链接的限制意味着您需要在我的链接中将+符号替换为“t”

第一个数据流任务从平面文本文件中提取要检查的实例列表,并将它们存储在记录集中。然后foreach循环遍历其中的每一个实例,并相应地更改源连接管理器的连接字符串。在循环中,我们一次遍历一个实例。“Process Server”Dataflow任务用于查找服务器名称并将其添加到目标数据库(如果它不存在),无论哪种方式,它都会将服务器ID和名称存储在包变量中。“Process Instance”与上面的操作相同,但用于实例。“Collect DB Data”然后,Task使用这些包变量将该实例中的所有DBs作为外键的上述包变量的记录插入。完成后,我们将继续执行“收集作业数据”任务(希望是此包的最终任务)。最后一个任务的内容如下:

在这个任务中,这就是我目前正在做的。我首先使用一个查询来收集带有维护计划数据的作业信息。下面是对OLE DB源的查询:

--WRITTEN BY MAXWELL WALLACE
--THE PURPOSE OF THIS QUERY IS TO COLLECT INFORMATION ABOUT JOBS AND MAINTENANCE PLANS
--RUNNING ON A PARTICULAR INSTANCE. IT COLLECTS NAMES, STATUSES, RUN TIMES AND DATES
--AS WELL AS DATABASES AFFECTED AND MAINTENANCE PLAN NAMES IF APPLICABLE.
SELECT B.NAME AS JOB_NAME, B.CATEGORY_ID, 
--RUN_STATUS CODE GETS TRANSLATED INTO ENGLISH
CASE A.RUN_STATUS
WHEN 0 THEN 'Failed'
WHEN 1 THEN 'Succeeded'
WHEN 2 THEN 'Retry'
WHEN 3 THEN 'Canceled'
ELSE 'Unknown'
END AS RUN_STATUS,
--CONVERT INTEGER DATE INTO SOMETHING MORE LEGABLE
SUBSTRING(CAST(A.RUN_DATE AS CHAR(8)),5,2) + '/' + 
RIGHT(CAST(A.RUN_DATE AS CHAR(8)),2) + '/' + 
LEFT(CAST(A.RUN_DATE AS CHAR(8)),4) AS RUN_DATE,
--CONVERT RUN_TIME INTO SOMETHING MORE RECONGNIZABLE (HH:MM:SS)
LEFT(RIGHT('000000' + CAST(A.RUN_TIME AS VARCHAR(10)),6),2) + ':' + 
SUBSTRING(RIGHT('000000' + CAST(A.RUN_TIME AS VARCHAR(10)),6),3,2) + ':' + 
RIGHT(RIGHT('000000' + CAST(A.RUN_TIME AS VARCHAR(10)),6),2) AS RUN_TIME,
--CONVERT RUN_DURATION INTO SOMETHING MORE RECONGNIZABLE (HH:MM:SS)
LEFT(RIGHT('000000' + CAST(A.RUN_DURATION AS VARCHAR(10)),6),2) + ':' + 
SUBSTRING(RIGHT('000000' + CAST(A.RUN_DURATION AS VARCHAR(10)),6),3,2) + ':' + 
RIGHT(RIGHT('000000' + CAST(A.RUN_DURATION AS VARCHAR(10)),6),2) AS RUN_DURATION,
--THE FOLLOWING SUBQUERY IS USED TO EXTRAPOLATE DETAILS FOR THE JOB IN IT'S MAINTENANCE PLAN (IF IT HAS 1)
--THE TOP 1 MAKES SURE WE GET ONLY 1 RECORD SINCE THIS IS A 1 TO MANY RELATIONSHIP
--THE LINE3 COLUMN CONTAINS DETAILS ABOUT THE TASK THAT WAS RUN
(SELECT TOP 1 E.LINE3 
    --WE START WITH THE SYSMAINTPLAN_LOG BECAUSE WE CAN (IN A WAY) JOIN IT TO OUR OUTER JOIN THROUGH THE PLAN_ID IN THE WHERE CLAUSE
    FROM MSDB.DBO.SYSMAINTPLAN_LOG AS D 
    --NOW IT IS POSSIBLE TO, BY EXTENTION, JOIN SYSMAINTPLAN_LOGDETAIL TO THE OUTER JOIN AS WELL THROUGH ITS 1 TO 1 RELATIONSHIP WITH SYSMAINTPLAN_LOG
    INNER JOIN MSDB.DBO.SYSMAINTPLAN_LOGDETAIL AS E ON E.TASK_DETAIL_ID = D.TASK_DETAIL_ID
    --THE 1ST PART OF THE WHERE RETURNS ONLY RECORDS OF THE SAME PLAN_ID, ESSENTIALLY "JOINING" THIS RECORD TO THE OUTER JOIN THE IN MAIN QUERY
    --THE 2ND PART MAKES SURE THE FIELD WE ACTUALLY CARE ABOUT CONTAINS MEANINGFUL DATA
    WHERE D.PLAN_ID = C.PLAN_ID AND E.LINE3 != '') AS PLAN_DETAILS, 
--THE FOLLOWING SUBQUERY RETURNS THE NAME OF THE MAINTENANCE PLAN (IF IT HAS 1)
(SELECT F.NAME
    FROM MSDB.DBO.SYSMAINTPLAN_PLANS AS F --THIS IS A SYSTEM GENERATED VIEW
    --LIKE THE ABOVE SUBQUERY, THIS WHERE ESSENTIALLY "JOINS" THIS RECORD TO THE OUTER JOIN IN THE MAIN QUERY
    WHERE F.ID = C.PLAN_ID) AS PLAN_NAME 
FROM MSDB.DBO.SYSJOBHISTORY AS A
INNER JOIN MSDB.DBO.SYSJOBS AS B ON A.JOB_ID = B.JOB_ID
--THIS OUTTER JOIN ATTACHES PLAN_IDS OF MAINTENANCE PLANS TO JOBS THAT HAVE THEM
LEFT OUTER JOIN SYSMAINTPLAN_SUBPLANS AS C ON C.JOB_ID = B.JOB_ID
--ONLY RETURN ENABLED JOBS
WHERE B.[ENABLED] = 1 
--AND ONLY JOB OUTCOMES, NOT EACH STEP
AND A.STEP_ID = 0 
--AND ONLY COMPLETED JOBS
AND A.RUN_STATUS <> 4
--SORTED BY LATEST DATE 1ST
ORDER BY A.RUN_DATE DESC
下面是我之前发布的查询的一些示例结果。请记住,只要使用MSDB,脚本就可以针对任何实例运行,因为它使用所有系统生成的表和视图:


请务必明确我对此包的目标。作业名称、类别ID、运行日期、运行时间、运行持续时间和计划名称都会进入TBL_SQL_作业表。计划详细信息列不会对空值(计划名称也是如此)执行任何操作,但对于填充的记录,它将删除“数据库”:字符串并拆分逗号分隔的数据库名称。然后它需要对照TBL_Databases表(以前填充)检查拆分中的DB名称,并获取相应的ID。然后,结合我们正在处理的当前作业记录的ID(考虑包的最后一个任务的“查找作业ID”部分)我们将这些记录分别添加到TBL_DATABASE_JOBS表中。最终结果是一个表,其中包含一个唯一的数据库列表,一个表包含一个历史作业信息列表,以及一个提供1个作业:多个数据库关系的表。再次感谢。

听起来您的脚本解决方案是可行的。而且,您不必担心inse从脚本中删除rting

您可以将脚本的角色限制为仅处理逗号分隔列表的拆分。脚本的输出将是列表中每个项目的一行

重要的一步是将脚本组件设置为异步。使用异步模式可使组件输出的行数与输入的行数不同。将新脚本组件创建为转换后,编辑组件。选择输入和输出属性,选择输出0。更改SynchronousInputID属性设置为“无”。展开“输出0”分支并向“输出列”分支添加列。这些列将包含退出组件的行。最后,添加脚本代码,该代码将为逗号分隔列表中的每个项创建行


一旦您可以为列表中的每个项目导出一行,就可以像其他任何目的地一样添加目的地。

我们从不温和,但我们会尽量礼貌。编辑区域上方有一个101010按钮,可以帮助您格式化问题中的代码。
CREATE TABLE TBL_SERVERS(
ID INT UNIQUE IDENTITY(1,1),
TITLE NVARCHAR(50) PRIMARY KEY,
CLUSTER_NAME NVARCHAR(50) DEFAULT '',
RESOURCES_USED NVARCHAR(20) DEFAULT '',
RESOURCE_THRESHOLD NVARCHAR(20) DEFAULT '',
IS_CLUSTERED BIT NOT NULL DEFAULT 0)

CREATE TABLE TBL_INSTANCES(
ID INT UNIQUE IDENTITY(1,1),
SERVER_ID INT NOT NULL REFERENCES TBL_SERVERS(ID),
TITLE NVARCHAR(50) NOT NULL,
PRIMARY KEY (SERVER_ID,TITLE))

CREATE TABLE TBL_CATEGORY_TYPES(
ID INT UNIQUE IDENTITY(1,1),
TITLE NVARCHAR(50) PRIMARY KEY)

INSERT INTO TBL_CATEGORY_TYPES VALUES ('LOCAL')
INSERT INTO TBL_CATEGORY_TYPES VALUES ('MULTISERVER')
INSERT INTO TBL_CATEGORY_TYPES VALUES ('NONE')

CREATE TABLE TBL_CATEGORY_CLASSES(
ID INT UNIQUE IDENTITY(1,1),
TITLE NVARCHAR(50) PRIMARY KEY)

INSERT INTO TBL_CATEGORY_CLASSES VALUES ('JOB')
INSERT INTO TBL_CATEGORY_CLASSES VALUES ('ALERT')
INSERT INTO TBL_CATEGORY_CLASSES VALUES ('OPERATOR')

CREATE TABLE TBL_CATEGORIES(
ID INT UNIQUE IDENTITY(1,1),
TITLE NVARCHAR(50) NOT NULL,
CATEGORY_CLASS_ID INT NOT NULL REFERENCES TBL_CATEGORY_CLASSES(ID),
CATEGORY_TYPE_ID INT NOT NULL REFERENCES TBL_CATEGORY_TYPES(ID),
PRIMARY KEY (TITLE,CATEGORY_CLASS_ID))

CREATE TABLE TBL_SQL_JOBS(
ID INT PRIMARY KEY IDENTITY(1,1),
TITLE NVARCHAR(200) NOT NULL,
INSTANCE_ID INT NOT NULL REFERENCES TBL_INSTANCES(ID),
CATEGORY_ID INT NOT NULL REFERENCES TBL_CATEGORIES(ID),
RUN_STATUS NVARCHAR(10) NOT NULL,
RUN_DATE NVARCHAR(10) NOT NULL,
RUN_TIME NVARCHAR(8) NOT NULL,
RUN_DURATION NVARCHAR(8) NOT NULL,
MAINTENANCE_PLAN_NAME NVARCHAR(200),
RUN_INTERVAL NVARCHAR(20) DEFAULT '',
IS_ENABLED BIT NOT NULL DEFAULT 1)

SET IDENTITY_INSERT TBL_CATEGORIES ON
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (0,'[Uncategorized (Local)]',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (2,'[Uncategorized (Multi-Server)]',1,2,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (98,'[Uncategorized]',2,3,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (99,'[Uncategorized]',3,3,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (8,'Data Collector',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (7,'Database Engine Tuning Advisor',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (3,'Database Maintenance',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (5,'Full-Text',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (1,'Jobs from MSX',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (6,'Log Shipping',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (18,'REPL-Alert Response',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (16,'REPL-Checkup',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (10,'REPL-Distribution',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (11,'REPL-Distribution Cleanup',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (12,'REPL-History Cleanup',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (20,'Replication',2,3,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (13,'REPL-LogReader',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (14,'REPL-Merge',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (19,'REPL-QueueReader',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (15,'REPL-Snapshot',1,1,1)
INSERT INTO TBL_CATEGORIES (ID,TITLE,CATEGORY_CLASS_ID,CATEGORY_TYPE_ID,CATEGORY_GROUP_ID) VALUES (17,'REPL-Subscription Cleanup',1,1,1)
SET IDENTITY_INSERT TBL_CATEGORIES OFF

CREATE TABLE TBL_APPLICATIONS(
ID INT UNIQUE IDENTITY(1,1),
TITLE NVARCHAR(200) NOT NULL,
HUB_SITE NVARCHAR(50) DEFAULT '',
PRIMARY KEY (TITLE,HUB_SITE))

CREATE TABLE TBL_DATABASES(
ID INT UNIQUE IDENTITY(1,1),
INSTANCE_ID INT NOT NULL REFERENCES TBL_INSTANCES(ID),
TITLE NVARCHAR(200) NOT NULL,
APPLICATION_ID INT REFERENCES TBL_APPLICATIONS(ID),
MANAGED BIT NOT NULL DEFAULT 0,
CONNECTIONSTRING NVARCHAR(MAX) NOT NULL DEFAULT '',
RESOURCES_USED NVARCHAR(MAX) NOT NULL DEFAULT '',
RESOURCE_THRESHOLD NVARCHAR(MAX) NOT NULL DEFAULT '',
LAST_SEEN DATETIME NOT NULL DEFAULT GETDATE(),
PRIMARY KEY (INSTANCE_ID,TITLE))

CREATE TABLE TBL_DATABASE_JOBS(
ID INT UNIQUE IDENTITY(1,1),
DATABASE_ID INT NOT NULL REFERENCES TBL_DATABASES(ID),
JOB_ID INT NOT NULL REFERENCES TBL_SQL_JOBS(ID),
PRIMARY KEY (DATABASE_ID,JOB_ID))