如何将事务日志插入数据库
How to Insert Transaction Log to Database
我想在 运行 SSIS 包时将 table 名称、开始时间、结束时间和行数输入 TABLE_LOG。所以这是我的数据流任务。
这是我执行 SQL 开始时间和结束时间的任务脚本:
INSERT INTO TABLE_LOG (TABLE_NAME, START_TIME)
VALUES ("EMPLOYEE_DESTINATION", GETDATE());
INSERT INTO TABLE_LOG (FINISH_TIME, NUM_OF_ROWS)
VALUES (GETDATE(), 6);
但是我得到的结果并不是我所期望的。这是结果:
我该怎么做?我也想自动插入 table 名称,而不是那样硬写。
我初学者是SSIS。
对不起我的英语
** 注(更正):
TABLE_NAME = DATABASE_NAME
为什么我有两行而不是一行?
虽然可能不是您所期望的,但执行 SQL 任务正在执行您要求它执行的操作。您发出了 2 条 INSERT 语句,因此第一行有开始记录,第二行有结束记录。
如果您想更改数据库中现有行的数据,您需要 UPDATE
它。这将使您的完成时间查询看起来像
UPDATE TL
SET
FINISH_TIME = GETDATE()
, NUM_OF_ROWS = 6
FROM
TABLE_LOG AS TL
WHERE
TL.TABLE_NAME = 'Employee_Destination'
AND TL.FINISH_TIME IS NULL;
现在,您当前 table 设计的缺点是,如果此程序包运行失败,再次运行失败,第三次运行并成功,将有 3 行都具有相同的结束日期和行数。您希望在该行上有一些独特的东西,例如自动生成的 ID,您在执行插入时将其发送回包。这将简化您的更新语句,因为您只需更新 where LogID = 1;
如何使我的条目动态化?
您需要创建 SSIS 变量。
为类型 String/DT_WSTR 的 TABLE_NAME 创建一个变量。使用您要将数据发送到的 table 的名称填充 - Employee_Destination
在数据流中,将 OLE DB 目标组件从使用 Table 名称 - 快速加载更改为 Table 来自变量的名称 - 快速加载(文本近似)并在变量中使用新的 @[User::TABLE_NAME]
为 NUM_OF_ROWS 创建一个 Integer/Int32 类型。在源和目标之间的数据流中添加行计数转换。选择这个@[User::NUM_OF_ROWS]
并且由于您将向日志记录添加一个标识 table,因此添加一个 Integer/Int32
类型的 LogId
您将通过插入
来填充 LogId
INSERT INTO TABLE_LOG (TABLE_NAME, START_TIME)
VALUES ('EMPLOYEE_DESTINATION', GETDATE());
SELECT SCOPE_IDENTITY();
更改您的执行 SQL 任务、开始时间,以获得 single row
结果集输出。在“结果”选项卡中,添加一个条目并为元素 0 将其关联到 @[User::LogId]
但是,您还需要研究参数化您的查询。假设使用 OLE DB 连接管理器,它将采用
的形式
INSERT INTO TABLE_LOG (TABLE_NAME, START_TIME)
VALUES (?, GETDATE());
SELECT SCOPE_IDENTITY();
在输入参数上,变量名0为@[User::TABLE_NAME]
最后,您的更新也将进行参数化
UPDATE TL
SET
FINISH_TIME = GETDATE()
, NUM_OF_ROWS = ?
FROM
TABLE_LOG AS TL
WHERE
TL.LogID = ?;
元素 0 是@[User::NUM_OF_ROWS],元素 1 是@[User::LogId]
我想在 运行 SSIS 包时将 table 名称、开始时间、结束时间和行数输入 TABLE_LOG。所以这是我的数据流任务。
这是我执行 SQL 开始时间和结束时间的任务脚本:
INSERT INTO TABLE_LOG (TABLE_NAME, START_TIME)
VALUES ("EMPLOYEE_DESTINATION", GETDATE());
INSERT INTO TABLE_LOG (FINISH_TIME, NUM_OF_ROWS)
VALUES (GETDATE(), 6);
但是我得到的结果并不是我所期望的。这是结果:
我该怎么做?我也想自动插入 table 名称,而不是那样硬写。 我初学者是SSIS。 对不起我的英语
** 注(更正): TABLE_NAME = DATABASE_NAME
为什么我有两行而不是一行?
虽然可能不是您所期望的,但执行 SQL 任务正在执行您要求它执行的操作。您发出了 2 条 INSERT 语句,因此第一行有开始记录,第二行有结束记录。
如果您想更改数据库中现有行的数据,您需要 UPDATE
它。这将使您的完成时间查询看起来像
UPDATE TL
SET
FINISH_TIME = GETDATE()
, NUM_OF_ROWS = 6
FROM
TABLE_LOG AS TL
WHERE
TL.TABLE_NAME = 'Employee_Destination'
AND TL.FINISH_TIME IS NULL;
现在,您当前 table 设计的缺点是,如果此程序包运行失败,再次运行失败,第三次运行并成功,将有 3 行都具有相同的结束日期和行数。您希望在该行上有一些独特的东西,例如自动生成的 ID,您在执行插入时将其发送回包。这将简化您的更新语句,因为您只需更新 where LogID = 1;
如何使我的条目动态化?
您需要创建 SSIS 变量。
为类型 String/DT_WSTR 的 TABLE_NAME 创建一个变量。使用您要将数据发送到的 table 的名称填充 - Employee_Destination
在数据流中,将 OLE DB 目标组件从使用 Table 名称 - 快速加载更改为 Table 来自变量的名称 - 快速加载(文本近似)并在变量中使用新的 @[User::TABLE_NAME]
为 NUM_OF_ROWS 创建一个 Integer/Int32 类型。在源和目标之间的数据流中添加行计数转换。选择这个@[User::NUM_OF_ROWS]
并且由于您将向日志记录添加一个标识 table,因此添加一个 Integer/Int32
类型的 LogId您将通过插入
来填充 LogIdINSERT INTO TABLE_LOG (TABLE_NAME, START_TIME)
VALUES ('EMPLOYEE_DESTINATION', GETDATE());
SELECT SCOPE_IDENTITY();
更改您的执行 SQL 任务、开始时间,以获得 single row
结果集输出。在“结果”选项卡中,添加一个条目并为元素 0 将其关联到 @[User::LogId]
但是,您还需要研究参数化您的查询。假设使用 OLE DB 连接管理器,它将采用
的形式INSERT INTO TABLE_LOG (TABLE_NAME, START_TIME)
VALUES (?, GETDATE());
SELECT SCOPE_IDENTITY();
在输入参数上,变量名0为@[User::TABLE_NAME]
最后,您的更新也将进行参数化
UPDATE TL
SET
FINISH_TIME = GETDATE()
, NUM_OF_ROWS = ?
FROM
TABLE_LOG AS TL
WHERE
TL.LogID = ?;
元素 0 是@[User::NUM_OF_ROWS],元素 1 是@[User::LogId]