![](/img/trans.png)
[英]Access 2010 or SQL Server 2008 Export Query to Custom Text File
[英]SSIS 2008 : Export SQL Data to Access Database 2010 Table
我正在创建一个新的SSIS 2008 ETL报告,该报告将从SQL Server中读取数据并将其附加到ACCESS 2010数据库表中。 当访问表中有一个标识列时,如何将记录追加到现有访问表中?
我当前的解决方案有一个带SQL的OLE DB源,可读取数据。 它连接到数据转换任务,然后连接到OLE DB目标任务。 访问表中的标识字段名为“ Id”,它是一个自动编号字段。
当Access表为空时,我能够使用OLE DB目标插入值。 问题与身份字段以及表中是否已有记录有关。
因此,问题在于我的Id列始终从1开始,这意味着由于引擎认为我正在尝试插入重复的键而收到错误消息。
我创建了一个SQL任务,该任务从表中读取最大ID并将其存储到变量中,但是现在我一直试图找出如何在数据流导出过程中使用此值。
当表中已经有记录时,有人可以告诉我如何将数据插入到Access DB中吗?
为清楚起见进行了编辑。 我已经添加了以下用于获取所需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的自动编号字段。
我在下面添加了整个工作流程的屏幕截图。
我找到了一种方法来做我需要的事情,所以我将答案发布在这里,以防它对其他人有帮助。 我将总结以下步骤,然后发布代码。 我正在使用SSIS 2008。
我从在此站点上找到的一个相关答案中得出了这个答案: 在C#中将10万条记录插入MDB文件的最快方法是什么?
创建数据流任务
在数据流任务中,使用您的SQL代码创建OLE Db源。 该查询将为您提供要放入访问表中的结果。
一旦开始运行SQL,就创建了一个数据转换任务,并将大多数列转换为unicode(日期列除外)。 请注意转换器的“输出别名”列中的名称。 这些是您在下面显示的C#脚本任务中使用的名称。
将结果保存到记录集目标。 创建记录集时,“组件属性”选项卡上有一个名为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
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.