我正在创建一个新的SSIS 2008 ETL报告,该报告将从SQL Server读取数据并将其附加到ACCESS 2010数据库表。当Access表中有标识列时,如何将记录附加到现有访问表?
我当前的解决方案有一个带有SQL的OLE DB源,用于读取数据。它连接到数据转换任务,然后连接到OLE DB目标任务。访问表中的标识字段命名为" Id"它是一个自动编号字段。
当Access表为空时,我可以使用OLE DB目标插入值。问题与身份字段有关,并且表中已有记录。
所以,问题是我的Id列总是从1开始,这意味着我得到一个错误,因为引擎认为我试图插入一个重复的键。
我创建了一个SQL任务,它从表中读取最大ID并将其存储到变量中,但现在我不知道如何在数据流导出过程中弄清楚如何使用这个值。
如果表中已有记录,有人会告诉我如何将数据插入Access数据库吗?
编辑清晰。我添加了用于获取下面所需SQL记录的SQL。请注意,我没有在我的SQL中包含ID身份字段:
DECLARE @STARTDATE DATETIME = (SELECT CONVERT(VARCHAR(25),DATEADD(DD,-(DAY(DATEADD(MM,4,GETDATE()))-1),
DATEADD(MM,4,GETDATE())),101))
DECLARE @ENDDATE DATETIME = (SELECT CONVERT(VARCHAR(25),DATEADD(DD,-(DAY(DATEADD(MM,5,GETDATE()))),
DATEADD(MM,5,GETDATE())),101))
SELECT DISTINCT
ISNULL(CONVERT(VARCHAR(3),PP.LOBCD),'CPP') 'LOB_Name_Product'
, POLICYID 'Policy_#'
, P.PRODUCERID 'Agent_#'
, CONVERT(VARCHAR(14),POLICYEFFDT,101) 'Policy_Eff_Date'
, CONVERT(VARCHAR(14),TS.POLICYEXPDT,101) 'Policy_Exp_Date'
, CONVERT(NUMERIC(15,2),TS.TERMPREMAMT) 'Inforce_Prem_Sum'
, REPLACE(CONVERT(CHAR(100),REPLACE(REPLACE(N.INSUREDNM,CHAR(10),' '),CHAR(13),'')),',',' ') AS 'Insured_Name'
, REPLACE(P.PRODUCERNM1TX,',',' ') AS 'Agent_Name'
, PD.PREDSTATECD 'Policy_State'
, REPLACE(II.ADDRLINE1TX ,',',' ') AS 'Insured_Address_1'
, REPLACE(ISNULL(II.ADDRLINE2TX,''),',',' ') AS 'Insured_Address_2'
, II.CITYNM 'Insured_City'
, II.STATECD 'Insured_State'
, CASE WHEN LEN(RTRIM(II.ZIPCD)) > 5 THEN (SUBSTRING(II.ZIPCD,1,5) + '-' + SUBSTRING(II.ZIPCD,6,5))
ELSE II.ZIPCD
END 'Insured_Zip'
, REPLACE(P.PRODUCERADDRLINE1TX,',',' ') AS 'Agent_Address_1'
, REPLACE(ISNULL(P.PRODUCERADDRLINE2TX,''),',',' ') AS 'Agent_Address_2'
, P.PRODUCERCITYNM 'Agent_City'
, P.STATECD 'Agent_State'
, CASE WHEN LEN(RTRIM(P.ZIPCD)) > 5 THEN SUBSTRING(RTRIM(P.ZIPCD),1,5) + '-' + SUBSTRING(RTRIM(P.ZIPCD),6,5)
ELSE P.ZIPCD
END 'Agent_Zip'
, CONVERT(VARCHAR(10), GETDATE(), 101) AS 'Upload_Date'
, 'Open' AS 'Status'
FROM COPOLICYPOINTER PP
JOIN COTRANSACTIONSUMMARY TS ON TS.SYSTEMASSIGNID = PP.SYSTEMASSIGNID
AND TS.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COTRANSACTIONSUMMARY TS2
WHERE TS2.SYSTEMASSIGNID = TS.SYSTEMASSIGNID)
AND TS.TRANSEFFDT = ( SELECT MAX(TRANSEFFDT) FROM COTRANSACTIONSUMMARY TS2
WHERE TS2.SYSTEMASSIGNID = TS.SYSTEMASSIGNID)
JOIN COPOLICYDETAIL PD ON TS.SYSTEMASSIGNID = PD.SYSTEMASSIGNID
AND PD.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COPRODUCER PD2
WHERE PD2.SYSTEMASSIGNID = PD.SYSTEMASSIGNID)
JOIN COPRODUCER P ON P.SYSTEMASSIGNID = TS.SYSTEMASSIGNID
AND P.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COPRODUCER P2
WHERE P2.SYSTEMASSIGNID = P.SYSTEMASSIGNID)
JOIN COINSUREDNAME N ON N.SYSTEMASSIGNID = P.SYSTEMASSIGNID
AND N.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COINSUREDNAME N2
WHERE N2.SYSTEMASSIGNID = N.SYSTEMASSIGNID)
JOIN COINSUREDINFO II ON II.SYSTEMASSIGNID = N.SYSTEMASSIGNID
AND II.TRANSSEQNO = ( SELECT MAX(TRANSSEQNO) FROM COINSUREDINFO I2
WHERE I2.SYSTEMASSIGNID = II.SYSTEMASSIGNID)
WHERE TS.POLICYEXPDT BETWEEN @STARTDATE AND @ENDDATE
AND PP.CANCEFFDT IS NULL
AND PD.PREDSTATECD IN ('CT', 'RI', 'GA','NH','NY')
ORDER BY POLICYID
结果与数据转换任务相关联。
然后将数据转换任务链接到OLE DB目标任务。
OLE DB目标任务使用连接到Access数据库的OLE DB提供程序。此数据库中的一个表称为MasterTable,它有一个名为ID的自动编号字段。
我添加了以下整个工作流程的屏幕截图。
答案 0 :(得分:0)
我找到了一种方法来做我需要的事情所以我在这里发布答案,以防它帮助其他人。我将总结以下步骤,然后发布代码。我正在使用SSIS 2008。
我从本网站上找到的相关答案中得出了这个答案: What is the fastest way to insert 100 000 records into an MDB file in C#
创建数据流任务
在数据流任务中,使用SQL代码创建OLE Db源。这个查询将为您提供放入访问表的结果。
一旦我开始使用SQL,我就创建了一个数据转换任务,并将大多数列转换为unicode(日期列除外)。注意"输出别名"中的名称。转换器的列。这些是您在下面显示的C#脚本任务中使用的名称。
将结果保存到记录集目标。当您创建记录集时,"组件属性" tab有一个名为VariableName的字段。在那里放一个变量。此变量将保存SQL查询的结果。我命名为我的" rsSourceTable。"这个变量是C#代码读取的结果集。
使数据流任务生效后,创建一个C#脚本任务。我创建了几个用于脚本任务的变量。
只读变量:
AccessPath - 保存Access文件所在的路径。
rsSourceTable - 保存数据流任务结果的变量。
读/写变量: MasterTableRowCount - 我使用它可以轻松报告日志文件和电子邮件任务中插入的文件数。
6。脚本任务的c#代码如下所示。我没有必要添加任何引用。
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Data.OleDb;
namespace ST_afd8e3cca5534e51ba5855e82f502e92.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
OleDbConnection myConnection = new OleDbConnection();
try
{
string accessPath = Dts.Variables["AccessPath"].Value.ToString();
string materTableId = Dts.Variables["MasterTableId"].Value.ToString();
myConnection.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + accessPath;
DataTable dt = new DataTable();
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.Fill(dt, Dts.Variables["User::rsSourceTable"].Value);
int rowCount = 0;
if (dt.Rows.Count > 0)
{
rowCount = dt.Rows.Count;
Dts.Variables["MasterTableRowCount"].Value.ToString();
myConnection.Open();
//1. When building the INSERT statement, remember to enclose column names in square brackets. This prevents errors because Access allows special characters in column names and OLE DB doesn't
//2. Also remember that the order the column names appear in the INSERT statement is important for the code that adds parameters below.
//3. To prevent an error, the INSERT statement is first constructed with a ? for each parameter. The parameter is replaced with the
// appropriate column name in the for loop below.
string insertString = "INSERT INTO MasterTable ([LOB_Name_Product], [Policy_#], [Policy_State], [Policy_Eff_Date], [Policy_Exp_Date], [Insured_Name], [Insured_Address_1], ";
insertString += "[Insured_Address_2], [Insured_City], [Agent_#], [Agent_Name], [Inforce_Prem_Sum], [Status], [Upload_date], [Insured_Zip], [Insured_State], [Agent_Address_1], [Agent_Address_2], [Agent_City], [Agent_Zip], [Agent_State])";
insertString += " Values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
OleDbCommand cmmd = new OleDbCommand(insertString, myConnection);
if (myConnection.State == ConnectionState.Open)
{
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //LOB_Name_Product
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Policy_#
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Policy_State
cmmd.Parameters.Add("?", OleDbType.DBDate, 10); //Policy_Eff_Date
cmmd.Parameters.Add("?", OleDbType.DBDate, 10); //Policy_Exp_Date
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Name
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Address_1
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Address_2
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_City
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_#
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Name
cmmd.Parameters.Add("?", OleDbType.Currency, 255); //Inforce_Prem_Sum
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Status
cmmd.Parameters.Add("?", OleDbType.Date, 10); //Upload_date
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_Zip
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Insured_State
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Address_1
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Address_2
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_City
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_Zip
cmmd.Parameters.Add("?", OleDbType.VarWChar, 255); //Agent_State
cmmd.Prepare();
OleDbTransaction trans = myConnection.BeginTransaction();
cmmd.Transaction = trans;
foreach(DataRow dr in dt.Rows)
{
cmmd.Parameters[0].Value = dr["Copy of LOB_Name_Product"];
cmmd.Parameters[1].Value = dr["Copy of Policy_#"];
cmmd.Parameters[2].Value = dr["Copy of Policy_State"];
cmmd.Parameters[3].Value = dr["Policy_Eff_Date"];
cmmd.Parameters[4].Value = dr["Policy_Exp_Date"];
cmmd.Parameters[5].Value = dr["Copy of Insured_Name"];
cmmd.Parameters[6].Value = dr["Copy of Insured_Address_1"];
cmmd.Parameters[7].Value = dr["Copy of Insured_Address_2"];
cmmd.Parameters[8].Value = dr["Copy of Insured_City"];
cmmd.Parameters[9].Value = dr["Copy of Agent_#"];
cmmd.Parameters[10].Value = dr["Copy of Agent_Name"];
cmmd.Parameters[11].Value = dr["Copy of Inforce_Prem_Sum"];
cmmd.Parameters[12].Value = "Open";
cmmd.Parameters[13].Value = DateTime.Today.ToString("d");
cmmd.Parameters[14].Value = dr["Copy of Insured_Zip"];
cmmd.Parameters[15].Value = dr["Copy of Insured_State"];
cmmd.Parameters[16].Value = dr["Copy of Agent_Address_1"];
cmmd.Parameters[17].Value = dr["Copy of Agent_Address_2"];
cmmd.Parameters[18].Value = dr["Copy of Agent_City"];
cmmd.Parameters[19].Value = dr["Copy of Agent_Zip"];
cmmd.Parameters[20].Value = dr["Copy of Agent_State"];
cmmd.ExecuteNonQuery();
}
trans.Commit();
myConnection.Close();
Dts.TaskResult = (int)ScriptResults.Success; //add logging here for successful operation
}
else
Dts.TaskResult = (int)ScriptResults.Failure;
}
else
Dts.TaskResult = (int)ScriptResults.Success; //add logging here for no records
}
catch (OleDbException oleEx)
{
myConnection.Close();
Dts.TaskResult = (int)ScriptResults.Failure; //add logging here for unable to connect
}
catch (Exception ex)
{
myConnection.Close();
Dts.TaskResult = (int)ScriptResults.Failure; //add logging here for any other error
}
}
}
}